wanpipe_multppp.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:69k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2. * wanpipe_multppp.c Multi-Port PPP driver module.
  3. *
  4. * Authors:  Nenad Corbic <ncorbic@sangoma.com>
  5. *
  6. * Copyright: (c) 1995-2001 Sangoma Technologies Inc.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version
  11. * 2 of the License, or (at your option) any later version.
  12. * ============================================================================
  13. * Dec 15 2000   Updated for 2.4.X kernel
  14. * Nov 15 2000   Fixed the SyncPPP support for kernels 2.2.16 and higher.
  15. *    The pppstruct has changed.
  16. * Jul 13 2000 Using the kernel Syncppp module on top of RAW Wanpipe CHDLC
  17. *   module.
  18. *****************************************************************************/
  19. #include <linux/module.h>
  20. #include <linux/version.h>
  21. #include <linux/kernel.h> /* printk(), and other useful stuff */
  22. #include <linux/stddef.h> /* offsetof(), etc. */
  23. #include <linux/errno.h> /* return codes */
  24. #include <linux/string.h> /* inline memset(), etc. */
  25. #include <linux/slab.h> /* kmalloc(), kfree() */
  26. #include <linux/wanrouter.h> /* WAN router definitions */
  27. #include <linux/wanpipe.h> /* WANPIPE common user API definitions */
  28. #include <linux/if_arp.h> /* ARPHRD_* defines */
  29. #include <linux/in.h> /* sockaddr_in */
  30. #include <linux/inet.h>
  31. #include <linux/if.h>
  32. #include <asm/byteorder.h> /* htons(), etc. */
  33. #include <linux/sdlapci.h>
  34. #include <asm/io.h>
  35. #include <linux/sdla_chdlc.h> /* CHDLC firmware API definitions */
  36. #include <linux/sdla_asy.h>            /* CHDLC (async) API definitions */
  37. #include <linux/if_wanpipe_common.h>    /* Socket Driver common area */
  38. #include <linux/if_wanpipe.h>
  39. #if defined(LINUX_2_1) || defined(LINUX_2_4)
  40.   #include <linux/inetdevice.h>
  41.   #include <asm/uaccess.h>
  42. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
  43.  #include <net/syncppp.h>
  44. #else
  45.  #include "syncppp.h"
  46. #endif
  47. #else
  48.   #include <net/route.h>          /* Adding new route entries */
  49. #endif
  50. /****** Defines & Macros ****************************************************/
  51. #ifdef _DEBUG_
  52. #define STATIC
  53. #else
  54. #define STATIC static
  55. #endif
  56. /* reasons for enabling the timer interrupt on the adapter */
  57. #define TMR_INT_ENABLED_UDP    0x01
  58. #define TMR_INT_ENABLED_UPDATE 0x02
  59. #define TMR_INT_ENABLED_CONFIG  0x04
  60.  
  61. #define CHDLC_DFLT_DATA_LEN 1500 /* default MTU */
  62. #define CHDLC_HDR_LEN 1
  63. #define IFF_POINTTOPOINT 0x10
  64. #define CHDLC_API 0x01
  65. #define PORT(x)   (x == 0 ? "PRIMARY" : "SECONDARY" )
  66. #define MAX_BH_BUFF 10
  67. #define CRC_LENGTH  2 
  68. #define PPP_HEADER_LEN  4
  69.  
  70. /******Data Structures*****************************************************/
  71. /* This structure is placed in the private data area of the device structure.
  72.  * The card structure used to occupy the private area but now the following 
  73.  * structure will incorporate the card structure along with CHDLC specific data
  74.  */
  75. typedef struct chdlc_private_area
  76. {
  77. void *if_ptr; /* General Pointer used by SPPP */
  78. wanpipe_common_t common;
  79. sdla_t *card;
  80. int  TracingEnabled; /* For enabling Tracing */
  81. unsigned long  curr_trace_addr; /* Used for Tracing */
  82. unsigned long  start_trace_addr;
  83. unsigned long  end_trace_addr;
  84. unsigned long  base_addr_trace_buffer;
  85. unsigned long  end_addr_trace_buffer;
  86. unsigned short  number_trace_elements;
  87. unsigned   available_buffer_space;
  88. unsigned long  router_start_time;
  89. unsigned char  route_status;
  90. unsigned char  route_removed;
  91. unsigned long  tick_counter; /* For 5s timeout counter */
  92. unsigned long  router_up_time;
  93.         u32             IP_address; /* IP addressing */
  94.         u32             IP_netmask;
  95. unsigned char  mc; /* Mulitcast support on/off */
  96. unsigned short udp_pkt_lgth; /* udp packet processing */
  97. char udp_pkt_src;
  98. char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
  99. unsigned short timer_int_enabled;
  100. char update_comms_stats; /* updating comms stats */
  101. //FIXME: add driver stats as per frame relay!
  102. } chdlc_private_area_t;
  103. /* Route Status options */
  104. #define NO_ROUTE 0x00
  105. #define ADD_ROUTE 0x01
  106. #define ROUTE_ADDED 0x02
  107. #define REMOVE_ROUTE 0x03
  108. /* variable for keeping track of enabling/disabling FT1 monitor status */
  109. static int rCount = 0;
  110. /* variable for tracking how many interfaces to open for WANPIPE on the
  111.    two ports */
  112. extern void disable_irq(unsigned int);
  113. extern void enable_irq(unsigned int);
  114. /****** Function Prototypes *************************************************/
  115. /* WAN link driver entry points. These are called by the WAN router module. */
  116. static int update (wan_device_t* wandev);
  117. static int new_if (wan_device_t* wandev, netdevice_t* dev,
  118. wanif_conf_t* conf);
  119. static int del_if (wan_device_t* wandev, netdevice_t* dev);
  120. /* Network device interface */
  121. static int if_init   (netdevice_t* dev);
  122. static int if_open   (netdevice_t* dev);
  123. static int if_close  (netdevice_t* dev);
  124. static int if_send (struct sk_buff* skb, netdevice_t* dev);
  125. #if defined(LINUX_2_1) || defined(LINUX_2_4)
  126. static struct net_device_stats* if_stats (netdevice_t* dev);
  127. #else
  128. static struct enet_statistics* if_stats (netdevice_t* dev);
  129. #endif
  130. #ifdef LINUX_2_4
  131. static void if_tx_timeout (netdevice_t *dev);
  132. #endif
  133. /* CHDLC Firmware interface functions */
  134. static int chdlc_configure  (sdla_t* card, void* data);
  135. static int chdlc_comm_enable  (sdla_t* card);
  136. static int chdlc_comm_disable  (sdla_t* card);
  137. static int chdlc_read_version  (sdla_t* card, char* str);
  138. static int chdlc_set_intr_mode  (sdla_t* card, unsigned mode);
  139. static int chdlc_send (sdla_t* card, void* data, unsigned len);
  140. static int chdlc_read_comm_err_stats (sdla_t* card);
  141. static int chdlc_read_op_stats (sdla_t* card);
  142. static int config_chdlc (sdla_t *card);
  143. /* Miscellaneous CHDLC Functions */
  144. static int set_chdlc_config (sdla_t* card);
  145. static void init_chdlc_tx_rx_buff( sdla_t* card, netdevice_t *dev );
  146. static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb);
  147. static int process_chdlc_exception(sdla_t *card);
  148. static int process_global_exception(sdla_t *card);
  149. static int update_comms_stats(sdla_t* card,
  150.         chdlc_private_area_t* chdlc_priv_area);
  151. static void port_set_state (sdla_t *card, int);
  152. /* Interrupt handlers */
  153. static void wsppp_isr (sdla_t* card);
  154. static void rx_intr (sdla_t* card);
  155. static void timer_intr(sdla_t *);
  156. /* Miscellaneous functions */
  157. static int reply_udp( unsigned char *data, unsigned int mbox_len );
  158. static int intr_test( sdla_t* card);
  159. static int udp_pkt_type( struct sk_buff *skb , sdla_t* card);
  160. static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
  161.                                 struct sk_buff *skb, netdevice_t* dev,
  162.                                 chdlc_private_area_t* chdlc_priv_area);
  163. static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev,  
  164. chdlc_private_area_t* chdlc_priv_area);
  165. static unsigned short calc_checksum (char *, int);
  166. static void s508_lock (sdla_t *card, unsigned long *smp_flags);
  167. static void s508_unlock (sdla_t *card, unsigned long *smp_flags);
  168. static void send_ppp_term_request (netdevice_t*);
  169. static int  Intr_test_counter;
  170. /****** Public Functions ****************************************************/
  171. /*============================================================================
  172.  * Cisco HDLC protocol initialization routine.
  173.  *
  174.  * This routine is called by the main WANPIPE module during setup.  At this
  175.  * point adapter is completely initialized and firmware is running.
  176.  *  o read firmware version (to make sure it's alive)
  177.  *  o configure adapter
  178.  *  o initialize protocol-specific fields of the adapter data space.
  179.  *
  180.  * Return: 0 o.k.
  181.  * < 0 failure.
  182.  */
  183. int wsppp_init (sdla_t* card, wandev_conf_t* conf)
  184. {
  185. unsigned char port_num;
  186. int err;
  187. unsigned long max_permitted_baud = 0;
  188. SHARED_MEMORY_INFO_STRUCT *flags;
  189. union
  190. {
  191. char str[80];
  192. } u;
  193. volatile CHDLC_MAILBOX_STRUCT* mb;
  194. CHDLC_MAILBOX_STRUCT* mb1;
  195. unsigned long timeout;
  196. /* Verify configuration ID */
  197. if (conf->config_id != WANCONFIG_MPPP) {
  198. printk(KERN_INFO "%s: invalid configuration ID %u!n",
  199.   card->devname, conf->config_id);
  200. return -EINVAL;
  201. }
  202. /* Find out which Port to use */
  203. if ((conf->comm_port == WANOPT_PRI) || (conf->comm_port == WANOPT_SEC)){
  204. if (card->next){
  205. if (conf->comm_port != card->next->u.c.comm_port){
  206. card->u.c.comm_port = conf->comm_port;
  207. }else{
  208. printk(KERN_ERR "%s: ERROR - %s port used!n",
  209.                   card->wandev.name, PORT(conf->comm_port));
  210. return -EINVAL;
  211. }
  212. }else{
  213. card->u.c.comm_port = conf->comm_port;
  214. }
  215. }else{
  216. printk(KERN_ERR "%s: ERROR - Invalid Port Selected!n",
  217.                  card->wandev.name);
  218. return -EINVAL;
  219. }
  220. /* Initialize protocol-specific fields */
  221. if(card->hw.type != SDLA_S514){
  222. if (card->u.c.comm_port == WANOPT_PRI){
  223. card->mbox  = (void *) card->hw.dpmbase;
  224. }else{
  225. card->mbox  = (void *) card->hw.dpmbase + 
  226. SEC_BASE_ADDR_MB_STRUCT - PRI_BASE_ADDR_MB_STRUCT;
  227. }
  228. }else{ 
  229. /* for a S514 adapter, set a pointer to the actual mailbox in the */
  230. /* allocated virtual memory area */
  231. if (card->u.c.comm_port == WANOPT_PRI){
  232. card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT;
  233. }else{
  234. card->mbox = (void *) card->hw.dpmbase + SEC_BASE_ADDR_MB_STRUCT;
  235. }
  236. }
  237. mb = mb1 = card->mbox;
  238. if (!card->configured){
  239. /* The board will place an 'I' in the return code to indicate that it is
  240.     ready to accept commands.  We expect this to be completed in less
  241.             than 1 second. */
  242. timeout = jiffies;
  243. while (mb->return_code != 'I') /* Wait 1s for board to initialize */
  244. if ((jiffies - timeout) > 1*HZ) break;
  245. if (mb->return_code != 'I') {
  246. printk(KERN_INFO
  247. "%s: Initialization not completed by adaptern",
  248. card->devname);
  249. printk(KERN_INFO "Please contact Sangoma representative.n");
  250. return -EIO;
  251. }
  252. }
  253. /* Read firmware version.  Note that when adapter initializes, it
  254.  * clears the mailbox, so it may appear that the first command was
  255.  * executed successfully when in fact it was merely erased. To work
  256.  * around this, we execute the first command twice.
  257.  */
  258. if (chdlc_read_version(card, u.str))
  259. return -EIO;
  260. printk(KERN_INFO "%s: Running Raw CHDLC firmware v%sn" 
  261.  "%s: for Multi-Port PPP protocol.n",
  262. card->devname,u.str,card->devname); 
  263. card->isr = &wsppp_isr;
  264. card->poll = NULL;
  265. card->exec = NULL;
  266. card->wandev.update = &update;
  267.   card->wandev.new_if = &new_if;
  268. card->wandev.del_if = &del_if;
  269. card->wandev.udp_port    = conf->udp_port;
  270. card->wandev.new_if_cnt = 0;
  271. /* reset the number of times the 'update()' proc has been called */
  272. card->u.c.update_call_count = 0;
  273. card->wandev.ttl = conf->ttl;
  274. card->wandev.interface = conf->interface; 
  275. if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&&
  276.     card->hw.type != SDLA_S514){
  277. printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port n",
  278. card->devname, PORT(card->u.c.comm_port));
  279. return -EIO;
  280. }
  281. card->wandev.clocking = conf->clocking;
  282. port_num = card->u.c.comm_port;
  283. /* Setup Port Bps */
  284. if(card->wandev.clocking) {
  285. if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
  286. /* For Primary Port 0 */
  287.                 max_permitted_baud =
  288. (card->hw.type == SDLA_S514) ?
  289. PRI_MAX_BAUD_RATE_S514 : 
  290. PRI_MAX_BAUD_RATE_S508;
  291. }
  292. else if(port_num == WANOPT_SEC) {
  293. /* For Secondary Port 1 */
  294.                         max_permitted_baud =
  295.                                (card->hw.type == SDLA_S514) ?
  296.                                 SEC_MAX_BAUD_RATE_S514 :
  297.                                 SEC_MAX_BAUD_RATE_S508;
  298.                         }
  299.   
  300. if(conf->bps > max_permitted_baud) {
  301. conf->bps = max_permitted_baud;
  302. printk(KERN_INFO "%s: Baud too high!n",
  303. card->wandev.name);
  304.   printk(KERN_INFO "%s: Baud rate set to %lu bpsn", 
  305. card->wandev.name, max_permitted_baud);
  306. }
  307.                              
  308. card->wandev.bps = conf->bps;
  309. }else{
  310.          card->wandev.bps = 0;
  311.    }
  312. /* Setup the Port MTU */
  313. if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
  314. /* For Primary Port 0 */
  315. card->wandev.mtu =
  316. (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
  317. min_t(unsigned int, conf->mtu, PRI_MAX_NO_DATA_BYTES_IN_FRAME) :
  318. CHDLC_DFLT_DATA_LEN;
  319. } else if(port_num == WANOPT_SEC) { 
  320. /* For Secondary Port 1 */
  321. card->wandev.mtu =
  322. (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
  323. min_t(unsigned int, conf->mtu, SEC_MAX_NO_DATA_BYTES_IN_FRAME) :
  324. CHDLC_DFLT_DATA_LEN;
  325. }
  326. /* Add on a PPP Header */
  327. card->wandev.mtu += PPP_HEADER_LEN;
  328. /* Set up the interrupt status area */
  329. /* Read the CHDLC Configuration and obtain: 
  330.  * Ptr to shared memory infor struct
  331.          * Use this pointer to calculate the value of card->u.c.flags !
  332.    */
  333. mb1->buffer_length = 0;
  334. mb1->command = READ_CHDLC_CONFIGURATION;
  335. err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT;
  336. if(err != COMMAND_OK) {
  337. clear_bit(1, (void*)&card->wandev.critical);
  338.                 if(card->hw.type != SDLA_S514)
  339.                  enable_irq(card->hw.irq);
  340. chdlc_error(card, err, mb1);
  341. return -EIO;
  342. }
  343. if(card->hw.type == SDLA_S514){
  344.                 card->u.c.flags = (void *)(card->hw.dpmbase +
  345.                 (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
  346. ptr_shared_mem_info_struct));
  347.         }else{
  348.                 card->u.c.flags = (void *)(card->hw.dpmbase +
  349.                         (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
  350. ptr_shared_mem_info_struct % SDLA_WINDOWSIZE));
  351. }
  352. flags = card->u.c.flags;
  353. /* This is for the ports link state */
  354. card->wandev.state = WAN_DUALPORT;
  355. card->u.c.state = WAN_DISCONNECTED;
  356. if (!card->wandev.piggyback){
  357. err = intr_test(card);
  358. if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { 
  359. printk(KERN_ERR "%s: Interrupt test failed (%i)n",
  360. card->devname, Intr_test_counter);
  361. printk(KERN_ERR "%s: Please choose another interruptn",
  362. card->devname);
  363. return  -EIO;
  364. }
  365. printk(KERN_INFO "%s: Interrupt test passed (%i)n", 
  366. card->devname, Intr_test_counter);
  367. }
  368. if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){
  369. printk (KERN_INFO "%s: Failed to set interrupt triggers!n",
  370. card->devname);
  371. return -EIO;
  372.         }
  373. /* Mask the Timer interrupt */
  374. flags->interrupt_info_struct.interrupt_permission &= 
  375. ~APP_INT_ON_TIMER;
  376. printk(KERN_INFO "n");
  377. return 0;
  378. }
  379. /******* WAN Device Driver Entry Points *************************************/
  380. /*============================================================================
  381.  * Update device status & statistics
  382.  * This procedure is called when updating the PROC file system and returns
  383.  * various communications statistics. These statistics are accumulated from 3 
  384.  * different locations:
  385.  *  1) The 'if_stats' recorded for the device.
  386.  *  2) Communication error statistics on the adapter.
  387.  *      3) CHDLC operational statistics on the adapter.
  388.  * The board level statistics are read during a timer interrupt. Note that we 
  389.  * read the error and operational statistics during consecitive timer ticks so
  390.  * as to minimize the time that we are inside the interrupt handler.
  391.  *
  392.  */
  393. static int update (wan_device_t* wandev)
  394. {
  395. sdla_t* card = wandev->private;
  396.   netdevice_t* dev;
  397.         volatile chdlc_private_area_t* chdlc_priv_area;
  398.         SHARED_MEMORY_INFO_STRUCT *flags;
  399. unsigned long timeout;
  400. /* sanity checks */
  401. if((wandev == NULL) || (wandev->private == NULL))
  402. return -EFAULT;
  403. if(wandev->state == WAN_UNCONFIGURED)
  404. return -ENODEV;
  405. /* more sanity checks */
  406.         if(!card->u.c.flags)
  407.                 return -ENODEV;
  408. if((dev=card->wandev.dev) == NULL)
  409. return -ENODEV;
  410. if((chdlc_priv_area=dev->priv) == NULL)
  411. return -ENODEV;
  412.        flags = card->u.c.flags;
  413.         if(chdlc_priv_area->update_comms_stats){
  414. return -EAGAIN;
  415. }
  416. /* we will need 2 timer interrupts to complete the */
  417. /* reading of the statistics */
  418. chdlc_priv_area->update_comms_stats = 2;
  419.         flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
  420. chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE;
  421.   
  422. /* wait a maximum of 1 second for the statistics to be updated */ 
  423.         timeout = jiffies;
  424.         for(;;) {
  425. if(chdlc_priv_area->update_comms_stats == 0)
  426. break;
  427.                 if ((jiffies - timeout) > (1 * HZ)){
  428.      chdlc_priv_area->update_comms_stats = 0;
  429.   chdlc_priv_area->timer_int_enabled &=
  430. ~TMR_INT_ENABLED_UPDATE; 
  431.   return -EAGAIN;
  432. }
  433.         }
  434. return 0;
  435. }
  436. /*============================================================================
  437.  * Create new logical channel.
  438.  * This routine is called by the router when ROUTER_IFNEW IOCTL is being
  439.  * handled.
  440.  * o parse media- and hardware-specific configuration
  441.  * o make sure that a new channel can be created
  442.  * o allocate resources, if necessary
  443.  * o prepare network device structure for registaration.
  444.  *
  445.  * Return: 0 o.k.
  446.  * < 0 failure (channel will not be created)
  447.  */
  448. static int new_if (wan_device_t* wandev, netdevice_t* pdev, wanif_conf_t* conf)
  449. {
  450. struct ppp_device *pppdev = (struct ppp_device *)pdev;
  451. netdevice_t *dev=NULL;
  452. struct sppp *sp;
  453. sdla_t* card = wandev->private;
  454. chdlc_private_area_t* chdlc_priv_area;
  455. if ((conf->name[0] == '') || (strlen(conf->name) > WAN_IFNAME_SZ)) {
  456. printk(KERN_INFO "%s: invalid interface name!n",
  457. card->devname);
  458. return -EINVAL;
  459. }
  460. /* allocate and initialize private data */
  461. chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL);
  462. if(chdlc_priv_area == NULL) 
  463. return -ENOMEM;
  464. memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t));
  465. chdlc_priv_area->card = card; 
  466. /* initialize data */
  467. strcpy(card->u.c.if_name, conf->name);
  468. if(card->wandev.new_if_cnt > 0) {
  469.                 kfree(chdlc_priv_area);
  470. return -EEXIST;
  471. }
  472. card->wandev.new_if_cnt++;
  473. chdlc_priv_area->TracingEnabled = 0;
  474. //We don't need this any more
  475. chdlc_priv_area->route_status = NO_ROUTE;
  476. chdlc_priv_area->route_removed = 0;
  477. printk(KERN_INFO "%s: Firmware running in HDLC STREAMING Moden",
  478. wandev->name);
  479. /* Setup wanpipe as a router (WANPIPE) or as an API */
  480. if( strcmp(conf->usedby, "WANPIPE") == 0) {
  481. printk(KERN_INFO "%s: Driver running in WANPIPE mode!n",
  482. wandev->name);
  483. card->u.c.usedby = WANPIPE;
  484. } else {
  485. printk(KERN_INFO 
  486. "%s: API Mode is not supported for SyncPPP!n",
  487. wandev->name);
  488. kfree(chdlc_priv_area);
  489. return -EINVAL;
  490. }
  491. /* Get Multicast Information */
  492. chdlc_priv_area->mc = conf->mc;
  493. chdlc_priv_area->if_ptr = pppdev;
  494. /* prepare network device data space for registration */
  495. #ifdef LINUX_2_4
  496. strcpy(dev->name,card->u.c.if_name);
  497. #else
  498. dev->name = (char *)kmalloc(strlen(card->u.c.if_name) + 2, GFP_KERNEL); 
  499. if(dev->name == NULL)
  500. {
  501. kfree(chdlc_priv_area);
  502. return -ENOMEM;
  503. }
  504. sprintf(dev->name, "%s", card->u.c.if_name);
  505. #endif
  506. /* Attach PPP protocol layer to pppdev
  507.  * The sppp_attach() will initilize the dev structure
  508.          * and setup ppp layer protocols.
  509.          * All we have to do is to bind in:
  510.          *        if_open(), if_close(), if_send() and get_stats() functions.
  511.          */
  512. sppp_attach(pppdev);
  513. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,16)
  514. dev = pppdev->dev;
  515. #else
  516. dev = &pppdev->dev;
  517. #endif
  518. sp = &pppdev->sppp;
  519. /* Enable PPP Debugging */
  520. // FIXME Fix this up somehow
  521. //sp->pp_flags |= PP_DEBUG; 
  522. sp->pp_flags &= ~PP_CISCO;
  523. dev->init = &if_init;
  524. dev->priv = chdlc_priv_area;
  525. return 0;
  526. }
  527. /*============================================================================
  528.  * Delete logical channel.
  529.  */
  530. static int del_if (wan_device_t* wandev, netdevice_t* dev)
  531. {
  532. chdlc_private_area_t *chdlc_priv_area = dev->priv;
  533. sdla_t *card = chdlc_priv_area->card;
  534. unsigned long smp_lock;
  535. /* Detach the PPP layer */
  536. printk(KERN_INFO "%s: Detaching SyncPPP Module from %sn",
  537. wandev->name,dev->name);
  538. lock_adapter_irq(&wandev->lock,&smp_lock);
  539. sppp_detach(dev);
  540. chdlc_priv_area->if_ptr=NULL;
  541. chdlc_set_intr_mode(card, 0);
  542. if (card->u.c.comm_enabled)
  543. chdlc_comm_disable(card);
  544. unlock_adapter_irq(&wandev->lock,&smp_lock);
  545. port_set_state(card, WAN_DISCONNECTED);
  546. return 0;
  547. }
  548. /****** Network Device Interface ********************************************/
  549. /*============================================================================
  550.  * Initialize Linux network interface.
  551.  *
  552.  * This routine is called only once for each interface, during Linux network
  553.  * interface registration.  Returning anything but zero will fail interface
  554.  * registration.
  555.  */
  556. static int if_init (netdevice_t* dev)
  557. {
  558. chdlc_private_area_t* chdlc_priv_area = dev->priv;
  559. sdla_t* card = chdlc_priv_area->card;
  560. wan_device_t* wandev = &card->wandev;
  561. #ifdef LINUX_2_0
  562. int i;
  563. #endif
  564. /* NOTE: Most of the dev initialization was
  565.          *       done in sppp_attach(), called by new_if() 
  566.          *       function. All we have to do here is
  567.          *       to link four major routines below. 
  568.          */
  569. /* Initialize device driver entry points */
  570. dev->open = &if_open;
  571. dev->stop = &if_close;
  572. dev->hard_start_xmit = &if_send;
  573. dev->get_stats = &if_stats;
  574. #ifdef LINUX_2_4
  575. dev->tx_timeout = &if_tx_timeout;
  576. dev->watchdog_timeo = TX_TIMEOUT;
  577. #endif
  578. #ifdef LINUX_2_0
  579. dev->family = AF_INET;
  580. #endif
  581.  
  582. /* Initialize hardware parameters */
  583. dev->irq = wandev->irq;
  584. dev->dma = wandev->dma;
  585. dev->base_addr = wandev->ioport;
  586. dev->mem_start = wandev->maddr;
  587. dev->mem_end = wandev->maddr + wandev->msize - 1;
  588. /* Set transmit buffer queue length 
  589.          * If we over fill this queue the packets will
  590.          * be droped by the kernel.
  591.          * sppp_attach() sets this to 10, but
  592.          * 100 will give us more room at low speeds.
  593.  */
  594.         dev->tx_queue_len = 100;
  595.    
  596. /* Initialize socket buffers */
  597. #if !defined(LINUX_2_1) && !defined(LINUX_2_4)
  598.         for (i = 0; i < DEV_NUMBUFFS; ++i)
  599.                 skb_queue_head_init(&dev->buffs[i]);
  600. #endif
  601. return 0;
  602. }
  603. #ifdef LINUX_2_4
  604. /*============================================================================
  605.  * Handle transmit timeout event from netif watchdog
  606.  */
  607. static void if_tx_timeout (netdevice_t *dev)
  608. {
  609.      chdlc_private_area_t* chan = dev->priv;
  610. sdla_t *card = chan->card;
  611. /* If our device stays busy for at least 5 seconds then we will
  612.  * kick start the device by making dev->tbusy = 0.  We expect
  613.  * that our device never stays busy more than 5 seconds. So this                 
  614.  * is only used as a last resort.
  615.  */
  616. ++card->wandev.stats.collisions;
  617. printk (KERN_INFO "%s: Transmit timed out on %sn", card->devname,dev->name);
  618. netif_wake_queue (dev);
  619. }
  620. #endif
  621. /*============================================================================
  622.  * Open network interface.
  623.  * o enable communications and interrupts.
  624.  * o prevent module from unloading by incrementing use count
  625.  *
  626.  * Return 0 if O.k. or errno.
  627.  */
  628. static int if_open (netdevice_t* dev)
  629. {
  630. chdlc_private_area_t* chdlc_priv_area = dev->priv;
  631. sdla_t* card = chdlc_priv_area->card;
  632. struct timeval tv;
  633. SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
  634. /* Only one open per interface is allowed */
  635. #ifdef LINUX_2_4
  636. if (netif_running(dev))
  637. return -EBUSY;
  638. #else
  639. if (dev->start)
  640. return -EBUSY; /* only one open is allowed */
  641. #endif
  642. /* Start PPP Layer */
  643. if (sppp_open(dev)){
  644. return -EIO;
  645. }
  646. do_gettimeofday(&tv);
  647. chdlc_priv_area->router_start_time = tv.tv_sec;
  648.  
  649. #ifdef LINUX_2_4
  650. netif_start_queue(dev);
  651. #else
  652. dev->interrupt = 0;
  653. dev->tbusy = 0;
  654. dev->start = 1;
  655. #endif
  656. wanpipe_open(card);
  657. chdlc_priv_area->timer_int_enabled |= TMR_INT_ENABLED_CONFIG;
  658. flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
  659. return 0;
  660. }
  661. /*============================================================================
  662.  * Close network interface.
  663.  * o if this is the last close, then disable communications and interrupts.
  664.  * o reset flags.
  665.  */
  666. static int if_close (netdevice_t* dev)
  667. {
  668. chdlc_private_area_t* chdlc_priv_area = dev->priv;
  669. sdla_t* card = chdlc_priv_area->card;
  670. /* Stop the PPP Layer */
  671. sppp_close(dev);
  672. stop_net_queue(dev);
  673. #ifndef LINUX_2_4
  674. dev->start=0;
  675. #endif
  676. wanpipe_close(card);
  677. return 0;
  678. }
  679. /*============================================================================
  680.  * Send a packet on a network interface.
  681.  * o set tbusy flag (marks start of the transmission) to block a timer-based
  682.  *   transmit from overlapping.
  683.  * o check link state. If link is not up, then drop the packet.
  684.  * o execute adapter send command.
  685.  * o free socket buffer
  686.  *
  687.  * Return: 0 complete (socket buffer must be freed)
  688.  * non-0 packet may be re-transmitted (tbusy must be set)
  689.  *
  690.  * Notes:
  691.  * 1. This routine is called either by the protocol stack or by the "net
  692.  *    bottom half" (with interrupts enabled).
  693.  * 2. Setting tbusy flag will inhibit further transmit requests from the
  694.  *    protocol stack and can be used for flow control with protocol layer.
  695.  */
  696. static int if_send (struct sk_buff* skb, netdevice_t* dev)
  697. {
  698. chdlc_private_area_t *chdlc_priv_area = dev->priv;
  699. sdla_t *card = chdlc_priv_area->card;
  700. SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
  701. INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct;
  702. int udp_type = 0;
  703. unsigned long smp_flags;
  704. int err=0;
  705. #ifdef LINUX_2_4
  706. netif_stop_queue(dev);
  707. #endif
  708. if (skb == NULL){
  709. /* If we get here, some higher layer thinks we've missed an
  710.  * tx-done interrupt.
  711.  */
  712. printk(KERN_INFO "%s: Received NULL skb buffer! interface %s got kicked!n",
  713. card->devname, dev->name);
  714. wake_net_dev(dev);
  715. return 0;
  716. }
  717. #ifndef LINUX_2_4
  718. if (dev->tbusy){
  719. /* If our device stays busy for at least 5 seconds then we will
  720.  * kick start the device by making dev->tbusy = 0.  We expect 
  721.  * that our device never stays busy more than 5 seconds. So this
  722.  * is only used as a last resort. 
  723.  */
  724.                 ++card->wandev.stats.collisions;
  725. if((jiffies - chdlc_priv_area->tick_counter) < (5 * HZ)) {
  726. return 1;
  727. }
  728. printk (KERN_INFO "%s: Transmit (tbusy) timeout !n",
  729. card->devname);
  730. /* unbusy the interface */
  731. dev->tbusy = 0;
  732. }
  733. #endif
  734.     if (ntohs(skb->protocol) != htons(PVC_PROT)){
  735. /* check the udp packet type */
  736. udp_type = udp_pkt_type(skb, card);
  737. if (udp_type == UDP_CPIPE_TYPE){
  738.                         if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev,
  739.                                 chdlc_priv_area)){
  740. chdlc_int->interrupt_permission |=
  741. APP_INT_ON_TIMER;
  742. }
  743. start_net_queue(dev);
  744. return 0;
  745. }
  746.         }
  747. /* Lock the 508 Card: SMP is supported */
  748.        if(card->hw.type != SDLA_S514){
  749. s508_lock(card,&smp_flags);
  750.      if (test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)){
  751. printk(KERN_INFO "%s: Critical in if_send: %lxn",
  752. card->wandev.name,card->wandev.critical);
  753.                 ++card->wandev.stats.tx_dropped;
  754. start_net_queue(dev);
  755. goto if_send_crit_exit;
  756. }
  757. if (card->wandev.state != WAN_CONNECTED){
  758. ++card->wandev.stats.tx_dropped;
  759. start_net_queue(dev);
  760. goto if_send_crit_exit;
  761. }
  762. if (chdlc_send(card, skb->data, skb->len)){
  763. stop_net_queue(dev);
  764. }else{
  765. ++card->wandev.stats.tx_packets;
  766. #if defined(LINUX_2_1) || defined(LINUX_2_4)
  767.         card->wandev.stats.tx_bytes += skb->len;
  768. #endif
  769. #ifdef LINUX_2_4
  770. dev->trans_start = jiffies;
  771. #endif
  772. start_net_queue(dev);
  773. }
  774. if_send_crit_exit:
  775. if (!(err=is_queue_stopped(dev))){
  776.                 wan_dev_kfree_skb(skb, FREE_WRITE);
  777. }else{
  778. chdlc_priv_area->tick_counter = jiffies;
  779. chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME;
  780. }
  781. clear_bit(SEND_CRIT, (void*)&card->wandev.critical);
  782. if(card->hw.type != SDLA_S514){
  783. s508_unlock(card,&smp_flags);
  784. }
  785. return err;
  786. }
  787. /*============================================================================
  788.  * Reply to UDP Management system.
  789.  * Return length of reply.
  790.  */
  791. static int reply_udp( unsigned char *data, unsigned int mbox_len )
  792. {
  793. unsigned short len, udp_length, temp, ip_length;
  794. unsigned long ip_temp;
  795. int even_bound = 0;
  796.    chdlc_udp_pkt_t *c_udp_pkt = (chdlc_udp_pkt_t *)data;
  797.  
  798. /* Set length of packet */
  799. len = sizeof(ip_pkt_t)+ 
  800.       sizeof(udp_pkt_t)+
  801.       sizeof(wp_mgmt_t)+
  802.       sizeof(cblock_t)+
  803.       sizeof(trace_info_t)+ 
  804.       mbox_len;
  805. /* fill in UDP reply */
  806. c_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY;
  807.    
  808. /* fill in UDP length */
  809. udp_length = sizeof(udp_pkt_t)+ 
  810.      sizeof(wp_mgmt_t)+
  811.      sizeof(cblock_t)+
  812.              sizeof(trace_info_t)+
  813.      mbox_len; 
  814.   /* put it on an even boundary */
  815. if ( udp_length & 0x0001 ) {
  816. udp_length += 1;
  817. len += 1;
  818. even_bound = 1;
  819. }  
  820. temp = (udp_length<<8)|(udp_length>>8);
  821. c_udp_pkt->udp_pkt.udp_length = temp;
  822.  
  823. /* swap UDP ports */
  824. temp = c_udp_pkt->udp_pkt.udp_src_port;
  825. c_udp_pkt->udp_pkt.udp_src_port = 
  826. c_udp_pkt->udp_pkt.udp_dst_port; 
  827. c_udp_pkt->udp_pkt.udp_dst_port = temp;
  828. /* add UDP pseudo header */
  829. temp = 0x1100;
  830. *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound)) = temp;
  831. temp = (udp_length<<8)|(udp_length>>8);
  832. *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound+2)) = temp;
  833.  
  834. /* calculate UDP checksum */
  835. c_udp_pkt->udp_pkt.udp_checksum = 0;
  836. c_udp_pkt->udp_pkt.udp_checksum = calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET);
  837. /* fill in IP length */
  838. ip_length = len;
  839. temp = (ip_length<<8)|(ip_length>>8);
  840. c_udp_pkt->ip_pkt.total_length = temp;
  841.   
  842. /* swap IP addresses */
  843. ip_temp = c_udp_pkt->ip_pkt.ip_src_address;
  844. c_udp_pkt->ip_pkt.ip_src_address = c_udp_pkt->ip_pkt.ip_dst_address;
  845. c_udp_pkt->ip_pkt.ip_dst_address = ip_temp;
  846. /* fill in IP checksum */
  847. c_udp_pkt->ip_pkt.hdr_checksum = 0;
  848. c_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t));
  849. return len;
  850. } /* reply_udp */
  851. unsigned short calc_checksum (char *data, int len)
  852. {
  853. unsigned short temp; 
  854. unsigned long sum=0;
  855. int i;
  856. for( i = 0; i <len; i+=2 ) {
  857. memcpy(&temp,&data[i],2);
  858. sum += (unsigned long)temp;
  859. }
  860. while (sum >> 16 ) {
  861. sum = (sum & 0xffffUL) + (sum >> 16);
  862. }
  863. temp = (unsigned short)sum;
  864. temp = ~temp;
  865. if( temp == 0 ) 
  866. temp = 0xffff;
  867. return temp;
  868. }
  869. /*============================================================================
  870.  * Get ethernet-style interface statistics.
  871.  * Return a pointer to struct enet_statistics.
  872.  */
  873. #if defined(LINUX_2_1) || defined(LINUX_2_4)
  874. static struct net_device_stats* if_stats (netdevice_t* dev)
  875. {
  876. sdla_t *my_card;
  877. chdlc_private_area_t* chdlc_priv_area;
  878. /* Shutdown bug fix. In del_if() we kill
  879.          * dev->priv pointer. This function, gets
  880.          * called after del_if(), thus check
  881.          * if pointer has been deleted */
  882. if ((chdlc_priv_area=dev->priv) == NULL)
  883. return NULL;
  884. my_card = chdlc_priv_area->card;
  885. return &my_card->wandev.stats; 
  886. }
  887. #else
  888. static struct enet_statistics* if_stats (netdevice_t* dev)
  889. {
  890.         sdla_t *my_card;
  891.         chdlc_private_area_t* chdlc_priv_area = dev->priv;
  892. /* Shutdown bug fix. In del_if() we kill
  893.          * dev->priv pointer. This function, gets
  894.          * called after del_if(), thus check
  895.          * if pointer has been deleted */
  896. if ((chdlc_priv_area=dev->priv) == NULL)
  897. return NULL;
  898.         my_card = chdlc_priv_area->card;
  899.         return &my_card->wandev.stats;
  900. }
  901. #endif
  902. /****** Cisco HDLC Firmware Interface Functions *******************************/
  903. /*============================================================================
  904.  * Read firmware code version.
  905.  * Put code version as ASCII string in str. 
  906.  */
  907. static int chdlc_read_version (sdla_t* card, char* str)
  908. {
  909. CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  910. int len;
  911. char err;
  912. mb->buffer_length = 0;
  913. mb->command = READ_CHDLC_CODE_VERSION;
  914. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  915. if(err != COMMAND_OK) {
  916. chdlc_error(card,err,mb);
  917. }
  918. else if (str) {  /* is not null */
  919. len = mb->buffer_length;
  920. memcpy(str, mb->data, len);
  921. str[len] = '';
  922. }
  923. return (err);
  924. }
  925. /*-----------------------------------------------------------------------------
  926.  *  Configure CHDLC firmware.
  927.  */
  928. static int chdlc_configure (sdla_t* card, void* data)
  929. {
  930. int err;
  931. CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;
  932. int data_length = sizeof(CHDLC_CONFIGURATION_STRUCT);
  933. mailbox->buffer_length = data_length;  
  934. memcpy(mailbox->data, data, data_length);
  935. mailbox->command = SET_CHDLC_CONFIGURATION;
  936. err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT;
  937. if (err != COMMAND_OK) chdlc_error (card, err, mailbox);
  938.                            
  939. return err;
  940. }
  941. /*============================================================================
  942.  * Set interrupt mode -- HDLC Version.
  943.  */
  944. static int chdlc_set_intr_mode (sdla_t* card, unsigned mode)
  945. {
  946. CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  947. CHDLC_INT_TRIGGERS_STRUCT* int_data =
  948.  (CHDLC_INT_TRIGGERS_STRUCT *)mb->data;
  949. int err;
  950. int_data->CHDLC_interrupt_triggers  = mode;
  951. int_data->IRQ = card->hw.irq;
  952. int_data->interrupt_timer               = 1;
  953.    
  954. mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT);
  955. mb->command = SET_CHDLC_INTERRUPT_TRIGGERS;
  956. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  957. if (err != COMMAND_OK)
  958. chdlc_error (card, err, mb);
  959. return err;
  960. }
  961. /*============================================================================
  962.  * Enable communications.
  963.  */
  964. static int chdlc_comm_enable (sdla_t* card)
  965. {
  966. int err;
  967. CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  968. mb->buffer_length = 0;
  969. mb->command = ENABLE_CHDLC_COMMUNICATIONS;
  970. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  971. if (err != COMMAND_OK)
  972. chdlc_error(card, err, mb);
  973. else
  974. card->u.c.comm_enabled=1;
  975. return err;
  976. }
  977. /*============================================================================
  978.  * Disable communications and Drop the Modem lines (DCD and RTS).
  979.  */
  980. static int chdlc_comm_disable (sdla_t* card)
  981. {
  982. int err;
  983. CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  984. mb->buffer_length = 0;
  985. mb->command = DISABLE_CHDLC_COMMUNICATIONS;
  986. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  987. if (err != COMMAND_OK)
  988. chdlc_error(card,err,mb);
  989. return err;
  990. }
  991. /*============================================================================
  992.  * Read communication error statistics.
  993.  */
  994. static int chdlc_read_comm_err_stats (sdla_t* card)
  995. {
  996.         int err;
  997.         CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  998.         mb->buffer_length = 0;
  999.         mb->command = READ_COMMS_ERROR_STATS;
  1000.         err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  1001.         if (err != COMMAND_OK)
  1002.                 chdlc_error(card,err,mb);
  1003.         return err;
  1004. }
  1005. /*============================================================================
  1006.  * Read CHDLC operational statistics.
  1007.  */
  1008. static int chdlc_read_op_stats (sdla_t* card)
  1009. {
  1010.         int err;
  1011.         CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  1012.         mb->buffer_length = 0;
  1013.         mb->command = READ_CHDLC_OPERATIONAL_STATS;
  1014.         err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  1015.         if (err != COMMAND_OK)
  1016.                 chdlc_error(card,err,mb);
  1017.         return err;
  1018. }
  1019. /*============================================================================
  1020.  * Update communications error and general packet statistics.
  1021.  */
  1022. static int update_comms_stats(sdla_t* card,
  1023. chdlc_private_area_t* chdlc_priv_area)
  1024. {
  1025.         CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  1026.    COMMS_ERROR_STATS_STRUCT* err_stats;
  1027.         CHDLC_OPERATIONAL_STATS_STRUCT *op_stats;
  1028. /* on the first timer interrupt, read the comms error statistics */
  1029. if(chdlc_priv_area->update_comms_stats == 2) {
  1030. if(chdlc_read_comm_err_stats(card))
  1031. return 1;
  1032. err_stats = (COMMS_ERROR_STATS_STRUCT *)mb->data;
  1033. card->wandev.stats.rx_over_errors = 
  1034. err_stats->Rx_overrun_err_count;
  1035. card->wandev.stats.rx_crc_errors = 
  1036. err_stats->CRC_err_count;
  1037. card->wandev.stats.rx_frame_errors = 
  1038. err_stats->Rx_abort_count;
  1039. card->wandev.stats.rx_fifo_errors = 
  1040. err_stats->Rx_dis_pri_bfrs_full_count; 
  1041. card->wandev.stats.rx_missed_errors =
  1042. card->wandev.stats.rx_fifo_errors;
  1043. card->wandev.stats.tx_aborted_errors =
  1044. err_stats->sec_Tx_abort_count;
  1045. }
  1046.         /* on the second timer interrupt, read the operational statistics */
  1047. else {
  1048.          if(chdlc_read_op_stats(card))
  1049.                  return 1;
  1050. op_stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)mb->data;
  1051. card->wandev.stats.rx_length_errors =
  1052. (op_stats->Rx_Data_discard_short_count +
  1053. op_stats->Rx_Data_discard_long_count);
  1054. }
  1055. return 0;
  1056. }
  1057. /*============================================================================
  1058.  * Send packet.
  1059.  * Return: 0 - o.k.
  1060.  * 1 - no transmit buffers available
  1061.  */
  1062. static int chdlc_send (sdla_t* card, void* data, unsigned len)
  1063. {
  1064. CHDLC_DATA_TX_STATUS_EL_STRUCT *txbuf = card->u.c.txbuf;
  1065. if (txbuf->opp_flag)
  1066. return 1;
  1067. sdla_poke(&card->hw, txbuf->ptr_data_bfr, data, len);
  1068. txbuf->frame_length = len;
  1069. txbuf->opp_flag = 1; /* start transmission */
  1070. /* Update transmit buffer control fields */
  1071. card->u.c.txbuf = ++txbuf;
  1072. if ((void*)txbuf > card->u.c.txbuf_last)
  1073. card->u.c.txbuf = card->u.c.txbuf_base;
  1074. return 0;
  1075. }
  1076. /****** Firmware Error Handler **********************************************/
  1077. /*============================================================================
  1078.  * Firmware error handler.
  1079.  * This routine is called whenever firmware command returns non-zero
  1080.  * return code.
  1081.  *
  1082.  * Return zero if previous command has to be cancelled.
  1083.  */
  1084. static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb)
  1085. {
  1086. unsigned cmd = mb->command;
  1087. switch (err) {
  1088. case CMD_TIMEOUT:
  1089. printk(KERN_ERR "%s: command 0x%02X timed out!n",
  1090. card->devname, cmd);
  1091. break;
  1092. case S514_BOTH_PORTS_SAME_CLK_MODE:
  1093. if(cmd == SET_CHDLC_CONFIGURATION) {
  1094. printk(KERN_INFO
  1095.  "%s: Configure both ports for the same clock sourcen",
  1096. card->devname);
  1097. break;
  1098. }
  1099. default:
  1100. printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!n",
  1101. card->devname, cmd, err);
  1102. }
  1103. return 0;
  1104. }
  1105. /****** Interrupt Handlers **************************************************/
  1106. /*============================================================================
  1107.  * Cisco HDLC interrupt service routine.
  1108.  */
  1109. STATIC void wsppp_isr (sdla_t* card)
  1110. {
  1111. netdevice_t* dev;
  1112. SHARED_MEMORY_INFO_STRUCT* flags = NULL;
  1113. int i;
  1114. sdla_t *my_card;
  1115. /* Check for which port the interrupt has been generated
  1116.  * Since Secondary Port is piggybacking on the Primary
  1117.          * the check must be done here. 
  1118.  */
  1119. flags = card->u.c.flags;
  1120. if (!flags->interrupt_info_struct.interrupt_type){
  1121. /* Check for a second port (piggybacking) */
  1122. if((my_card = card->next)){
  1123. flags = my_card->u.c.flags;
  1124. if (flags->interrupt_info_struct.interrupt_type){
  1125. card = my_card;
  1126. card->isr(card);
  1127. return;
  1128. }
  1129. }
  1130. }
  1131. dev = card->wandev.dev;
  1132. card->in_isr = 1;
  1133. flags = card->u.c.flags;
  1134. /* If we get an interrupt with no network device, stop the interrupts
  1135.  * and issue an error */
  1136. if ((!dev || !dev->priv) && flags->interrupt_info_struct.interrupt_type != 
  1137.      COMMAND_COMPLETE_APP_INT_PEND){
  1138. goto isr_done;
  1139. }
  1140. /* if critical due to peripheral operations
  1141.  * ie. update() or getstats() then reset the interrupt and
  1142.  * wait for the board to retrigger.
  1143.  */
  1144. if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) {
  1145. flags->interrupt_info_struct.
  1146. interrupt_type = 0;
  1147. goto isr_done;
  1148. }
  1149. /* On a 508 Card, if critical due to if_send 
  1150.          * Major Error !!!
  1151.  */
  1152. if(card->hw.type != SDLA_S514) {
  1153. if(test_bit(0, (void*)&card->wandev.critical)) {
  1154. printk(KERN_INFO "%s: Critical while in ISR: %lxn",
  1155. card->devname, card->wandev.critical);
  1156. goto isr_done;
  1157. }
  1158. }
  1159. switch(flags->interrupt_info_struct.interrupt_type) {
  1160. case RX_APP_INT_PEND: /* 0x01: receive interrupt */
  1161. rx_intr(card);
  1162. break;
  1163. case TX_APP_INT_PEND: /* 0x02: transmit interrupt */
  1164. flags->interrupt_info_struct.interrupt_permission &=
  1165.  ~APP_INT_ON_TX_FRAME;
  1166. wake_net_dev(dev);
  1167. break;
  1168. case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */
  1169. ++ Intr_test_counter;
  1170. break;
  1171. case CHDLC_EXCEP_COND_APP_INT_PEND: /* 0x20 */
  1172. process_chdlc_exception(card);
  1173. break;
  1174. case GLOBAL_EXCEP_COND_APP_INT_PEND:
  1175. process_global_exception(card);
  1176. break;
  1177. case TIMER_APP_INT_PEND:
  1178. timer_intr(card);
  1179. break;
  1180. default:
  1181. printk(KERN_INFO "%s: spurious interrupt 0x%02X!n", 
  1182. card->devname,
  1183. flags->interrupt_info_struct.interrupt_type);
  1184. printk(KERN_INFO "Code name: ");
  1185. for(i = 0; i < 4; i ++)
  1186. printk(KERN_INFO "%c",
  1187. flags->global_info_struct.codename[i]); 
  1188. printk(KERN_INFO "nCode version: ");
  1189. for(i = 0; i < 4; i ++)
  1190. printk(KERN_INFO "%c", 
  1191. flags->global_info_struct.codeversion[i]); 
  1192. printk(KERN_INFO "n");
  1193. break;
  1194. }
  1195. isr_done:
  1196. card->in_isr = 0;
  1197. flags->interrupt_info_struct.interrupt_type = 0;
  1198. }
  1199. /*============================================================================
  1200.  * Receive interrupt handler.
  1201.  */
  1202. static void rx_intr (sdla_t* card)
  1203. {
  1204. netdevice_t *dev;
  1205. chdlc_private_area_t *chdlc_priv_area;
  1206. SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
  1207. CHDLC_DATA_RX_STATUS_EL_STRUCT *rxbuf = card->u.c.rxmb;
  1208. struct sk_buff *skb;
  1209. unsigned len;
  1210. unsigned addr = rxbuf->ptr_data_bfr;
  1211. void *buf;
  1212. int i,udp_type;
  1213. if (rxbuf->opp_flag != 0x01) {
  1214. printk(KERN_INFO 
  1215. "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!n", 
  1216. card->devname, (unsigned)rxbuf, rxbuf->opp_flag);
  1217.                 printk(KERN_INFO "Code name: ");
  1218.                 for(i = 0; i < 4; i ++)
  1219.                         printk(KERN_INFO "%c",
  1220.                                 flags->global_info_struct.codename[i]);
  1221.                 printk(KERN_INFO "nCode version: ");
  1222.                 for(i = 0; i < 4; i ++)
  1223.                         printk(KERN_INFO "%c",
  1224.                                 flags->global_info_struct.codeversion[i]);
  1225.                 printk(KERN_INFO "n");
  1226. /* Bug Fix: Mar 6 2000
  1227.                  * If we get a corrupted mailbox, it measn that driver 
  1228.                  * is out of sync with the firmware. There is no recovery.
  1229.                  * If we don't turn off all interrupts for this card
  1230.                  * the machine will crash. 
  1231.                  */
  1232. printk(KERN_INFO "%s: Critical router failure ...!!!n", card->devname);
  1233. printk(KERN_INFO "Please contact Sangoma Technologies !n");
  1234. chdlc_set_intr_mode(card,0);
  1235. return;
  1236. }
  1237. dev = card->wandev.dev;
  1238. if (!dev){ 
  1239. goto rx_exit;
  1240. }
  1241. #ifdef LINUX_2_4
  1242. if (!netif_running(dev)){
  1243. goto rx_exit;
  1244. }
  1245. #else
  1246. if (!dev->start){ 
  1247. goto rx_exit;
  1248. }
  1249. #endif
  1250. chdlc_priv_area = dev->priv;
  1251. if (rxbuf->error_flag){
  1252. goto rx_exit;
  1253. }
  1254. /* Take off two CRC bytes */
  1255. if (rxbuf->frame_length < 7 || rxbuf->frame_length > 1506 ){
  1256. goto rx_exit;
  1257. }
  1258. len = rxbuf->frame_length - CRC_LENGTH;
  1259. /* Allocate socket buffer */
  1260. skb = dev_alloc_skb(len);
  1261. if (skb == NULL) {
  1262. if (net_ratelimit()){
  1263. printk(KERN_INFO "%s: no socket buffers available!n",
  1264. card->devname);
  1265. }
  1266. ++card->wandev.stats.rx_dropped;
  1267. goto rx_exit;
  1268. }
  1269. /* Copy data to the socket buffer */
  1270. if((addr + len) > card->u.c.rx_top + 1) {
  1271. unsigned tmp = card->u.c.rx_top - addr + 1;
  1272. buf = skb_put(skb, tmp);
  1273. sdla_peek(&card->hw, addr, buf, tmp);
  1274. addr = card->u.c.rx_base;
  1275. len -= tmp;
  1276. }
  1277. buf = skb_put(skb, len);
  1278. sdla_peek(&card->hw, addr, buf, len);
  1279. skb->protocol = htons(ETH_P_WAN_PPP);
  1280. card->wandev.stats.rx_packets ++;
  1281. #if defined(LINUX_2_1) || defined(LINUX_2_4)
  1282. card->wandev.stats.rx_bytes += skb->len;
  1283. #endif
  1284. udp_type = udp_pkt_type( skb, card );
  1285. if(udp_type == UDP_CPIPE_TYPE) {
  1286. if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK,
  1287.           card, skb, dev, chdlc_priv_area)) {
  1288.               flags->interrupt_info_struct.
  1289. interrupt_permission |= 
  1290. APP_INT_ON_TIMER; 
  1291. }
  1292. }else{
  1293.                 /* Pass it up the protocol stack */
  1294.                 skb->dev = dev;
  1295.                 skb->mac.raw  = skb->data;
  1296.                 netif_rx(skb);
  1297. }
  1298. rx_exit:
  1299. /* Release buffer element and calculate a pointer to the next one */
  1300. rxbuf->opp_flag = 0x00;
  1301. card->u.c.rxmb = ++ rxbuf;
  1302. if((void*)rxbuf > card->u.c.rxbuf_last){
  1303. card->u.c.rxmb = card->u.c.rxbuf_base;
  1304. }
  1305. }
  1306. /*============================================================================
  1307.  * Timer interrupt handler.
  1308.  * The timer interrupt is used for two purposes:
  1309.  *    1) Processing udp calls from 'cpipemon'.
  1310.  *    2) Reading board-level statistics for updating the proc file system.
  1311.  */
  1312. void timer_intr(sdla_t *card)
  1313. {
  1314.         netdevice_t* dev;
  1315.         chdlc_private_area_t* chdlc_priv_area = NULL;
  1316.         SHARED_MEMORY_INFO_STRUCT* flags = NULL;
  1317.         dev = card->wandev.dev; 
  1318.         chdlc_priv_area = dev->priv;
  1319. if (chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG) {
  1320. if (!config_chdlc(card)){
  1321. chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_CONFIG;
  1322. }
  1323. }
  1324. /* process a udp call if pending */
  1325.         if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP) {
  1326.                 process_udp_mgmt_pkt(card, dev,
  1327.                        chdlc_priv_area);
  1328. chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP;
  1329.         }
  1330. /* read the communications statistics if required */
  1331. if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE) {
  1332. update_comms_stats(card, chdlc_priv_area);
  1333.                 if(!(-- chdlc_priv_area->update_comms_stats)) {
  1334. chdlc_priv_area->timer_int_enabled &= 
  1335. ~TMR_INT_ENABLED_UPDATE;
  1336. }
  1337.         }
  1338. /* only disable the timer interrupt if there are no udp or statistic */
  1339. /* updates pending */
  1340.         if(!chdlc_priv_area->timer_int_enabled) {
  1341.                 flags = card->u.c.flags;
  1342.                 flags->interrupt_info_struct.interrupt_permission &=
  1343.                         ~APP_INT_ON_TIMER;
  1344.         }
  1345. }
  1346. /*------------------------------------------------------------------------------
  1347.   Miscellaneous Functions
  1348. - set_chdlc_config() used to set configuration options on the board
  1349. ------------------------------------------------------------------------------*/
  1350. static int set_chdlc_config(sdla_t* card)
  1351. {
  1352. CHDLC_CONFIGURATION_STRUCT cfg;
  1353. memset(&cfg, 0, sizeof(CHDLC_CONFIGURATION_STRUCT));
  1354. if(card->wandev.clocking)
  1355. cfg.baud_rate = card->wandev.bps;
  1356. cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
  1357. INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
  1358. cfg.modem_config_options = 0;
  1359. //API OPTIONS
  1360. cfg.CHDLC_API_options = DISCARD_RX_ERROR_FRAMES;
  1361. cfg.modem_status_timer = 100;
  1362. cfg.CHDLC_protocol_options = HDLC_STREAMING_MODE;
  1363. cfg.percent_data_buffer_for_Tx  = 50;
  1364. cfg.CHDLC_statistics_options = (CHDLC_TX_DATA_BYTE_COUNT_STAT |
  1365. CHDLC_RX_DATA_BYTE_COUNT_STAT);
  1366. cfg.max_CHDLC_data_field_length = card->wandev.mtu;
  1367. cfg.transmit_keepalive_timer = 0;
  1368. cfg.receive_keepalive_timer = 0;
  1369. cfg.keepalive_error_tolerance = 0;
  1370. cfg.SLARP_request_timer = 0;
  1371. cfg.IP_address = 0;
  1372. cfg.IP_netmask = 0;
  1373. return chdlc_configure(card, &cfg);
  1374. }
  1375. /*============================================================================
  1376.  * Process global exception condition
  1377.  */
  1378. static int process_global_exception(sdla_t *card)
  1379. {
  1380. CHDLC_MAILBOX_STRUCT* mbox = card->mbox;
  1381. int err;
  1382. mbox->buffer_length = 0;
  1383. mbox->command = READ_GLOBAL_EXCEPTION_CONDITION;
  1384. err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT;
  1385. if(err != CMD_TIMEOUT ){
  1386. switch(mbox->return_code) {
  1387.          
  1388.        case EXCEP_MODEM_STATUS_CHANGE:
  1389. printk(KERN_INFO "%s: Modem status changen",
  1390. card->devname);
  1391. switch(mbox->data[0] & (DCD_HIGH | CTS_HIGH)) {
  1392. case (DCD_HIGH):
  1393. printk(KERN_INFO "%s: DCD high, CTS lown",card->devname);
  1394. break;
  1395. case (CTS_HIGH):
  1396.                                         printk(KERN_INFO "%s: DCD low, CTS highn",card->devname);
  1397.                                         break;
  1398.                                 case ((DCD_HIGH | CTS_HIGH)):
  1399.                                         printk(KERN_INFO "%s: DCD high, CTS highn",card->devname);
  1400.                                         break;
  1401. default:
  1402.                                         printk(KERN_INFO "%s: DCD low, CTS lown",card->devname);
  1403.                                         break;
  1404. }
  1405. if (!(mbox->data[0] & DCD_HIGH) || !(mbox->data[0] & DCD_HIGH)){
  1406. //printk(KERN_INFO "Sending TERM Request Manually !n");
  1407. send_ppp_term_request(card->wandev.dev);
  1408. }
  1409. break;
  1410.                 case EXCEP_TRC_DISABLED:
  1411.                         printk(KERN_INFO "%s: Line trace disabledn",
  1412. card->devname);
  1413.                         break;
  1414. case EXCEP_IRQ_TIMEOUT:
  1415. printk(KERN_INFO "%s: IRQ timeout occurredn",
  1416. card->devname); 
  1417. break;
  1418.                 default:
  1419.                         printk(KERN_INFO "%s: Global exception %xn",
  1420. card->devname, mbox->return_code);
  1421.                         break;
  1422.                 }
  1423. }
  1424. return 0;
  1425. }
  1426. /*============================================================================
  1427.  * Process chdlc exception condition
  1428.  */
  1429. static int process_chdlc_exception(sdla_t *card)
  1430. {
  1431. CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  1432. int err;
  1433. mb->buffer_length = 0;
  1434. mb->command = READ_CHDLC_EXCEPTION_CONDITION;
  1435. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  1436. if(err != CMD_TIMEOUT) {
  1437. switch (err) {
  1438. case EXCEP_LINK_ACTIVE:
  1439. port_set_state(card, WAN_CONNECTED);
  1440. break;
  1441. case EXCEP_LINK_INACTIVE_MODEM:
  1442. port_set_state(card, WAN_DISCONNECTED);
  1443. break;
  1444. case EXCEP_LOOPBACK_CONDITION:
  1445. printk(KERN_INFO "%s: Loopback Condition Detected.n",
  1446. card->devname);
  1447. break;
  1448. case NO_CHDLC_EXCEP_COND_TO_REPORT:
  1449. printk(KERN_INFO "%s: No exceptions reported.n",
  1450. card->devname);
  1451. break;
  1452. default:
  1453. printk(KERN_INFO "%s: Exception Condition %x!n",
  1454. card->devname,err);
  1455. break;
  1456. }
  1457. }
  1458. return 0;
  1459. }
  1460. /*=============================================================================
  1461.  * Store a UDP management packet for later processing.
  1462.  */
  1463. static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
  1464.                                 struct sk_buff *skb, netdevice_t* dev,
  1465.                                 chdlc_private_area_t* chdlc_priv_area )
  1466. {
  1467. int udp_pkt_stored = 0;
  1468. if(!chdlc_priv_area->udp_pkt_lgth &&
  1469.   (skb->len <= MAX_LGTH_UDP_MGNT_PKT)) {
  1470.          chdlc_priv_area->udp_pkt_lgth = skb->len;
  1471. chdlc_priv_area->udp_pkt_src = udp_pkt_src;
  1472.         memcpy(chdlc_priv_area->udp_pkt_data, skb->data, skb->len);
  1473. chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UDP;
  1474. udp_pkt_stored = 1;
  1475. }
  1476. if(udp_pkt_src == UDP_PKT_FRM_STACK)
  1477. wan_dev_kfree_skb(skb, FREE_WRITE);
  1478. else
  1479.                 wan_dev_kfree_skb(skb, FREE_READ);
  1480. return(udp_pkt_stored);
  1481. }
  1482. /*=============================================================================
  1483.  * Process UDP management packet.
  1484.  */
  1485. static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev,
  1486. chdlc_private_area_t* chdlc_priv_area ) 
  1487. {
  1488. unsigned char *buf;
  1489. unsigned int frames, len;
  1490. struct sk_buff *new_skb;
  1491. unsigned short buffer_length, real_len;
  1492. unsigned long data_ptr;
  1493. unsigned data_length;
  1494. int udp_mgmt_req_valid = 1;
  1495. CHDLC_MAILBOX_STRUCT *mb = card->mbox;
  1496. SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
  1497. chdlc_udp_pkt_t *chdlc_udp_pkt;
  1498. struct timeval tv;
  1499. int err;
  1500. char ut_char;
  1501. chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data;
  1502. if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
  1503. switch(chdlc_udp_pkt->cblock.command) {
  1504. case READ_GLOBAL_STATISTICS:
  1505. case READ_MODEM_STATUS:  
  1506. case READ_CHDLC_LINK_STATUS:
  1507. case CPIPE_ROUTER_UP_TIME:
  1508. case READ_COMMS_ERROR_STATS:
  1509. case READ_CHDLC_OPERATIONAL_STATS:
  1510. /* These two commands are executed for
  1511.  * each request */
  1512. case READ_CHDLC_CONFIGURATION:
  1513. case READ_CHDLC_CODE_VERSION:
  1514. udp_mgmt_req_valid = 1;
  1515. break;
  1516. default:
  1517. udp_mgmt_req_valid = 0;
  1518. break;
  1519. }
  1520.    if(!udp_mgmt_req_valid) {
  1521. /* set length to 0 */
  1522. chdlc_udp_pkt->cblock.buffer_length = 0;
  1523.      /* set return code */
  1524. chdlc_udp_pkt->cblock.return_code = 0xCD;
  1525. if (net_ratelimit()){
  1526. printk(KERN_INFO 
  1527. "%s: Warning, Illegal UDP command attempted from network: %xn",
  1528. card->devname,chdlc_udp_pkt->cblock.command);
  1529. }
  1530.     } else {
  1531.     unsigned long trace_status_cfg_addr = 0;
  1532. TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct;
  1533. TRACE_STATUS_ELEMENT_STRUCT trace_element_struct;
  1534. switch(chdlc_udp_pkt->cblock.command) {
  1535. case CPIPE_ENABLE_TRACING:
  1536.      if (!chdlc_priv_area->TracingEnabled) {
  1537. /* OPERATE_DATALINE_MONITOR */
  1538. mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
  1539. mb->command = SET_TRACE_CONFIGURATION;
  1540.      ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
  1541. trace_config = TRACE_ACTIVE;
  1542. /* Trace delay mode is not used because it slows
  1543.    down transfer and results in a standoff situation
  1544.    when there is a lot of data */
  1545. /* Configure the Trace based on user inputs */
  1546. ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |= 
  1547. chdlc_udp_pkt->data[0];
  1548. ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
  1549.    trace_deactivation_timer = 4000;
  1550. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  1551. if (err != COMMAND_OK) {
  1552. chdlc_error(card,err,mb);
  1553. card->TracingEnabled = 0;
  1554. chdlc_udp_pkt->cblock.return_code = err;
  1555. mb->buffer_length = 0;
  1556. break;
  1557.      } 
  1558. /* Get the base address of the trace element list */
  1559. mb->buffer_length = 0;
  1560. mb->command = READ_TRACE_CONFIGURATION;
  1561. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  1562. if (err != COMMAND_OK) {
  1563. chdlc_error(card,err,mb);
  1564. chdlc_priv_area->TracingEnabled = 0;
  1565. chdlc_udp_pkt->cblock.return_code = err;
  1566. mb->buffer_length = 0;
  1567. break;
  1568.      } 
  1569.     trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *)
  1570. mb->data) -> ptr_trace_stat_el_cfg_struct;
  1571. sdla_peek(&card->hw, trace_status_cfg_addr,
  1572.  &trace_cfg_struct, sizeof(trace_cfg_struct));
  1573.     
  1574. chdlc_priv_area->start_trace_addr = trace_cfg_struct.
  1575. base_addr_trace_status_elements;
  1576. chdlc_priv_area->number_trace_elements = 
  1577. trace_cfg_struct.number_trace_status_elements;
  1578. chdlc_priv_area->end_trace_addr = (unsigned long)
  1579. ((TRACE_STATUS_ELEMENT_STRUCT *)
  1580.  chdlc_priv_area->start_trace_addr + 
  1581.  (chdlc_priv_area->number_trace_elements - 1));
  1582. chdlc_priv_area->base_addr_trace_buffer = 
  1583. trace_cfg_struct.base_addr_trace_buffer;
  1584. chdlc_priv_area->end_addr_trace_buffer = 
  1585. trace_cfg_struct.end_addr_trace_buffer;
  1586.      chdlc_priv_area->curr_trace_addr = 
  1587. trace_cfg_struct.next_trace_element_to_use;
  1588.      chdlc_priv_area->available_buffer_space = 2000 - 
  1589.   sizeof(ip_pkt_t) -
  1590.   sizeof(udp_pkt_t) -
  1591.          sizeof(wp_mgmt_t) -
  1592.   sizeof(cblock_t) -
  1593.           sizeof(trace_info_t);
  1594.              }
  1595.      chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
  1596.      mb->buffer_length = 0;
  1597.              chdlc_priv_area->TracingEnabled = 1;
  1598.              break;
  1599.    
  1600. case CPIPE_DISABLE_TRACING:
  1601.      if (chdlc_priv_area->TracingEnabled) {
  1602. /* OPERATE_DATALINE_MONITOR */
  1603. mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
  1604. mb->command = SET_TRACE_CONFIGURATION;
  1605.      ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
  1606. trace_config = TRACE_INACTIVE;
  1607. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  1608.      }
  1609.      chdlc_priv_area->TracingEnabled = 0;
  1610.      chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
  1611.      mb->buffer_length = 0;
  1612.      break;
  1613.    
  1614. case CPIPE_GET_TRACE_INFO:
  1615.      if (!chdlc_priv_area->TracingEnabled) {
  1616. chdlc_udp_pkt->cblock.return_code = 1;
  1617. mb->buffer_length = 0;
  1618. break;
  1619.      }
  1620.         chdlc_udp_pkt->trace_info.ismoredata = 0x00;
  1621.      buffer_length = 0; /* offset of packet already occupied */
  1622.      for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){
  1623. trace_pkt_t *trace_pkt = (trace_pkt_t *)
  1624. &chdlc_udp_pkt->data[buffer_length];
  1625. sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr,
  1626.       (unsigned char *)&trace_element_struct,
  1627.       sizeof(TRACE_STATUS_ELEMENT_STRUCT));
  1628.       if (trace_element_struct.opp_flag == 0x00) {
  1629.   break;
  1630. }
  1631. /* get pointer to real data */
  1632. data_ptr = trace_element_struct.ptr_data_bfr;
  1633. /* See if there is actual data on the trace buffer */
  1634. if (data_ptr){
  1635. data_length = trace_element_struct.trace_length;
  1636. }else{
  1637. data_length = 0;
  1638. chdlc_udp_pkt->trace_info.ismoredata = 0x01;
  1639. }
  1640.     if( (chdlc_priv_area->available_buffer_space - buffer_length)
  1641. < ( sizeof(trace_pkt_t) + data_length) ) {
  1642.                             /* indicate there are more frames on board & exit */
  1643. chdlc_udp_pkt->trace_info.ismoredata = 0x01;
  1644.                                 break;
  1645.                          }
  1646. trace_pkt->status = trace_element_struct.trace_type;
  1647. trace_pkt->time_stamp =
  1648. trace_element_struct.trace_time_stamp;
  1649. trace_pkt->real_length =
  1650. trace_element_struct.trace_length;
  1651. /* see if we can fit the frame into the user buffer */
  1652. real_len = trace_pkt->real_length;
  1653. if (data_ptr == 0) {
  1654.       trace_pkt->data_avail = 0x00;
  1655. } else {
  1656. unsigned tmp = 0;
  1657. /* get the data from circular buffer
  1658.     must check for end of buffer */
  1659.         trace_pkt->data_avail = 0x01;
  1660. if ((data_ptr + real_len) >
  1661.      chdlc_priv_area->end_addr_trace_buffer + 1){
  1662.      tmp = chdlc_priv_area->end_addr_trace_buffer - data_ptr + 1;
  1663.      sdla_peek(&card->hw, data_ptr,
  1664.           trace_pkt->data,tmp);
  1665.      data_ptr = chdlc_priv_area->base_addr_trace_buffer;
  1666. }
  1667.          sdla_peek(&card->hw, data_ptr,
  1668.   &trace_pkt->data[tmp], real_len - tmp);
  1669. }
  1670. /* zero the opp flag to show we got the frame */
  1671. ut_char = 0x00;
  1672. sdla_poke(&card->hw, chdlc_priv_area->curr_trace_addr, &ut_char, 1);
  1673.         /* now move onto the next frame */
  1674.         chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT);
  1675.         /* check if we went over the last address */
  1676. if ( chdlc_priv_area->curr_trace_addr > chdlc_priv_area->end_trace_addr ) {
  1677. chdlc_priv_area->curr_trace_addr = chdlc_priv_area->start_trace_addr;
  1678.         }
  1679.              if(trace_pkt->data_avail == 0x01) {
  1680. buffer_length += real_len - 1;
  1681. }
  1682.  
  1683.              /* for the header */
  1684.              buffer_length += sizeof(trace_pkt_t);
  1685.      }  /* For Loop */
  1686.      if (frames == chdlc_priv_area->number_trace_elements){
  1687. chdlc_udp_pkt->trace_info.ismoredata = 0x01;
  1688.              }
  1689.        chdlc_udp_pkt->trace_info.num_frames = frames;
  1690.  
  1691.           mb->buffer_length = buffer_length;
  1692.      chdlc_udp_pkt->cblock.buffer_length = buffer_length; 
  1693.  
  1694.      chdlc_udp_pkt->cblock.return_code = COMMAND_OK; 
  1695.      
  1696.      break;
  1697. case CPIPE_FT1_READ_STATUS:
  1698. ((unsigned char *)chdlc_udp_pkt->data )[0] =
  1699. flags->FT1_info_struct.parallel_port_A_input;
  1700. ((unsigned char *)chdlc_udp_pkt->data )[1] =
  1701. flags->FT1_info_struct.parallel_port_B_input;
  1702.  
  1703. chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
  1704. mb->buffer_length = 2;
  1705. break;
  1706. case CPIPE_ROUTER_UP_TIME:
  1707. do_gettimeofday( &tv );
  1708. chdlc_priv_area->router_up_time = tv.tv_sec - 
  1709. chdlc_priv_area->router_start_time;
  1710. *(unsigned long *)&chdlc_udp_pkt->data = 
  1711. chdlc_priv_area->router_up_time;
  1712. mb->buffer_length = sizeof(unsigned long);
  1713. break;
  1714.     case FT1_MONITOR_STATUS_CTRL:
  1715. /* Enable FT1 MONITOR STATUS */
  1716.          if ((chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_STATUS) ||  
  1717. (chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_OP_STATS)) {
  1718.       if( rCount++ != 0 ) {
  1719. chdlc_udp_pkt->cblock.
  1720. return_code = COMMAND_OK;
  1721. mb->buffer_length = 1;
  1722.    break;
  1723.            }
  1724.        }
  1725.        /* Disable FT1 MONITOR STATUS */
  1726.        if( chdlc_udp_pkt->data[0] == 0) {
  1727.                  if( --rCount != 0) {
  1728.    chdlc_udp_pkt->cblock.
  1729. return_code = COMMAND_OK;
  1730. mb->buffer_length = 1;
  1731.    break;
  1732.                } 
  1733.        } 
  1734. default:
  1735. /* it's a board command */
  1736. mb->command = chdlc_udp_pkt->cblock.command;
  1737. mb->buffer_length = chdlc_udp_pkt->cblock.buffer_length;
  1738. if (mb->buffer_length) {
  1739. memcpy(&mb->data, (unsigned char *) chdlc_udp_pkt->
  1740. data, mb->buffer_length);
  1741.        } 
  1742. /* run the command on the board */
  1743. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  1744. if (err != COMMAND_OK) {
  1745. break;
  1746. }
  1747. /* copy the result back to our buffer */
  1748.           memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t)); 
  1749. if (mb->buffer_length) {
  1750.           memcpy(&chdlc_udp_pkt->data, &mb->data, 
  1751. mb->buffer_length); 
  1752.        }
  1753. } /* end of switch */
  1754.       } /* end of else */
  1755.       /* Fill UDP TTL */
  1756. chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl; 
  1757.       len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length);
  1758.       if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
  1759. if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) {
  1760. ++ card->wandev.stats.tx_packets;
  1761. #if defined(LINUX_2_1) || defined(LINUX_2_4)
  1762. card->wandev.stats.tx_bytes += len;
  1763. #endif
  1764. }
  1765. } else {
  1766. /* Pass it up the stack
  1767.         Allocate socket buffer */
  1768. if ((new_skb = dev_alloc_skb(len)) != NULL) {
  1769. /* copy data into new_skb */
  1770.        buf = skb_put(new_skb, len);
  1771.         memcpy(buf, chdlc_priv_area->udp_pkt_data, len);
  1772.              /* Decapsulate pkt and pass it up the protocol stack */
  1773.      new_skb->protocol = htons(ETH_P_IP);
  1774.              new_skb->dev = dev;
  1775.      new_skb->mac.raw  = new_skb->data;
  1776. netif_rx(new_skb);
  1777. } else {
  1778.     
  1779. printk(KERN_INFO "%s: no socket buffers available!n",
  1780. card->devname);
  1781.    }
  1782.      }
  1783.  
  1784. chdlc_priv_area->udp_pkt_lgth = 0;
  1785.  
  1786. return 0;
  1787. }
  1788. /*============================================================================
  1789.  * Initialize Receive and Transmit Buffers.
  1790.  */
  1791. static void init_chdlc_tx_rx_buff( sdla_t* card, netdevice_t *dev )
  1792. {
  1793. CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  1794. CHDLC_TX_STATUS_EL_CFG_STRUCT *tx_config;
  1795. CHDLC_RX_STATUS_EL_CFG_STRUCT *rx_config;
  1796. char err;
  1797. mb->buffer_length = 0;
  1798. mb->command = READ_CHDLC_CONFIGURATION;
  1799. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  1800. if(err != COMMAND_OK) {
  1801. chdlc_error(card,err,mb);
  1802. return;
  1803. }
  1804. if(card->hw.type == SDLA_S514) {
  1805. tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
  1806.                 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
  1807.                             ptr_CHDLC_Tx_stat_el_cfg_struct));
  1808.          rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
  1809.                 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
  1810.                             ptr_CHDLC_Rx_stat_el_cfg_struct));
  1811.         /* Setup Head and Tails for buffers */
  1812.          card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
  1813.                 tx_config->base_addr_Tx_status_elements);
  1814.          card->u.c.txbuf_last = 
  1815. (CHDLC_DATA_TX_STATUS_EL_STRUCT *)  
  1816.                 card->u.c.txbuf_base +
  1817. (tx_config->number_Tx_status_elements - 1);
  1818.          card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
  1819.                 rx_config->base_addr_Rx_status_elements);
  1820.          card->u.c.rxbuf_last =
  1821. (CHDLC_DATA_RX_STATUS_EL_STRUCT *)
  1822.                 card->u.c.rxbuf_base +
  1823. (rx_config->number_Rx_status_elements - 1);
  1824.   /* Set up next pointer to be used */
  1825.          card->u.c.txbuf = (void *)(card->hw.dpmbase +
  1826.                 tx_config->next_Tx_status_element_to_use);
  1827.          card->u.c.rxmb = (void *)(card->hw.dpmbase +
  1828.                 rx_config->next_Rx_status_element_to_use);
  1829. }
  1830.         else {
  1831.                 tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
  1832. (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
  1833. ptr_CHDLC_Tx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
  1834.                 rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
  1835. (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
  1836. ptr_CHDLC_Rx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
  1837.                 /* Setup Head and Tails for buffers */
  1838.                 card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
  1839. (tx_config->base_addr_Tx_status_elements % SDLA_WINDOWSIZE));
  1840.                 card->u.c.txbuf_last =
  1841. (CHDLC_DATA_TX_STATUS_EL_STRUCT *)card->u.c.txbuf_base
  1842. + (tx_config->number_Tx_status_elements - 1);
  1843.                 card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
  1844. (rx_config->base_addr_Rx_status_elements % SDLA_WINDOWSIZE));
  1845.                 card->u.c.rxbuf_last = 
  1846. (CHDLC_DATA_RX_STATUS_EL_STRUCT *)card->u.c.rxbuf_base
  1847. + (rx_config->number_Rx_status_elements - 1);
  1848.                  /* Set up next pointer to be used */
  1849.                 card->u.c.txbuf = (void *)(card->hw.dpmbase +
  1850. (tx_config->next_Tx_status_element_to_use % SDLA_WINDOWSIZE));
  1851.                 card->u.c.rxmb = (void *)(card->hw.dpmbase +
  1852. (rx_config->next_Rx_status_element_to_use % SDLA_WINDOWSIZE));
  1853.         }
  1854.         /* Setup Actual Buffer Start and end addresses */
  1855.         card->u.c.rx_base = rx_config->base_addr_Rx_buffer;
  1856.         card->u.c.rx_top  = rx_config->end_addr_Rx_buffer;
  1857. }
  1858. /*=============================================================================
  1859.  * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR
  1860.  * _TEST_COUNTER times.
  1861.  */
  1862. static int intr_test( sdla_t* card)
  1863. {
  1864. CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  1865. int err,i;
  1866. Intr_test_counter = 0;
  1867. /* The critical flag is unset because during intialization (if_open) 
  1868.  * we want the interrupts to be enabled so that when the wpc_isr is
  1869.  * called it does not exit due to critical flag set.
  1870.  */ 
  1871. err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE);
  1872. if (err == CMD_OK) { 
  1873. for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) {
  1874. mb->buffer_length  = 0;
  1875. mb->command = READ_CHDLC_CODE_VERSION;
  1876. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  1877. }
  1878. }
  1879. else {
  1880. return err;
  1881. }
  1882. err = chdlc_set_intr_mode(card, 0);
  1883. if (err != CMD_OK)
  1884. return err;
  1885. return 0;
  1886. }
  1887. /*==============================================================================
  1888.  * Determine what type of UDP call it is. CPIPEAB ?
  1889.  */
  1890. static int udp_pkt_type(struct sk_buff *skb, sdla_t* card)
  1891. {
  1892.  chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data;
  1893. if (!strncmp(chdlc_udp_pkt->wp_mgmt.signature,UDPMGMT_SIGNATURE,8) &&
  1894.    (chdlc_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) &&
  1895.    (chdlc_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) &&
  1896.    (chdlc_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) {
  1897. return UDP_CPIPE_TYPE;
  1898. }
  1899. else return UDP_INVALID_TYPE;
  1900. }
  1901. /*============================================================================
  1902.  * Set PORT state.
  1903.  */
  1904. static void port_set_state (sdla_t *card, int state)
  1905. {
  1906. netdevice_t *dev = card->wandev.dev;
  1907. chdlc_private_area_t *chdlc_priv_area = dev->priv;
  1908.         if (card->u.c.state != state)
  1909.         {
  1910.                 switch (state)
  1911.                 {
  1912.                 case WAN_CONNECTED:
  1913.                         printk (KERN_INFO "%s: HDLC link connected!n",
  1914.                                 card->devname);
  1915.                       break;
  1916.                 case WAN_CONNECTING:
  1917.                         printk (KERN_INFO "%s: HDLC link connecting...n",
  1918.                                 card->devname);
  1919.                         break;
  1920.                 case WAN_DISCONNECTED:
  1921.                         printk (KERN_INFO "%s: HDLC link disconnected!n",
  1922.                                 card->devname);
  1923.                         break;
  1924.                 }
  1925.                 card->wandev.state = card->u.c.state = state;
  1926. chdlc_priv_area->common.state = state;
  1927.         }
  1928. }
  1929. void s508_lock (sdla_t *card, unsigned long *smp_flags)
  1930. {
  1931. #if defined(__SMP__) || defined(LINUX_2_4)
  1932. spin_lock_irqsave(&card->wandev.lock, *smp_flags);
  1933.         if (card->next){
  1934. /* It is ok to use spin_lock here, since we
  1935.  * already turned off interrupts */
  1936.          spin_lock(&card->next->wandev.lock);
  1937. }
  1938. #else
  1939. disable_irq(card->hw.irq);
  1940. #endif
  1941. }
  1942. void s508_unlock (sdla_t *card, unsigned long *smp_flags)
  1943. {
  1944. #if defined(__SMP__) || defined(LINUX_2_4)
  1945. if (card->next){
  1946. spin_unlock(&card->next->wandev.lock);
  1947. }
  1948. spin_unlock_irqrestore(&card->wandev.lock, *smp_flags);
  1949. #else
  1950. enable_irq(card->hw.irq);
  1951. #endif           
  1952. }
  1953. /*===========================================================================
  1954.  * config_chdlc
  1955.  *
  1956.  * Configure the chdlc protocol and enable communications.
  1957.  *
  1958.  *    The if_open() function binds this function to the poll routine.
  1959.  *      Therefore, this function will run every time the chdlc interface
  1960.  *      is brought up. We cannot run this function from the if_open 
  1961.  *      because if_open does not have access to the remote IP address.
  1962.  *      
  1963.  * If the communications are not enabled, proceed to configure
  1964.  *      the card and enable communications.
  1965.  *
  1966.  *      If the communications are enabled, it means that the interface
  1967.  *      was shutdown by ether the user or driver. In this case, we 
  1968.  *      have to check that the IP addresses have not changed.  If
  1969.  *      the IP addresses have changed, we have to reconfigure the firmware
  1970.  *      and update the changed IP addresses.  Otherwise, just exit.
  1971.  *
  1972.  */
  1973. static int config_chdlc (sdla_t *card)
  1974. {
  1975. netdevice_t *dev = card->wandev.dev;
  1976. SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
  1977. if (card->u.c.comm_enabled){
  1978. chdlc_comm_disable(card);
  1979. port_set_state(card, WAN_DISCONNECTED);
  1980. }
  1981. if (set_chdlc_config(card)) {
  1982. printk(KERN_INFO "%s: CHDLC Configuration Failed!n",
  1983. card->devname);
  1984. return 0;
  1985. }
  1986. init_chdlc_tx_rx_buff(card, dev);
  1987. /* Set interrupt mode and mask */
  1988.         if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME |
  1989.                  APP_INT_ON_GLOBAL_EXCEP_COND |
  1990.                  APP_INT_ON_TX_FRAME |
  1991.                  APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){
  1992. printk (KERN_INFO "%s: Failed to set interrupt triggers!n",
  1993. card->devname);
  1994. return 0;
  1995.         }
  1996. /* Mask the Transmit and Timer interrupt */
  1997. flags->interrupt_info_struct.interrupt_permission &= 
  1998. ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
  1999. if (chdlc_comm_enable(card) != 0) {
  2000. printk(KERN_INFO "%s: Failed to enable chdlc communications!n",
  2001. card->devname);
  2002. flags->interrupt_info_struct.interrupt_permission = 0;
  2003. card->u.c.comm_enabled=0;
  2004. chdlc_set_intr_mode(card,0);
  2005. return 0;
  2006. }
  2007. /* Initialize Rx/Tx buffer control fields */
  2008. port_set_state(card, WAN_CONNECTING);
  2009. return 0; 
  2010. }
  2011. static void send_ppp_term_request (netdevice_t *dev)
  2012. {
  2013. struct sk_buff *new_skb;
  2014. unsigned char *buf;
  2015. if ((new_skb = dev_alloc_skb(8)) != NULL) {
  2016. /* copy data into new_skb */
  2017. buf = skb_put(new_skb, 8);
  2018. sprintf(buf,"%c%c%c%c%c%c%c%c", 0xFF,0x03,0xC0,0x21,0x05,0x98,0x00,0x07);
  2019. /* Decapsulate pkt and pass it up the protocol stack */
  2020. new_skb->protocol = htons(ETH_P_WAN_PPP);
  2021. new_skb->dev = dev;
  2022. new_skb->mac.raw  = new_skb->data;
  2023. netif_rx(new_skb);
  2024. }
  2025. }
  2026. MODULE_LICENSE("GPL");
  2027. /****** End ****************************************************************/