sdla_chdlc.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:129k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. return chdlc_configure(card, &cfg);
  2. }
  3. /*-----------------------------------------------------------------------------
  4.    set_asy_config() used to set asynchronous configuration options on the board
  5. ------------------------------------------------------------------------------*/
  6. static int set_asy_config(sdla_t* card)
  7. {
  8.         ASY_CONFIGURATION_STRUCT cfg;
  9.   CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;
  10. int err;
  11. memset(&cfg, 0, sizeof(ASY_CONFIGURATION_STRUCT));
  12. if(card->wandev.clocking)
  13. cfg.baud_rate = card->wandev.bps;
  14. cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
  15. INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
  16. cfg.modem_config_options = 0;
  17. cfg.asy_API_options  = card->u.c.api_options;
  18. cfg.asy_protocol_options = card->u.c.protocol_options;
  19. cfg.Tx_bits_per_char = card->u.c.tx_bits_per_char;
  20. cfg.Rx_bits_per_char = card->u.c.rx_bits_per_char;
  21. cfg.stop_bits = card->u.c.stop_bits;
  22. cfg.parity = card->u.c.parity;
  23. cfg.break_timer = card->u.c.break_timer;
  24. cfg.asy_Rx_inter_char_timer = card->u.c.inter_char_timer; 
  25. cfg.asy_Rx_complete_length = card->u.c.rx_complete_length; 
  26. cfg.XON_char = card->u.c.xon_char;
  27. cfg.XOFF_char = card->u.c.xoff_char;
  28. cfg.asy_statistics_options = (CHDLC_TX_DATA_BYTE_COUNT_STAT |
  29. CHDLC_RX_DATA_BYTE_COUNT_STAT);
  30. mailbox->buffer_length = sizeof(ASY_CONFIGURATION_STRUCT);
  31. memcpy(mailbox->data, &cfg, mailbox->buffer_length);
  32. mailbox->command = SET_ASY_CONFIGURATION;
  33. err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT;
  34. if (err != COMMAND_OK) 
  35. chdlc_error (card, err, mailbox);
  36. return err;
  37. }
  38. /*============================================================================
  39.  * Enable asynchronous communications.
  40.  */
  41. static int asy_comm_enable (sdla_t* card)
  42. {
  43. int err;
  44. CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  45. mb->buffer_length = 0;
  46. mb->command = ENABLE_ASY_COMMUNICATIONS;
  47. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  48. if (err != COMMAND_OK && card->wandev.dev)
  49. chdlc_error(card, err, mb);
  50. if (!err)
  51. card->u.c.comm_enabled = 1;
  52. return err;
  53. }
  54. /*============================================================================
  55.  * Process global exception condition
  56.  */
  57. static int process_global_exception(sdla_t *card)
  58. {
  59. CHDLC_MAILBOX_STRUCT* mbox = card->mbox;
  60. int err;
  61. mbox->buffer_length = 0;
  62. mbox->command = READ_GLOBAL_EXCEPTION_CONDITION;
  63. err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT;
  64. if(err != CMD_TIMEOUT ){
  65. switch(mbox->return_code) {
  66.          
  67.        case EXCEP_MODEM_STATUS_CHANGE:
  68. printk(KERN_INFO "%s: Modem status changen",
  69. card->devname);
  70. switch(mbox->data[0] & (DCD_HIGH | CTS_HIGH)) {
  71. case (DCD_HIGH):
  72. printk(KERN_INFO "%s: DCD high, CTS lown",card->devname);
  73. break;
  74. case (CTS_HIGH):
  75.                                         printk(KERN_INFO "%s: DCD low, CTS highn",card->devname); 
  76. break;
  77.                                 case ((DCD_HIGH | CTS_HIGH)):
  78.                                         printk(KERN_INFO "%s: DCD high, CTS highn",card->devname);
  79.                                         break;
  80. default:
  81.                                         printk(KERN_INFO "%s: DCD low, CTS lown",card->devname);
  82.                                         break;
  83. }
  84. break;
  85.                 case EXCEP_TRC_DISABLED:
  86.                         printk(KERN_INFO "%s: Line trace disabledn",
  87. card->devname);
  88.                         break;
  89. case EXCEP_IRQ_TIMEOUT:
  90. printk(KERN_INFO "%s: IRQ timeout occurredn",
  91. card->devname); 
  92. break;
  93. case 0x17:
  94. if (card->tty_opt){
  95. if (card->tty && card->tty_open){ 
  96. printk(KERN_INFO 
  97. "%s: Modem Hangup Exception: Hanging Up!n",
  98. card->devname);
  99. tty_hangup(card->tty);
  100. }
  101. break;
  102. }
  103. /* If TTY is not used just drop throught */
  104.                 default:
  105.                         printk(KERN_INFO "%s: Global exception %xn",
  106. card->devname, mbox->return_code);
  107.                         break;
  108.                 }
  109. }
  110. return 0;
  111. }
  112. /*============================================================================
  113.  * Process chdlc exception condition
  114.  */
  115. static int process_chdlc_exception(sdla_t *card)
  116. {
  117. CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  118. int err;
  119. mb->buffer_length = 0;
  120. mb->command = READ_CHDLC_EXCEPTION_CONDITION;
  121. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  122. if(err != CMD_TIMEOUT) {
  123. switch (err) {
  124. case EXCEP_LINK_ACTIVE:
  125. port_set_state(card, WAN_CONNECTED);
  126. trigger_chdlc_poll(card->wandev.dev);
  127. break;
  128. case EXCEP_LINK_INACTIVE_MODEM:
  129. port_set_state(card, WAN_DISCONNECTED);
  130. unconfigure_ip(card);
  131. trigger_chdlc_poll(card->wandev.dev);
  132. break;
  133. case EXCEP_LINK_INACTIVE_KPALV:
  134. port_set_state(card, WAN_DISCONNECTED);
  135. printk(KERN_INFO "%s: Keepalive timer expired.n",
  136.   card->devname);
  137. unconfigure_ip(card);
  138. trigger_chdlc_poll(card->wandev.dev);
  139. break;
  140. case EXCEP_IP_ADDRESS_DISCOVERED:
  141. if (configure_ip(card)) 
  142. return -1;
  143. break;
  144. case EXCEP_LOOPBACK_CONDITION:
  145. printk(KERN_INFO "%s: Loopback Condition Detected.n",
  146. card->devname);
  147. break;
  148. case NO_CHDLC_EXCEP_COND_TO_REPORT:
  149. printk(KERN_INFO "%s: No exceptions reported.n",
  150. card->devname);
  151. break;
  152. }
  153. }
  154. return 0;
  155. }
  156. /*============================================================================
  157.  * Configure IP from SLARP negotiation
  158.  * This adds dynamic routes when SLARP has provided valid addresses
  159.  */
  160. static int configure_ip (sdla_t* card)
  161. {
  162. netdevice_t *dev = card->wandev.dev;
  163.         chdlc_private_area_t *chdlc_priv_area;
  164.         char err;
  165. if (!dev)
  166. return 0;
  167. chdlc_priv_area = dev->priv;
  168.         /* set to discover */
  169.         if(card->u.c.slarp_timer != 0x00) {
  170. CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  171. CHDLC_CONFIGURATION_STRUCT *cfg;
  172.       mb->buffer_length = 0;
  173. mb->command = READ_CHDLC_CONFIGURATION;
  174. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  175. if(err != COMMAND_OK) {
  176. chdlc_error(card,err,mb);
  177. return -1;
  178. }
  179. cfg = (CHDLC_CONFIGURATION_STRUCT *)mb->data;
  180.                 chdlc_priv_area->IP_address = cfg->IP_address;
  181.                 chdlc_priv_area->IP_netmask = cfg->IP_netmask;
  182. /* Set flag to add route */
  183. chdlc_priv_area->route_status = ADD_ROUTE;
  184. /* The idea here is to add the route in the poll routine.
  185.     This way, we aren't in interrupt context when adding routes */
  186. trigger_chdlc_poll(dev);
  187.         }
  188. return 0;
  189. }
  190. /*============================================================================
  191.  * Un-Configure IP negotiated by SLARP
  192.  * This removes dynamic routes when the link becomes inactive.
  193.  */
  194. static int unconfigure_ip (sdla_t* card)
  195. {
  196. netdevice_t *dev = card->wandev.dev;
  197. chdlc_private_area_t *chdlc_priv_area;
  198. if (!dev)
  199. return 0;
  200. chdlc_priv_area= dev->priv;
  201. if (chdlc_priv_area->route_status == ROUTE_ADDED) {
  202. /* Note: If this function is called, the 
  203.                  * port state has been DISCONNECTED.  This state
  204.                  * change will trigger a poll_disconnected 
  205.                  * function, that will check for this condition. 
  206.  */
  207. chdlc_priv_area->route_status = REMOVE_ROUTE;
  208. }
  209. return 0;
  210. }
  211. /*============================================================================
  212.  * Routine to add/remove routes 
  213.  * Called like a polling routine when Routes are flagged to be added/removed.
  214.  */
  215. static void process_route (sdla_t *card)
  216. {
  217.         netdevice_t *dev = card->wandev.dev;
  218.         unsigned char port_num;
  219.         chdlc_private_area_t *chdlc_priv_area = NULL;
  220. u32 local_IP_addr = 0;
  221. u32 remote_IP_addr = 0;
  222. u32 IP_netmask, IP_addr;
  223.         int err = 0;
  224. #if defined(LINUX_2_1) || defined(LINUX_2_4)
  225. struct in_device *in_dev;
  226. mm_segment_t fs;
  227. struct ifreq if_info;
  228.         struct sockaddr_in *if_data1, *if_data2;
  229. #else
  230. unsigned long fs = 0;
  231.         struct rtentry route;
  232. #endif
  233.         chdlc_priv_area = dev->priv;
  234.         port_num = card->u.c.comm_port;
  235. /* Bug Fix Mar 16 2000
  236.  * AND the IP address to the Mask before checking
  237.          * the last two bits. */
  238. if((chdlc_priv_area->route_status == ADD_ROUTE) &&
  239. ((chdlc_priv_area->IP_address & ~chdlc_priv_area->IP_netmask) > 2)) {
  240. printk(KERN_INFO "%s: Dynamic route failure.n",card->devname);
  241.                 if(card->u.c.slarp_timer) {
  242. u32 addr_net = htonl(chdlc_priv_area->IP_address);
  243. printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u receivedn",
  244. card->devname,
  245.        NIPQUAD(addr_net));
  246.                         printk(KERN_INFO "%s: from remote station.n",
  247. card->devname);
  248.                 }else{ 
  249. u32 addr_net = htonl(chdlc_priv_area->IP_address);
  250.                         printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u issuedn",
  251.        card->devname,
  252.        NIPQUAD(addr_net));
  253.                         printk(KERN_INFO "%s: to remote station. Localn",
  254. card->devname);
  255. printk(KERN_INFO "%s: IP address must be A.B.C.1n",
  256. card->devname);
  257. printk(KERN_INFO "%s: or A.B.C.2.n",card->devname);
  258. }
  259. /* remove the route due to the IP address error condition */
  260. chdlc_priv_area->route_status = REMOVE_ROUTE;
  261. err = 1;
  262.     }
  263. /* If we are removing a route with bad IP addressing, then use the */
  264. /* locally configured IP addresses */
  265.         if((chdlc_priv_area->route_status == REMOVE_ROUTE) && err) {
  266.           /* do not remove a bad route that has already been removed */
  267.          if(chdlc_priv_area->route_removed) {
  268.                 return;
  269.          }
  270. #if defined(LINUX_2_1) || defined(LINUX_2_4)
  271.                 in_dev = dev->ip_ptr;
  272.                 if(in_dev != NULL) {
  273.                         struct in_ifaddr *ifa = in_dev->ifa_list;
  274.                         if (ifa != NULL ) {
  275.                                 local_IP_addr = ifa->ifa_local;
  276.                                 IP_netmask  = ifa->ifa_mask;
  277.                         }
  278.                 }
  279. #else
  280.                 local_IP_addr = dev->pa_addr;
  281.                 remote_IP_addr = dev->pa_dstaddr;
  282.                 IP_netmask = dev->pa_mask;
  283. #endif
  284. }else{ 
  285.         /* According to Cisco HDLC, if the point-to-point address is
  286.    A.B.C.1, then we are the opposite (A.B.C.2), and vice-versa.
  287. */
  288. IP_netmask = ntohl(chdlc_priv_area->IP_netmask);
  289.         remote_IP_addr = ntohl(chdlc_priv_area->IP_address);
  290. /* If Netmask is 255.255.255.255 the local address
  291.                  * calculation will fail. Default it back to 255.255.255.0 */
  292. if (IP_netmask == 0xffffffff)
  293. IP_netmask &= 0x00ffffff;
  294. /* Bug Fix Mar 16 2000
  295.  * AND the Remote IP address with IP netmask, instead
  296.                  * of static netmask of 255.255.255.0 */
  297.          local_IP_addr = (remote_IP_addr & IP_netmask) +
  298.                  (~remote_IP_addr & ntohl(0x0003));
  299.         if(!card->u.c.slarp_timer) {
  300. IP_addr = local_IP_addr;
  301. local_IP_addr = remote_IP_addr;
  302. remote_IP_addr = IP_addr;
  303.         }
  304. }
  305.         fs = get_fs();                  /* Save file system  */
  306.         set_fs(get_ds());               /* Get user space block */
  307. #if defined(LINUX_2_1) || defined(LINUX_2_4)
  308.         /* Setup a structure for adding/removing routes */
  309.         memset(&if_info, 0, sizeof(if_info));
  310.         strcpy(if_info.ifr_name, dev->name);
  311. #else
  312. /* Setup a structure for adding/removing routes */
  313. dev->pa_mask = IP_netmask;
  314. dev->pa_dstaddr = remote_IP_addr;
  315. dev->pa_addr = local_IP_addr;
  316. memset(&route, 0, sizeof(route));
  317. route.rt_dev = dev->name;
  318. route.rt_flags = 0;
  319. ((struct sockaddr_in *)&(route.rt_dst))->sin_addr.s_addr =
  320. dev->pa_dstaddr;
  321. ((struct sockaddr_in *)&(route.rt_dst))->sin_family = AF_INET;
  322. ((struct sockaddr_in *)&(route.rt_genmask))->sin_addr.s_addr =
  323. 0xFFFFFFFF;
  324.         ((struct sockaddr_in *)&(route.rt_genmask))->sin_family =
  325. AF_INET;
  326. #endif
  327. switch (chdlc_priv_area->route_status) {
  328. case ADD_ROUTE:
  329. if(!card->u.c.slarp_timer) {
  330. #if defined(LINUX_2_1) || defined(LINUX_2_4)
  331. if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
  332. if_data2->sin_addr.s_addr = remote_IP_addr;
  333. if_data2->sin_family = AF_INET;
  334. err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
  335. #else
  336.                         err = ip_rt_new(&route);
  337. #endif
  338. } else { 
  339. #if defined(LINUX_2_1) || defined(LINUX_2_4)
  340. if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
  341. if_data1->sin_addr.s_addr = local_IP_addr;
  342. if_data1->sin_family = AF_INET;
  343. if(!(err = devinet_ioctl(SIOCSIFADDR, &if_info))){
  344. if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
  345. if_data2->sin_addr.s_addr = remote_IP_addr;
  346. if_data2->sin_family = AF_INET;
  347. err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
  348. }
  349. #else
  350.                 err = ip_rt_new(&route);
  351. #endif
  352. }
  353.                if(err) {
  354. printk(KERN_INFO "%s: Add route %u.%u.%u.%u failed (%d)n", 
  355. card->devname, NIPQUAD(remote_IP_addr), err);
  356. } else {
  357. ((chdlc_private_area_t *)dev->priv)->route_status = ROUTE_ADDED;
  358. printk(KERN_INFO "%s: Dynamic route added.n",
  359. card->devname);
  360. printk(KERN_INFO "%s:    Local IP addr : %u.%u.%u.%un",
  361. card->devname, NIPQUAD(local_IP_addr));
  362. printk(KERN_INFO "%s:    Remote IP addr: %u.%u.%u.%un",
  363. card->devname, NIPQUAD(remote_IP_addr));
  364. chdlc_priv_area->route_removed = 0;
  365. }
  366. break;
  367. case REMOVE_ROUTE:
  368. #if defined(LINUX_2_1) || defined(LINUX_2_4)
  369. /* Change the local ip address of the interface to 0.
  370.  * This will also delete the destination route.
  371.  */
  372. if(!card->u.c.slarp_timer) {
  373. if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
  374. if_data2->sin_addr.s_addr = 0;
  375. if_data2->sin_family = AF_INET;
  376. err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
  377. } else {
  378. if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
  379. if_data1->sin_addr.s_addr = 0;
  380. if_data1->sin_family = AF_INET;
  381. err = devinet_ioctl(SIOCSIFADDR,&if_info);
  382. }
  383. #else
  384. /* set the point-to-point IP address to 0.0.0.0 */
  385. dev->pa_dstaddr = 0; 
  386. err = ip_rt_kill(&route);
  387. #endif
  388. if(err) {
  389. printk(KERN_INFO
  390. "%s: Remove route %u.%u.%u.%u failed, (err %d)n",
  391. card->devname, NIPQUAD(remote_IP_addr),
  392. err);
  393. } else {
  394. ((chdlc_private_area_t *)dev->priv)->route_status =
  395. NO_ROUTE;
  396.                         printk(KERN_INFO "%s: Dynamic route removed: %u.%u.%u.%un",
  397.                                         card->devname, NIPQUAD(local_IP_addr)); 
  398. chdlc_priv_area->route_removed = 1;
  399. }
  400. break;
  401. }
  402.         set_fs(fs);                     /* Restore file system */
  403. }
  404. /*=============================================================================
  405.  * Store a UDP management packet for later processing.
  406.  */
  407. static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
  408.                                 struct sk_buff *skb, netdevice_t* dev,
  409.                                 chdlc_private_area_t* chdlc_priv_area )
  410. {
  411. int udp_pkt_stored = 0;
  412. if(!chdlc_priv_area->udp_pkt_lgth &&
  413.   (skb->len <= MAX_LGTH_UDP_MGNT_PKT)) {
  414.          chdlc_priv_area->udp_pkt_lgth = skb->len;
  415. chdlc_priv_area->udp_pkt_src = udp_pkt_src;
  416.         memcpy(chdlc_priv_area->udp_pkt_data, skb->data, skb->len);
  417. chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UDP;
  418. udp_pkt_stored = 1;
  419. }
  420. if(udp_pkt_src == UDP_PKT_FRM_STACK){
  421. wan_dev_kfree_skb(skb, FREE_WRITE);
  422. }else{
  423.                 wan_dev_kfree_skb(skb, FREE_READ);
  424. }
  425. return(udp_pkt_stored);
  426. }
  427. /*=============================================================================
  428.  * Process UDP management packet.
  429.  */
  430. static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev,
  431. chdlc_private_area_t* chdlc_priv_area ) 
  432. {
  433. unsigned char *buf;
  434. unsigned int frames, len;
  435. struct sk_buff *new_skb;
  436. unsigned short buffer_length, real_len;
  437. unsigned long data_ptr;
  438. unsigned data_length;
  439. int udp_mgmt_req_valid = 1;
  440. CHDLC_MAILBOX_STRUCT *mb = card->mbox;
  441. SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
  442. chdlc_udp_pkt_t *chdlc_udp_pkt;
  443. struct timeval tv;
  444. int err;
  445. char ut_char;
  446. chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data;
  447. if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK){
  448. /* Only these commands are support for remote debugging.
  449.  * All others are not */
  450. switch(chdlc_udp_pkt->cblock.command) {
  451. case READ_GLOBAL_STATISTICS:
  452. case READ_MODEM_STATUS:  
  453. case READ_CHDLC_LINK_STATUS:
  454. case CPIPE_ROUTER_UP_TIME:
  455. case READ_COMMS_ERROR_STATS:
  456. case READ_CHDLC_OPERATIONAL_STATS:
  457. /* These two commands are executed for
  458.  * each request */
  459. case READ_CHDLC_CONFIGURATION:
  460. case READ_CHDLC_CODE_VERSION:
  461. udp_mgmt_req_valid = 1;
  462. break;
  463. default:
  464. udp_mgmt_req_valid = 0;
  465. break;
  466. }
  467.    if(!udp_mgmt_req_valid) {
  468. /* set length to 0 */
  469. chdlc_udp_pkt->cblock.buffer_length = 0;
  470.      /* set return code */
  471. chdlc_udp_pkt->cblock.return_code = 0xCD;
  472. if (net_ratelimit()){
  473. printk(KERN_INFO 
  474. "%s: Warning, Illegal UDP command attempted from network: %xn",
  475. card->devname,chdlc_udp_pkt->cblock.command);
  476. }
  477.     } else {
  478.     unsigned long trace_status_cfg_addr = 0;
  479. TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct;
  480. TRACE_STATUS_ELEMENT_STRUCT trace_element_struct;
  481. switch(chdlc_udp_pkt->cblock.command) {
  482. case CPIPE_ENABLE_TRACING:
  483.      if (!chdlc_priv_area->TracingEnabled) {
  484. /* OPERATE_DATALINE_MONITOR */
  485. mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
  486. mb->command = SET_TRACE_CONFIGURATION;
  487.      ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
  488. trace_config = TRACE_ACTIVE;
  489. /* Trace delay mode is not used because it slows
  490.    down transfer and results in a standoff situation
  491.    when there is a lot of data */
  492. /* Configure the Trace based on user inputs */
  493. ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |= 
  494. chdlc_udp_pkt->data[0];
  495. ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
  496.    trace_deactivation_timer = 4000;
  497. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  498. if (err != COMMAND_OK) {
  499. chdlc_error(card,err,mb);
  500. card->TracingEnabled = 0;
  501. chdlc_udp_pkt->cblock.return_code = err;
  502. mb->buffer_length = 0;
  503. break;
  504.      } 
  505. /* Get the base address of the trace element list */
  506. mb->buffer_length = 0;
  507. mb->command = READ_TRACE_CONFIGURATION;
  508. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  509. if (err != COMMAND_OK) {
  510. chdlc_error(card,err,mb);
  511. chdlc_priv_area->TracingEnabled = 0;
  512. chdlc_udp_pkt->cblock.return_code = err;
  513. mb->buffer_length = 0;
  514. break;
  515.      } 
  516.     trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *)
  517. mb->data) -> ptr_trace_stat_el_cfg_struct;
  518. sdla_peek(&card->hw, trace_status_cfg_addr,
  519.  &trace_cfg_struct, sizeof(trace_cfg_struct));
  520.     
  521. chdlc_priv_area->start_trace_addr = trace_cfg_struct.
  522. base_addr_trace_status_elements;
  523. chdlc_priv_area->number_trace_elements = 
  524. trace_cfg_struct.number_trace_status_elements;
  525. chdlc_priv_area->end_trace_addr = (unsigned long)
  526. ((TRACE_STATUS_ELEMENT_STRUCT *)
  527.  chdlc_priv_area->start_trace_addr + 
  528.  (chdlc_priv_area->number_trace_elements - 1));
  529. chdlc_priv_area->base_addr_trace_buffer = 
  530. trace_cfg_struct.base_addr_trace_buffer;
  531. chdlc_priv_area->end_addr_trace_buffer = 
  532. trace_cfg_struct.end_addr_trace_buffer;
  533.      chdlc_priv_area->curr_trace_addr = 
  534. trace_cfg_struct.next_trace_element_to_use;
  535.      chdlc_priv_area->available_buffer_space = 2000 - 
  536.   sizeof(ip_pkt_t) -
  537.   sizeof(udp_pkt_t) -
  538.          sizeof(wp_mgmt_t) -
  539.   sizeof(cblock_t) -
  540.           sizeof(trace_info_t);
  541.              }
  542.      chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
  543.      mb->buffer_length = 0;
  544.              chdlc_priv_area->TracingEnabled = 1;
  545.              break;
  546.    
  547. case CPIPE_DISABLE_TRACING:
  548.      if (chdlc_priv_area->TracingEnabled) {
  549. /* OPERATE_DATALINE_MONITOR */
  550. mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
  551. mb->command = SET_TRACE_CONFIGURATION;
  552.      ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
  553. trace_config = TRACE_INACTIVE;
  554. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  555.      }
  556.      chdlc_priv_area->TracingEnabled = 0;
  557.      chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
  558.      mb->buffer_length = 0;
  559.      break;
  560.    
  561. case CPIPE_GET_TRACE_INFO:
  562.      if (!chdlc_priv_area->TracingEnabled) {
  563. chdlc_udp_pkt->cblock.return_code = 1;
  564. mb->buffer_length = 0;
  565. break;
  566.      }
  567.         chdlc_udp_pkt->trace_info.ismoredata = 0x00;
  568.      buffer_length = 0; /* offset of packet already occupied */
  569.      for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){
  570. trace_pkt_t *trace_pkt = (trace_pkt_t *)
  571. &chdlc_udp_pkt->data[buffer_length];
  572. sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr,
  573.       (unsigned char *)&trace_element_struct,
  574.       sizeof(TRACE_STATUS_ELEMENT_STRUCT));
  575.       if (trace_element_struct.opp_flag == 0x00) {
  576.   break;
  577. }
  578. /* get pointer to real data */
  579. data_ptr = trace_element_struct.ptr_data_bfr;
  580. /* See if there is actual data on the trace buffer */
  581. if (data_ptr){
  582. data_length = trace_element_struct.trace_length;
  583. }else{
  584. data_length = 0;
  585. chdlc_udp_pkt->trace_info.ismoredata = 0x01;
  586. }
  587.     if( (chdlc_priv_area->available_buffer_space - buffer_length)
  588. < ( sizeof(trace_pkt_t) + data_length) ) {
  589.                             /* indicate there are more frames on board & exit */
  590. chdlc_udp_pkt->trace_info.ismoredata = 0x01;
  591.                                 break;
  592.                          }
  593. trace_pkt->status = trace_element_struct.trace_type;
  594. trace_pkt->time_stamp =
  595. trace_element_struct.trace_time_stamp;
  596. trace_pkt->real_length =
  597. trace_element_struct.trace_length;
  598. /* see if we can fit the frame into the user buffer */
  599. real_len = trace_pkt->real_length;
  600. if (data_ptr == 0) {
  601.       trace_pkt->data_avail = 0x00;
  602. } else {
  603. unsigned tmp = 0;
  604. /* get the data from circular buffer
  605.     must check for end of buffer */
  606.         trace_pkt->data_avail = 0x01;
  607. if ((data_ptr + real_len) >
  608.      chdlc_priv_area->end_addr_trace_buffer + 1){
  609.      tmp = chdlc_priv_area->end_addr_trace_buffer - data_ptr + 1;
  610.      sdla_peek(&card->hw, data_ptr,
  611.           trace_pkt->data,tmp);
  612.      data_ptr = chdlc_priv_area->base_addr_trace_buffer;
  613. }
  614.          sdla_peek(&card->hw, data_ptr,
  615.   &trace_pkt->data[tmp], real_len - tmp);
  616. }
  617. /* zero the opp flag to show we got the frame */
  618. ut_char = 0x00;
  619. sdla_poke(&card->hw, chdlc_priv_area->curr_trace_addr, &ut_char, 1);
  620.         /* now move onto the next frame */
  621.         chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT);
  622.         /* check if we went over the last address */
  623. if ( chdlc_priv_area->curr_trace_addr > chdlc_priv_area->end_trace_addr ) {
  624. chdlc_priv_area->curr_trace_addr = chdlc_priv_area->start_trace_addr;
  625.         }
  626.              if(trace_pkt->data_avail == 0x01) {
  627. buffer_length += real_len - 1;
  628. }
  629.  
  630.              /* for the header */
  631.              buffer_length += sizeof(trace_pkt_t);
  632.      }  /* For Loop */
  633.      if (frames == chdlc_priv_area->number_trace_elements){
  634. chdlc_udp_pkt->trace_info.ismoredata = 0x01;
  635.              }
  636.        chdlc_udp_pkt->trace_info.num_frames = frames;
  637.  
  638.           mb->buffer_length = buffer_length;
  639.      chdlc_udp_pkt->cblock.buffer_length = buffer_length; 
  640.  
  641.      chdlc_udp_pkt->cblock.return_code = COMMAND_OK; 
  642.      
  643.      break;
  644. case CPIPE_FT1_READ_STATUS:
  645. ((unsigned char *)chdlc_udp_pkt->data )[0] =
  646. flags->FT1_info_struct.parallel_port_A_input;
  647. ((unsigned char *)chdlc_udp_pkt->data )[1] =
  648. flags->FT1_info_struct.parallel_port_B_input;
  649. chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
  650. chdlc_udp_pkt->cblock.buffer_length = 2;
  651. mb->buffer_length = 2;
  652. break;
  653. case CPIPE_ROUTER_UP_TIME:
  654. do_gettimeofday( &tv );
  655. chdlc_priv_area->router_up_time = tv.tv_sec - 
  656. chdlc_priv_area->router_start_time;
  657. *(unsigned long *)&chdlc_udp_pkt->data = 
  658. chdlc_priv_area->router_up_time;
  659. mb->buffer_length = sizeof(unsigned long);
  660. chdlc_udp_pkt->cblock.buffer_length = sizeof(unsigned long);
  661. chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
  662. break;
  663.     case FT1_MONITOR_STATUS_CTRL:
  664. /* Enable FT1 MONITOR STATUS */
  665.          if ((chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_STATUS) ||  
  666. (chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_OP_STATS)) {
  667.       if( rCount++ != 0 ) {
  668. chdlc_udp_pkt->cblock.
  669. return_code = COMMAND_OK;
  670. mb->buffer_length = 1;
  671.    break;
  672.            }
  673.        }
  674.        /* Disable FT1 MONITOR STATUS */
  675.        if( chdlc_udp_pkt->data[0] == 0) {
  676.                  if( --rCount != 0) {
  677.    chdlc_udp_pkt->cblock.
  678. return_code = COMMAND_OK;
  679. mb->buffer_length = 1;
  680.    break;
  681.                } 
  682.        } 
  683. goto dflt_1;
  684. default:
  685. dflt_1:
  686. /* it's a board command */
  687. mb->command = chdlc_udp_pkt->cblock.command;
  688. mb->buffer_length = chdlc_udp_pkt->cblock.buffer_length;
  689. if (mb->buffer_length) {
  690. memcpy(&mb->data, (unsigned char *) chdlc_udp_pkt->
  691. data, mb->buffer_length);
  692.        } 
  693. /* run the command on the board */
  694. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  695. if (err != COMMAND_OK) {
  696. break;
  697. }
  698. /* copy the result back to our buffer */
  699.           memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t)); 
  700. if (mb->buffer_length) {
  701.           memcpy(&chdlc_udp_pkt->data, &mb->data, 
  702. mb->buffer_length); 
  703.        }
  704. } /* end of switch */
  705.       } /* end of else */
  706.       /* Fill UDP TTL */
  707. chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl; 
  708.       len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length);
  709.       if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK){
  710. /* Must check if we interrupted if_send() routine. The
  711.  * tx buffers might be used. If so drop the packet */
  712.     if (!test_bit(SEND_CRIT,&card->wandev.critical)) {
  713. if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) {
  714. ++ card->wandev.stats.tx_packets;
  715. #if defined(LINUX_2_1) || defined(LINUX_2_4)
  716. card->wandev.stats.tx_bytes += len;
  717. #endif
  718. }
  719. }
  720. } else {
  721. /* Pass it up the stack
  722.         Allocate socket buffer */
  723. if ((new_skb = dev_alloc_skb(len)) != NULL) {
  724. /* copy data into new_skb */
  725.        buf = skb_put(new_skb, len);
  726.         memcpy(buf, chdlc_priv_area->udp_pkt_data, len);
  727.              /* Decapsulate pkt and pass it up the protocol stack */
  728.      new_skb->protocol = htons(ETH_P_IP);
  729.              new_skb->dev = dev;
  730.      new_skb->mac.raw  = new_skb->data;
  731. netif_rx(new_skb);
  732. } else {
  733.     
  734. printk(KERN_INFO "%s: no socket buffers available!n",
  735. card->devname);
  736.    }
  737.      }
  738.  
  739. chdlc_priv_area->udp_pkt_lgth = 0;
  740.  
  741. return 0;
  742. }
  743. /*============================================================================
  744.  * Initialize Receive and Transmit Buffers.
  745.  */
  746. static void init_chdlc_tx_rx_buff( sdla_t* card)
  747. {
  748. CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  749. CHDLC_TX_STATUS_EL_CFG_STRUCT *tx_config;
  750. CHDLC_RX_STATUS_EL_CFG_STRUCT *rx_config;
  751. char err;
  752. mb->buffer_length = 0;
  753. mb->command = READ_CHDLC_CONFIGURATION;
  754. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  755. if(err != COMMAND_OK) {
  756. if (card->wandev.dev){
  757. chdlc_error(card,err,mb);
  758. }
  759. return;
  760. }
  761. if(card->hw.type == SDLA_S514) {
  762. tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
  763.                 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
  764.                             ptr_CHDLC_Tx_stat_el_cfg_struct));
  765.          rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
  766.                 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
  767.                             ptr_CHDLC_Rx_stat_el_cfg_struct));
  768.         /* Setup Head and Tails for buffers */
  769.          card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
  770.                 tx_config->base_addr_Tx_status_elements);
  771.          card->u.c.txbuf_last = 
  772. (CHDLC_DATA_TX_STATUS_EL_STRUCT *)  
  773.                 card->u.c.txbuf_base +
  774. (tx_config->number_Tx_status_elements - 1);
  775.          card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
  776.                 rx_config->base_addr_Rx_status_elements);
  777.          card->u.c.rxbuf_last =
  778. (CHDLC_DATA_RX_STATUS_EL_STRUCT *)
  779.                 card->u.c.rxbuf_base +
  780. (rx_config->number_Rx_status_elements - 1);
  781.   /* Set up next pointer to be used */
  782.          card->u.c.txbuf = (void *)(card->hw.dpmbase +
  783.                 tx_config->next_Tx_status_element_to_use);
  784.          card->u.c.rxmb = (void *)(card->hw.dpmbase +
  785.                 rx_config->next_Rx_status_element_to_use);
  786. }
  787.         else {
  788.                 tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
  789. (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
  790. ptr_CHDLC_Tx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
  791.                 rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
  792. (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
  793. ptr_CHDLC_Rx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
  794.                 /* Setup Head and Tails for buffers */
  795.                 card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
  796. (tx_config->base_addr_Tx_status_elements % SDLA_WINDOWSIZE));
  797.                 card->u.c.txbuf_last =
  798. (CHDLC_DATA_TX_STATUS_EL_STRUCT *)card->u.c.txbuf_base
  799. + (tx_config->number_Tx_status_elements - 1);
  800.                 card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
  801. (rx_config->base_addr_Rx_status_elements % SDLA_WINDOWSIZE));
  802.                 card->u.c.rxbuf_last = 
  803. (CHDLC_DATA_RX_STATUS_EL_STRUCT *)card->u.c.rxbuf_base
  804. + (rx_config->number_Rx_status_elements - 1);
  805.                  /* Set up next pointer to be used */
  806.                 card->u.c.txbuf = (void *)(card->hw.dpmbase +
  807. (tx_config->next_Tx_status_element_to_use % SDLA_WINDOWSIZE));
  808.                 card->u.c.rxmb = (void *)(card->hw.dpmbase +
  809. (rx_config->next_Rx_status_element_to_use % SDLA_WINDOWSIZE));
  810.         }
  811.         /* Setup Actual Buffer Start and end addresses */
  812.         card->u.c.rx_base = rx_config->base_addr_Rx_buffer;
  813.         card->u.c.rx_top  = rx_config->end_addr_Rx_buffer;
  814. }
  815. /*=============================================================================
  816.  * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR
  817.  * _TEST_COUNTER times.
  818.  */
  819. static int intr_test( sdla_t* card)
  820. {
  821. CHDLC_MAILBOX_STRUCT* mb = card->mbox;
  822. int err,i;
  823. Intr_test_counter = 0;
  824. err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE);
  825. if (err == CMD_OK) { 
  826. for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) {
  827. mb->buffer_length  = 0;
  828. mb->command = READ_CHDLC_CODE_VERSION;
  829. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  830. if (err != CMD_OK) 
  831. chdlc_error(card, err, mb);
  832. }
  833. }
  834. else {
  835. return err;
  836. }
  837. err = chdlc_set_intr_mode(card, 0);
  838. if (err != CMD_OK)
  839. return err;
  840. return 0;
  841. }
  842. /*==============================================================================
  843.  * Determine what type of UDP call it is. CPIPEAB ?
  844.  */
  845. static int udp_pkt_type(struct sk_buff *skb, sdla_t* card)
  846. {
  847.  chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data;
  848. #ifdef _WAN_UDP_DEBUG
  849. printk(KERN_INFO "SIG %s = %sn
  850.   UPP %x = %xn
  851.   PRT %x = %xn
  852.   REQ %i = %in
  853.   36 th = %x 37th = %xn",
  854.   chdlc_udp_pkt->wp_mgmt.signature,
  855.   UDPMGMT_SIGNATURE,
  856.   chdlc_udp_pkt->udp_pkt.udp_dst_port,
  857.   ntohs(card->wandev.udp_port),
  858.   chdlc_udp_pkt->ip_pkt.protocol,
  859.   UDPMGMT_UDP_PROTOCOL,
  860.   chdlc_udp_pkt->wp_mgmt.request_reply,
  861.   UDPMGMT_REQUEST,
  862.   skb->data[36], skb->data[37]);
  863. #endif
  864. if (!strncmp(chdlc_udp_pkt->wp_mgmt.signature,UDPMGMT_SIGNATURE,8) &&
  865.    (chdlc_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) &&
  866.    (chdlc_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) &&
  867.    (chdlc_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) {
  868. return UDP_CPIPE_TYPE;
  869. }else{ 
  870. return UDP_INVALID_TYPE;
  871. }
  872. }
  873. /*============================================================================
  874.  * Set PORT state.
  875.  */
  876. static void port_set_state (sdla_t *card, int state)
  877. {
  878.         if (card->u.c.state != state)
  879.         {
  880.                 switch (state)
  881.                 {
  882.                 case WAN_CONNECTED:
  883.                         printk (KERN_INFO "%s: Link connected!n",
  884.                                 card->devname);
  885.                        break;
  886.                 case WAN_CONNECTING:
  887.                         printk (KERN_INFO "%s: Link connecting...n",
  888.                                 card->devname);
  889.                         break;
  890.                 case WAN_DISCONNECTED:
  891.                         printk (KERN_INFO "%s: Link disconnected!n",
  892.                                 card->devname);
  893.                         break;
  894.                 }
  895.                 card->wandev.state = card->u.c.state = state;
  896. if (card->wandev.dev){
  897. netdevice_t *dev = card->wandev.dev;
  898. chdlc_private_area_t *chdlc_priv_area = dev->priv;
  899. chdlc_priv_area->common.state = state;
  900. }
  901.         }
  902. }
  903. /*===========================================================================
  904.  * config_chdlc
  905.  *
  906.  * Configure the chdlc protocol and enable communications.
  907.  *
  908.  *    The if_open() function binds this function to the poll routine.
  909.  *      Therefore, this function will run every time the chdlc interface
  910.  *      is brought up. We cannot run this function from the if_open 
  911.  *      because if_open does not have access to the remote IP address.
  912.  *      
  913.  * If the communications are not enabled, proceed to configure
  914.  *      the card and enable communications.
  915.  *
  916.  *      If the communications are enabled, it means that the interface
  917.  *      was shutdown by ether the user or driver. In this case, we 
  918.  *      have to check that the IP addresses have not changed.  If
  919.  *      the IP addresses have changed, we have to reconfigure the firmware
  920.  *      and update the changed IP addresses.  Otherwise, just exit.
  921.  *
  922.  */
  923. static int config_chdlc (sdla_t *card)
  924. {
  925. netdevice_t *dev = card->wandev.dev;
  926. chdlc_private_area_t *chdlc_priv_area = dev->priv;
  927. SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
  928. if (card->u.c.comm_enabled){
  929. /* Jun 20. 2000: NC
  930.  * IP addresses are not used in the API mode */
  931. if ((chdlc_priv_area->ip_local_tmp != chdlc_priv_area->ip_local ||
  932.      chdlc_priv_area->ip_remote_tmp != chdlc_priv_area->ip_remote) && 
  933.      card->u.c.usedby == WANPIPE) {
  934. /* The IP addersses have changed, we must
  935.                          * stop the communications and reconfigure
  936.                          * the card. Reason: the firmware must know
  937.                          * the local and remote IP addresses. */
  938. disable_comm(card);
  939. port_set_state(card, WAN_DISCONNECTED);
  940. printk(KERN_INFO 
  941. "%s: IP addresses changed!n",
  942. card->devname);
  943. printk(KERN_INFO 
  944. "%s: Restarting communications ...n",
  945. card->devname);
  946. }else{ 
  947. /* IP addresses are the same and the link is up, 
  948.                          * we dont have to do anything here. Therefore, exit */
  949. return 0;
  950. }
  951. }
  952. chdlc_priv_area->ip_local = chdlc_priv_area->ip_local_tmp;
  953. chdlc_priv_area->ip_remote = chdlc_priv_area->ip_remote_tmp;
  954. /* Setup the Board for asynchronous mode */
  955. if (card->u.c.async_mode){
  956. if (set_asy_config(card)) {
  957. printk (KERN_INFO "%s: Failed CHDLC Async configuration!n",
  958. card->devname);
  959. return 0;
  960. }
  961. }else{
  962. /* Setup the Board for CHDLC */
  963. if (set_chdlc_config(card)) {
  964. printk (KERN_INFO "%s: Failed CHDLC configuration!n",
  965. card->devname);
  966. return 0;
  967. }
  968. }
  969. /* Set interrupt mode and mask */
  970.         if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME |
  971.                  APP_INT_ON_GLOBAL_EXCEP_COND |
  972.                  APP_INT_ON_TX_FRAME |
  973.                  APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){
  974. printk (KERN_INFO "%s: Failed to set interrupt triggers!n",
  975. card->devname);
  976. return 0;
  977.         }
  978. /* Mask the Transmit and Timer interrupt */
  979. flags->interrupt_info_struct.interrupt_permission &= 
  980. ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
  981. /* In TTY mode, receive interrupt will be enabled during
  982.  * wanpipe_tty_open() operation */
  983. if (card->tty_opt){
  984. flags->interrupt_info_struct.interrupt_permission &= ~APP_INT_ON_RX_FRAME;
  985. }
  986. /* Enable communications */
  987.   if (card->u.c.async_mode){
  988. if (asy_comm_enable(card) != 0) {
  989. printk(KERN_INFO "%s: Failed to enable async commnunication!n",
  990. card->devname);
  991. flags->interrupt_info_struct.interrupt_permission = 0;
  992. card->u.c.comm_enabled=0;
  993. chdlc_set_intr_mode(card,0);
  994. return 0;
  995. }
  996.         }else{ 
  997. if (chdlc_comm_enable(card) != 0) {
  998. printk(KERN_INFO "%s: Failed to enable chdlc communications!n",
  999. card->devname);
  1000. flags->interrupt_info_struct.interrupt_permission = 0;
  1001. card->u.c.comm_enabled=0;
  1002. chdlc_set_intr_mode(card,0);
  1003. return 0;
  1004. }
  1005. }
  1006. /* Initialize Rx/Tx buffer control fields */
  1007. init_chdlc_tx_rx_buff(card);
  1008. port_set_state(card, WAN_CONNECTING);
  1009. return 0; 
  1010. }
  1011. /*============================================================
  1012.  * chdlc_poll
  1013.  *
  1014.  * Rationale:
  1015.  *  We cannot manipulate the routing tables, or
  1016.  *      ip addresses withing the interrupt. Therefore
  1017.  *      we must perform such actons outside an interrupt 
  1018.  *      at a later time. 
  1019.  *
  1020.  * Description:
  1021.  * CHDLC polling routine, responsible for 
  1022.  *      shutting down interfaces upon disconnect
  1023.  *      and adding/removing routes. 
  1024.  *      
  1025.  * Usage:        
  1026.  *  This function is executed for each CHDLC  
  1027.  *  interface through a tq_schedule bottom half.
  1028.  *      
  1029.  *      trigger_chdlc_poll() function is used to kick
  1030.  *      the chldc_poll routine.  
  1031.  */
  1032. static void chdlc_poll (netdevice_t *dev)
  1033. {
  1034. chdlc_private_area_t *chdlc_priv_area;
  1035. sdla_t *card;
  1036. u8 check_gateway=0;
  1037. SHARED_MEMORY_INFO_STRUCT* flags;
  1038. if (!dev || (chdlc_priv_area=dev->priv) == NULL)
  1039. return;
  1040. card = chdlc_priv_area->card;
  1041. flags = card->u.c.flags;
  1042. /* (Re)Configuraiton is in progress, stop what you are 
  1043.  * doing and get out */
  1044. if (test_bit(PERI_CRIT,&card->wandev.critical)){
  1045. clear_bit(POLL_CRIT,&card->wandev.critical);
  1046. return;
  1047. }
  1048. /* if_open() function has triggered the polling routine
  1049.  * to determine the configured IP addresses.  Once the
  1050.  * addresses are found, trigger the chdlc configuration */
  1051. if (test_bit(0,&chdlc_priv_area->config_chdlc)){
  1052. chdlc_priv_area->ip_local_tmp  = get_ip_address(dev,WAN_LOCAL_IP);
  1053. chdlc_priv_area->ip_remote_tmp = get_ip_address(dev,WAN_POINTOPOINT_IP);
  1054.        /* Jun 20. 2000 Bug Fix
  1055.   * Only perform this check in WANPIPE mode, since
  1056.   * IP addresses are not used in the API mode. */
  1057. if (chdlc_priv_area->ip_local_tmp == chdlc_priv_area->ip_remote_tmp && 
  1058.     card->u.c.slarp_timer == 0x00 && 
  1059.     !card->u.c.backup && 
  1060.     card->u.c.usedby == WANPIPE){
  1061. if (++chdlc_priv_area->ip_error > MAX_IP_ERRORS){
  1062. printk(KERN_INFO "n%s: --- WARNING ---n",
  1063. card->devname);
  1064. printk(KERN_INFO 
  1065. "%s: The local IP address is the same as then",
  1066. card->devname);
  1067. printk(KERN_INFO 
  1068. "%s: Point-to-Point IP address.n",
  1069. card->devname);
  1070. printk(KERN_INFO "%s: --- WARNING ---nn",
  1071. card->devname);
  1072. }else{
  1073. clear_bit(POLL_CRIT,&card->wandev.critical);
  1074. chdlc_priv_area->poll_delay_timer.expires = jiffies+HZ;
  1075. add_timer(&chdlc_priv_area->poll_delay_timer);
  1076. return;
  1077. }
  1078. }
  1079. clear_bit(0,&chdlc_priv_area->config_chdlc);
  1080. clear_bit(POLL_CRIT,&card->wandev.critical);
  1081. chdlc_priv_area->timer_int_enabled |= TMR_INT_ENABLED_CONFIG;
  1082. flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
  1083. return;
  1084. }
  1085. /* Dynamic interface implementation, as well as dynamic
  1086.  * routing.  */
  1087. switch (card->u.c.state){
  1088. case WAN_DISCONNECTED:
  1089. /* If the dynamic interface configuration is on, and interface 
  1090.  * is up, then bring down the netowrk interface */
  1091. if (test_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down) && 
  1092.     !test_bit(DEV_DOWN,  &chdlc_priv_area->interface_down) &&
  1093.     card->wandev.dev->flags & IFF_UP){
  1094. printk(KERN_INFO "%s: Interface %s down.n",
  1095. card->devname,card->wandev.dev->name);
  1096. change_dev_flags(card->wandev.dev,(card->wandev.dev->flags&~IFF_UP));
  1097. set_bit(DEV_DOWN,&chdlc_priv_area->interface_down);
  1098. chdlc_priv_area->route_status = NO_ROUTE;
  1099. }else{
  1100. /* We need to check if the local IP address is
  1101.                     * zero. If it is, we shouldn't try to remove it.
  1102.                    */
  1103. if (card->wandev.dev->flags & IFF_UP && 
  1104.          get_ip_address(card->wandev.dev,WAN_LOCAL_IP) && 
  1105.          chdlc_priv_area->route_status != NO_ROUTE &&
  1106.     card->u.c.slarp_timer){
  1107. process_route(card);
  1108. }
  1109. }
  1110. break;
  1111. case WAN_CONNECTED:
  1112. /* In SMP machine this code can execute before the interface
  1113.  * comes up.  In this case, we must make sure that we do not
  1114.  * try to bring up the interface before dev_open() is finished */
  1115. /* DEV_DOWN will be set only when we bring down the interface
  1116.  * for the very first time. This way we know that it was us
  1117.  * that brought the interface down */
  1118. if (test_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down) &&
  1119.     test_bit(DEV_DOWN,  &chdlc_priv_area->interface_down) &&
  1120.     !(card->wandev.dev->flags & IFF_UP)){
  1121. printk(KERN_INFO "%s: Interface %s up.n",
  1122. card->devname,card->wandev.dev->name);
  1123. change_dev_flags(card->wandev.dev,(card->wandev.dev->flags|IFF_UP));
  1124. clear_bit(DEV_DOWN,&chdlc_priv_area->interface_down);
  1125. check_gateway=1;
  1126. }
  1127. if (chdlc_priv_area->route_status == ADD_ROUTE && 
  1128.     card->u.c.slarp_timer){ 
  1129. process_route(card);
  1130. check_gateway=1;
  1131. }
  1132. if (chdlc_priv_area->gateway && check_gateway)
  1133. add_gateway(card,dev);
  1134. break;
  1135. }
  1136. clear_bit(POLL_CRIT,&card->wandev.critical);
  1137. }
  1138. /*============================================================
  1139.  * trigger_chdlc_poll
  1140.  *
  1141.  * Description:
  1142.  *  Add a chdlc_poll() task into a tq_scheduler bh handler
  1143.  *      for a specific dlci/interface.  This will kick
  1144.  *      the fr_poll() routine at a later time. 
  1145.  *
  1146.  * Usage:
  1147.  *  Interrupts use this to defer a taks to 
  1148.  *      a polling routine.
  1149.  *
  1150.  */
  1151. static void trigger_chdlc_poll (netdevice_t *dev)
  1152. {
  1153. chdlc_private_area_t *chdlc_priv_area;
  1154. sdla_t *card;
  1155. if (!dev)
  1156. return;
  1157. if ((chdlc_priv_area = dev->priv)==NULL)
  1158. return;
  1159. card = chdlc_priv_area->card;
  1160. if (test_and_set_bit(POLL_CRIT,&card->wandev.critical)){
  1161. return;
  1162. }
  1163. if (test_bit(PERI_CRIT,&card->wandev.critical)){
  1164. return; 
  1165. }
  1166. #ifdef LINUX_2_4
  1167. schedule_task(&chdlc_priv_area->poll_task);
  1168. #else
  1169. queue_task(&chdlc_priv_area->poll_task, &tq_scheduler);
  1170. #endif
  1171. return;
  1172. }
  1173. static void chdlc_poll_delay (unsigned long dev_ptr)
  1174. {
  1175. netdevice_t *dev = (netdevice_t *)dev_ptr;
  1176. trigger_chdlc_poll(dev);
  1177. }
  1178. void s508_lock (sdla_t *card, unsigned long *smp_flags)
  1179. {
  1180. #if defined(__SMP__) || defined(LINUX_2_4)
  1181. spin_lock_irqsave(&card->wandev.lock, *smp_flags);
  1182.         if (card->next){
  1183.          spin_lock(&card->next->wandev.lock);
  1184. }
  1185. #else
  1186.         disable_irq(card->hw.irq);
  1187. #endif                                                                     
  1188. }
  1189. void s508_unlock (sdla_t *card, unsigned long *smp_flags)
  1190. {
  1191. #if defined(__SMP__) || defined(LINUX_2_4)
  1192.         if (card->next){
  1193.          spin_unlock(&card->next->wandev.lock);
  1194.         }
  1195.         spin_unlock_irqrestore(&card->wandev.lock, *smp_flags);
  1196. #else
  1197.         enable_irq(card->hw.irq);
  1198. #endif           
  1199. }
  1200. //*********** TTY SECTION ****************
  1201. #if defined(LINUX_2_4) || defined(LINUX_2_1)
  1202. static void wanpipe_tty_trigger_tx_irq(sdla_t *card)
  1203. {
  1204. SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
  1205. INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct;
  1206. chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME;
  1207. }
  1208. static void wanpipe_tty_trigger_poll(sdla_t *card)
  1209. {
  1210. #ifdef LINUX_2_4
  1211. schedule_task(&card->tty_task_queue);
  1212. #else
  1213. queue_task(&card->tty_task_queue, &tq_scheduler);
  1214. #endif
  1215. }
  1216. static void tty_poll_task (void* data)
  1217. {
  1218. sdla_t *card = (sdla_t*)data;
  1219. struct tty_struct *tty;
  1220. if ((tty=card->tty)==NULL)
  1221. return;
  1222. if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  1223.     tty->ldisc.write_wakeup){
  1224. (tty->ldisc.write_wakeup)(tty);
  1225. }
  1226. wake_up_interruptible(&tty->write_wait);
  1227. #if defined(SERIAL_HAVE_POLL_WAIT) || 
  1228.          (defined LINUX_2_1 && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15))
  1229. wake_up_interruptible(&tty->poll_wait);
  1230. #endif
  1231. return;
  1232. }
  1233. static void wanpipe_tty_close(struct tty_struct *tty, struct file * filp)
  1234. {
  1235. sdla_t *card;
  1236. unsigned long smp_flags;
  1237. if (!tty || !tty->driver_data){
  1238. return;
  1239. }
  1240. card = (sdla_t*)tty->driver_data;
  1241. if (!card)
  1242. return;
  1243. printk(KERN_INFO "%s: Closing TTY Driver!n",
  1244. card->devname);
  1245. /* Sanity Check */
  1246. if (!card->tty_open)
  1247. return;
  1248. wanpipe_close(card);
  1249. if (--card->tty_open == 0){
  1250. lock_adapter_irq(&card->wandev.lock,&smp_flags);
  1251. card->tty=NULL;
  1252. chdlc_disable_comm_shutdown(card);
  1253. unlock_adapter_irq(&card->wandev.lock,&smp_flags);
  1254. if (card->tty_buf){
  1255. kfree(card->tty_buf);
  1256. card->tty_buf=NULL;
  1257. }
  1258. if (card->tty_rx){
  1259. kfree(card->tty_rx);
  1260. card->tty_rx=NULL;
  1261. }
  1262. }
  1263. return;
  1264. }
  1265. static int wanpipe_tty_open(struct tty_struct *tty, struct file * filp)
  1266. {
  1267. unsigned long smp_flags;
  1268. sdla_t *card;
  1269. if (!tty){
  1270. return -ENODEV;
  1271. }
  1272. if (!tty->driver_data){
  1273. int port;
  1274. port = MINOR(tty->device) - tty->driver.minor_start;
  1275. if ((port < 0) || (port >= NR_PORTS)) 
  1276. return -ENODEV;
  1277. tty->driver_data = WAN_CARD(port);
  1278. if (!tty->driver_data)
  1279. return -ENODEV;
  1280. }
  1281. card = (sdla_t*)tty->driver_data;
  1282. if (!card){
  1283. lock_adapter_irq(&card->wandev.lock,&smp_flags);
  1284. card->tty=NULL;
  1285. unlock_adapter_irq(&card->wandev.lock,&smp_flags);
  1286. return -ENODEV;
  1287. }
  1288. printk(KERN_INFO "%s: Opening TTY Driver!n",
  1289. card->devname);
  1290. if (card->tty_open == 0){
  1291. lock_adapter_irq(&card->wandev.lock,&smp_flags);
  1292. card->tty=tty;
  1293. unlock_adapter_irq(&card->wandev.lock,&smp_flags);
  1294. if (!card->tty_buf){
  1295. card->tty_buf = kmalloc(TTY_CHDLC_MAX_MTU, GFP_KERNEL);
  1296. if (!card->tty_buf){
  1297. card->tty_buf=NULL;
  1298. card->tty=NULL;
  1299. return -ENOMEM;
  1300. }
  1301. }
  1302. if (!card->tty_rx){
  1303. card->tty_rx = kmalloc(TTY_CHDLC_MAX_MTU, GFP_KERNEL);
  1304. if (!card->tty_rx){
  1305. /* Free the buffer above */
  1306. kfree(card->tty_buf);
  1307. card->tty_buf=NULL;
  1308. card->tty=NULL;
  1309. return -ENOMEM;
  1310. }
  1311. }
  1312. }
  1313. ++card->tty_open;
  1314. wanpipe_open(card);
  1315. return 0;
  1316. }
  1317. static int wanpipe_tty_write(struct tty_struct * tty, int from_user,
  1318.     const unsigned char *buf, int count)
  1319. {
  1320. unsigned long smp_flags=0;
  1321. sdla_t *card=NULL;
  1322. if (!tty){
  1323. dbg_printk(KERN_INFO "NO TTY in Writen");
  1324. return -ENODEV;
  1325. }
  1326. card = (sdla_t *)tty->driver_data;
  1327. if (!card){
  1328. dbg_printk(KERN_INFO "No Card in TTY Writen");
  1329. return -ENODEV;
  1330. }
  1331. if (count > card->wandev.mtu){
  1332. dbg_printk(KERN_INFO "Frame too big in Write %i Max: %in",
  1333. count,card->wandev.mtu);
  1334. return -EINVAL;
  1335. }
  1336. if (card->wandev.state != WAN_CONNECTED){
  1337. dbg_printk(KERN_INFO "Card not connected in TTY Writen");
  1338. return -EINVAL;
  1339. }
  1340. /* Lock the 508 Card: SMP is supported */
  1341.        if(card->hw.type != SDLA_S514){
  1342. s508_lock(card,&smp_flags);
  1343. if (test_and_set_bit(SEND_CRIT,(void*)&card->wandev.critical)){
  1344. printk(KERN_INFO "%s: Critical in TTY Writen",
  1345. card->devname);
  1346. /* Lock the 508 Card: SMP is supported */
  1347. if(card->hw.type != SDLA_S514)
  1348. s508_unlock(card,&smp_flags);
  1349. return -EINVAL; 
  1350. }
  1351. if (from_user) {
  1352. unsigned char *tmp_buf;
  1353. if ((tmp_buf=card->tty_buf)==NULL){
  1354. dbg_printk(KERN_INFO "No TTY BUF in Writen");
  1355. clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
  1356. if(card->hw.type != SDLA_S514)
  1357. s508_unlock(card,&smp_flags);
  1358. return -ENOMEM;
  1359. }
  1360. if (copy_from_user(tmp_buf,buf,count)){
  1361. dbg_printk(KERN_INFO "%s: Failed to copy from user!n",
  1362. card->devname);
  1363. clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
  1364. if(card->hw.type != SDLA_S514)
  1365. s508_unlock(card,&smp_flags);
  1366. return -EINVAL;
  1367. }
  1368. if (chdlc_send(card,(void*)tmp_buf,count)){
  1369. dbg_printk(KERN_INFO "%s: Failed to send, retry later: user!n",
  1370. card->devname);
  1371. clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
  1372. wanpipe_tty_trigger_tx_irq(card);
  1373. if(card->hw.type != SDLA_S514)
  1374. s508_unlock(card,&smp_flags);
  1375. return 0;
  1376. }
  1377. }else{
  1378.   if (chdlc_send(card,(void*)buf,count)){
  1379. dbg_printk(KERN_INFO "%s: Failed to send, retry later: kernel!n",
  1380. card->devname);
  1381. clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
  1382. wanpipe_tty_trigger_tx_irq(card);
  1383. if(card->hw.type != SDLA_S514)
  1384. s508_unlock(card,&smp_flags);
  1385. return 0;
  1386. }
  1387. }
  1388. dbg_printk(KERN_INFO "%s: Packet sent OK: %in",card->devname,count);
  1389. clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
  1390. if(card->hw.type != SDLA_S514)
  1391. s508_unlock(card,&smp_flags);
  1392. return count;
  1393. }
  1394. static void wanpipe_tty_receive(sdla_t *card, unsigned addr, unsigned int len)
  1395. {
  1396. unsigned offset=0;
  1397. unsigned olen=len;
  1398. char fp=0;
  1399. struct tty_struct *tty;
  1400. int i;
  1401. if (!card->tty_open){
  1402. dbg_printk(KERN_INFO "%s: TTY not open during receiven",
  1403. card->devname);
  1404. return;
  1405. }
  1406. if ((tty=card->tty) == NULL){
  1407. dbg_printk(KERN_INFO "%s: No TTY on receiven",
  1408. card->devname);
  1409. return;
  1410. }
  1411. if (!tty->driver_data){
  1412. dbg_printk(KERN_INFO "%s: No Driver Data, or Flip on receiven",
  1413. card->devname);
  1414. return;
  1415. }
  1416. if (card->u.c.async_mode){
  1417. if ((tty->flip.count+len) >= TTY_FLIPBUF_SIZE){
  1418. if (net_ratelimit()){
  1419. printk(KERN_INFO 
  1420. "%s: Received packet size too big: %i bytes, Max: %i!n",
  1421. card->devname,len,TTY_FLIPBUF_SIZE);
  1422. }
  1423. return;
  1424. }
  1425. if((addr + len) > card->u.c.rx_top + 1) {
  1426. offset = card->u.c.rx_top - addr + 1;
  1427. sdla_peek(&card->hw, addr, tty->flip.char_buf_ptr, offset);
  1428. addr = card->u.c.rx_base;
  1429. len -= offset;
  1430. tty->flip.char_buf_ptr+=offset;
  1431. tty->flip.count+=offset;
  1432. for (i=0;i<offset;i++){
  1433. *tty->flip.flag_buf_ptr = 0;
  1434. tty->flip.flag_buf_ptr++;
  1435. }
  1436. }
  1437. sdla_peek(&card->hw, addr, tty->flip.char_buf_ptr, len);
  1438. tty->flip.char_buf_ptr+=len;
  1439. card->tty->flip.count+=len;
  1440. for (i=0;i<len;i++){
  1441. *tty->flip.flag_buf_ptr = 0;
  1442. tty->flip.flag_buf_ptr++;
  1443. }
  1444. tty->low_latency=1;
  1445. tty_flip_buffer_push(tty);
  1446. }else{
  1447. if (!card->tty_rx){
  1448. if (net_ratelimit()){
  1449. printk(KERN_INFO 
  1450. "%s: Receive sync buffer not available!n",
  1451.  card->devname);
  1452. }
  1453. return;
  1454. }
  1455. if (len > TTY_CHDLC_MAX_MTU){
  1456. if (net_ratelimit()){
  1457. printk(KERN_INFO 
  1458. "%s: Received packet size too big: %i bytes, Max: %i!n",
  1459. card->devname,len,TTY_FLIPBUF_SIZE);
  1460. }
  1461. return;
  1462. }
  1463. if((addr + len) > card->u.c.rx_top + 1) {
  1464. offset = card->u.c.rx_top - addr + 1;
  1465. sdla_peek(&card->hw, addr, card->tty_rx, offset);
  1466. addr = card->u.c.rx_base;
  1467. len -= offset;
  1468. }
  1469. sdla_peek(&card->hw, addr, card->tty_rx+offset, len);
  1470. if (tty->ldisc.receive_buf){
  1471. tty->ldisc.receive_buf(tty,card->tty_rx,&fp,olen);
  1472. }else{
  1473. if (net_ratelimit()){
  1474. printk(KERN_INFO 
  1475. "%s: NO TTY Sync line discipline!n",
  1476. card->devname);
  1477. }
  1478. }
  1479. }
  1480. dbg_printk(KERN_INFO "%s: Received Data %in",card->devname,olen);
  1481. return;
  1482. }
  1483. #if 0
  1484. static int wanpipe_tty_ioctl(struct tty_struct *tty, struct file * file,
  1485.     unsigned int cmd, unsigned long arg)
  1486. {
  1487. return -ENOIOCTLCMD;
  1488. }
  1489. #endif
  1490. static void wanpipe_tty_stop(struct tty_struct *tty)
  1491. {
  1492. return;
  1493. }
  1494. static void wanpipe_tty_start(struct tty_struct *tty)
  1495. {
  1496. return;
  1497. }
  1498. static int config_tty (sdla_t *card)
  1499. {
  1500. SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
  1501. /* Setup the Board for asynchronous mode */
  1502. if (card->u.c.async_mode){
  1503. if (set_asy_config(card)) {
  1504. printk (KERN_INFO "%s: Failed CHDLC Async configuration!n",
  1505. card->devname);
  1506. return -EINVAL;
  1507. }
  1508. }else{
  1509. /* Setup the Board for CHDLC */
  1510. if (set_chdlc_config(card)) {
  1511. printk (KERN_INFO "%s: Failed CHDLC configuration!n",
  1512. card->devname);
  1513. return -EINVAL;
  1514. }
  1515. }
  1516. /* Set interrupt mode and mask */
  1517.         if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME |
  1518.                  APP_INT_ON_GLOBAL_EXCEP_COND |
  1519.                  APP_INT_ON_TX_FRAME |
  1520.                  APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){
  1521. printk (KERN_INFO "%s: Failed to set interrupt triggers!n",
  1522. card->devname);
  1523. return -EINVAL;
  1524.         }
  1525. /* Mask the Transmit and Timer interrupt */
  1526. flags->interrupt_info_struct.interrupt_permission &= 
  1527. ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
  1528. /* Enable communications */
  1529.   if (card->u.c.async_mode){
  1530. if (asy_comm_enable(card) != 0) {
  1531. printk(KERN_INFO "%s: Failed to enable async commnunication!n",
  1532. card->devname);
  1533. flags->interrupt_info_struct.interrupt_permission = 0;
  1534. card->u.c.comm_enabled=0;
  1535. chdlc_set_intr_mode(card,0);
  1536. return -EINVAL;
  1537. }
  1538.         }else{ 
  1539. if (chdlc_comm_enable(card) != 0) {
  1540. printk(KERN_INFO "%s: Failed to enable chdlc communications!n",
  1541. card->devname);
  1542. flags->interrupt_info_struct.interrupt_permission = 0;
  1543. card->u.c.comm_enabled=0;
  1544. chdlc_set_intr_mode(card,0);
  1545. return -EINVAL;
  1546. }
  1547. }
  1548. /* Initialize Rx/Tx buffer control fields */
  1549. init_chdlc_tx_rx_buff(card);
  1550. port_set_state(card, WAN_CONNECTING);
  1551. return 0; 
  1552. }
  1553. static int change_speed(sdla_t *card, struct tty_struct *tty,
  1554.  struct termios *old_termios)
  1555. {
  1556. int baud, ret=0;
  1557. unsigned cflag; 
  1558. int dbits,sbits,parity,handshaking;
  1559. cflag = tty->termios->c_cflag;
  1560. /* There is always one stop bit */
  1561. sbits=WANOPT_ONE;
  1562. /* Parity is defaulted to NONE */
  1563. parity = WANOPT_NONE;
  1564. handshaking=0;
  1565. /* byte size and parity */
  1566. switch (cflag & CSIZE) {
  1567.       case CS5: dbits = 5; break;
  1568.       case CS6: dbits = 6; break;
  1569.       case CS7: dbits = 7; break;
  1570.       case CS8: dbits = 8; break;
  1571.       /* Never happens, but GCC is too dumb to figure it out */
  1572.       default:  dbits = 8; break;
  1573. }
  1574. /* One more stop bit should be supported, thus increment
  1575.  * the number of stop bits Max=2 */
  1576. if (cflag & CSTOPB) {
  1577. sbits = WANOPT_TWO;
  1578. }
  1579. if (cflag & PARENB) {
  1580. parity = WANOPT_EVEN;
  1581. }
  1582. if (cflag & PARODD){
  1583. parity = WANOPT_ODD;
  1584. }
  1585. /* Determine divisor based on baud rate */
  1586. baud = tty_get_baud_rate(tty);
  1587. if (!baud)
  1588. baud = 9600; /* B0 transition handled in rs_set_termios */
  1589. if (cflag & CRTSCTS) {
  1590. handshaking|=ASY_RTS_HS_FOR_RX;
  1591. }
  1592. if (I_IGNPAR(tty))
  1593. parity = WANOPT_NONE;
  1594. if (I_IXOFF(tty)){
  1595. handshaking|=ASY_XON_XOFF_HS_FOR_RX;
  1596. handshaking|=ASY_XON_XOFF_HS_FOR_TX;
  1597. }
  1598. if (I_IXON(tty)){
  1599. handshaking|=ASY_XON_XOFF_HS_FOR_RX;
  1600. handshaking|=ASY_XON_XOFF_HS_FOR_TX;
  1601. }
  1602. if (card->u.c.async_mode){
  1603. if (card->wandev.bps != baud)
  1604. ret=1;
  1605. card->wandev.bps = baud;
  1606. }
  1607. if (card->u.c.async_mode){
  1608. if (card->u.c.protocol_options != handshaking)
  1609. ret=1;
  1610. card->u.c.protocol_options = handshaking;
  1611. if (card->u.c.tx_bits_per_char != dbits)
  1612. ret=1;
  1613. card->u.c.tx_bits_per_char = dbits;
  1614. if (card->u.c.rx_bits_per_char != dbits)
  1615. ret=1;
  1616. card->u.c.rx_bits_per_char = dbits;
  1617. if (card->u.c.stop_bits != sbits)
  1618. ret=1;
  1619. card->u.c.stop_bits = sbits;
  1620. if (card->u.c.parity != parity)
  1621. ret=1;
  1622. card->u.c.parity = parity;
  1623. card->u.c.break_timer = 50;
  1624. card->u.c.inter_char_timer = 10;
  1625. card->u.c.rx_complete_length = 100;
  1626. card->u.c.xon_char = 0xFE;
  1627. }else{
  1628. card->u.c.protocol_options = HDLC_STREAMING_MODE;
  1629. }
  1630. return ret;
  1631. }
  1632. static void wanpipe_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
  1633. {
  1634. sdla_t *card;
  1635. int err=1;
  1636. if (!tty){
  1637. return;
  1638. }
  1639. card = (sdla_t *)tty->driver_data;
  1640. if (!card)
  1641. return;
  1642. if (change_speed(card, tty, old_termios) || !card->u.c.comm_enabled){
  1643. unsigned long smp_flags;
  1644. if (card->u.c.comm_enabled){
  1645. lock_adapter_irq(&card->wandev.lock,&smp_flags);
  1646. chdlc_disable_comm_shutdown(card);
  1647. unlock_adapter_irq(&card->wandev.lock,&smp_flags);
  1648. }
  1649. lock_adapter_irq(&card->wandev.lock,&smp_flags);
  1650. err = config_tty(card);
  1651. unlock_adapter_irq(&card->wandev.lock,&smp_flags);
  1652. if (card->u.c.async_mode){
  1653. printk(KERN_INFO "%s: TTY Async Configuration:n"
  1654.  "   Baud        =%in"
  1655.  "   Handshaking =%sn"
  1656.  "   Tx Dbits    =%in"
  1657.  "   Rx Dbits    =%in"
  1658.  "   Parity      =%sn"
  1659.  "   Stop Bits   =%in",
  1660.  card->devname,
  1661.  card->wandev.bps,
  1662.  opt_decode[card->u.c.protocol_options],
  1663.  card->u.c.tx_bits_per_char,
  1664.  card->u.c.rx_bits_per_char,
  1665.  p_decode[card->u.c.parity] ,
  1666.  card->u.c.stop_bits);
  1667. }else{
  1668. printk(KERN_INFO "%s: TTY Sync Configuration:n"
  1669.  "   Baud        =%in"
  1670.  "   Protocol    =HDLC_STREAMINGn",
  1671.  card->devname,card->wandev.bps);
  1672. }
  1673. if (!err){
  1674. port_set_state(card,WAN_CONNECTED);
  1675. }else{
  1676. port_set_state(card,WAN_DISCONNECTED);
  1677. }
  1678. }
  1679. return;
  1680. }
  1681. static void wanpipe_tty_put_char(struct tty_struct *tty, unsigned char ch)
  1682. {
  1683. sdla_t *card;
  1684. unsigned long smp_flags=0;
  1685. if (!tty){
  1686. return;
  1687. }
  1688. card = (sdla_t *)tty->driver_data;
  1689. if (!card)
  1690. return;
  1691. if (card->wandev.state != WAN_CONNECTED)
  1692. return;
  1693. if(card->hw.type != SDLA_S514)
  1694. s508_lock(card,&smp_flags);
  1695. if (test_and_set_bit(SEND_CRIT,(void*)&card->wandev.critical)){
  1696. wanpipe_tty_trigger_tx_irq(card);
  1697. if(card->hw.type != SDLA_S514)
  1698. s508_unlock(card,&smp_flags);
  1699. return;
  1700. }
  1701. if (chdlc_send(card,(void*)&ch,1)){
  1702. wanpipe_tty_trigger_tx_irq(card);
  1703. dbg_printk("%s: Failed to TX char!n",card->devname);
  1704. }
  1705. dbg_printk("%s: Char TX OKn",card->devname);
  1706. clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
  1707. if(card->hw.type != SDLA_S514)
  1708. s508_unlock(card,&smp_flags);
  1709. return;
  1710. }
  1711. static void wanpipe_tty_flush_chars(struct tty_struct *tty)
  1712. {
  1713. return;
  1714. }
  1715. static void wanpipe_tty_flush_buffer(struct tty_struct *tty)
  1716. {
  1717. if (!tty)
  1718. return;
  1719. wake_up_interruptible(&tty->write_wait);
  1720. #if defined(SERIAL_HAVE_POLL_WAIT) || 
  1721.          (defined LINUX_2_1 && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15))
  1722. wake_up_interruptible(&tty->poll_wait);
  1723. #endif
  1724. if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  1725.     tty->ldisc.write_wakeup)
  1726. (tty->ldisc.write_wakeup)(tty);
  1727. return;
  1728. }
  1729. /*
  1730.  * This function is used to send a high-priority XON/XOFF character to
  1731.  * the device
  1732.  */
  1733. static void wanpipe_tty_send_xchar(struct tty_struct *tty, char ch)
  1734. {
  1735. return;
  1736. }
  1737. static int wanpipe_tty_chars_in_buffer(struct tty_struct *tty)
  1738. {
  1739. return 0;
  1740. }
  1741. static int wanpipe_tty_write_room(struct tty_struct *tty)
  1742. {
  1743. sdla_t *card;
  1744. printk(KERN_INFO "TTY Write Roomn");
  1745. if (!tty){
  1746. return 0;
  1747. }
  1748. card = (sdla_t *)tty->driver_data;
  1749. if (!card)
  1750. return 0;
  1751. if (card->wandev.state != WAN_CONNECTED)
  1752. return 0;
  1753. return SEC_MAX_NO_DATA_BYTES_IN_FRAME;
  1754. }
  1755. static int set_modem_status(sdla_t *card, unsigned char data)
  1756. {
  1757. CHDLC_MAILBOX_STRUCT *mb = card->mbox;
  1758. int err;
  1759. mb->buffer_length=1;
  1760. mb->command=SET_MODEM_STATUS;
  1761. mb->data[0]=data;
  1762. err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
  1763. if (err != COMMAND_OK) 
  1764. chdlc_error (card, err, mb);
  1765. return err;
  1766. }
  1767. static void wanpipe_tty_hangup(struct tty_struct *tty)
  1768. {
  1769. sdla_t *card;
  1770. unsigned long smp_flags;
  1771. printk(KERN_INFO "TTY Hangup!n");
  1772. if (!tty){
  1773. return;
  1774. }
  1775. card = (sdla_t *)tty->driver_data;
  1776. if (!card)
  1777. return;
  1778. lock_adapter_irq(&card->wandev.lock,&smp_flags);
  1779. set_modem_status(card,0);
  1780. unlock_adapter_irq(&card->wandev.lock,&smp_flags);
  1781. return;
  1782. }
  1783. static void wanpipe_tty_break(struct tty_struct *tty, int break_state)
  1784. {
  1785. return;
  1786. }
  1787. static void wanpipe_tty_wait_until_sent(struct tty_struct *tty, int timeout)
  1788. {
  1789. return;
  1790. }
  1791. static void wanpipe_tty_throttle(struct tty_struct * tty)
  1792. {
  1793. return;
  1794. }
  1795. static void wanpipe_tty_unthrottle(struct tty_struct * tty)
  1796. {
  1797. return;
  1798. }
  1799. int wanpipe_tty_read_proc(char *page, char **start, off_t off, int count,
  1800.  int *eof, void *data)
  1801. {
  1802. return 0;
  1803. }
  1804. /*
  1805.  * The serial driver boot-time initialization code!
  1806.  */
  1807. int wanpipe_tty_init(sdla_t *card)
  1808. {
  1809. struct serial_state * state;
  1810. /* Initialize the tty_driver structure */
  1811. if (card->tty_minor < 0 || card->tty_minor > NR_PORTS){
  1812. printk(KERN_INFO "%s: Illegal Minor TTY number (0-4): %in",
  1813. card->devname,card->tty_minor);
  1814. return -EINVAL;
  1815. }
  1816. if (WAN_CARD(card->tty_minor)){
  1817. printk(KERN_INFO "%s: TTY Minor %i, already in usen",
  1818. card->devname,card->tty_minor);
  1819. return -EBUSY;
  1820. }
  1821. if (tty_init_cnt==0){
  1822. printk(KERN_INFO "%s: TTY %s Driver Init: Major %i, Minor Range %i-%in",
  1823. card->devname,
  1824. card->u.c.async_mode ? "ASYNC" : "SYNC",
  1825. WAN_TTY_MAJOR,MIN_PORT,MAX_PORT);
  1826. tty_driver_mode = card->u.c.async_mode;
  1827. memset(&serial_driver, 0, sizeof(struct tty_driver));
  1828. serial_driver.magic = TTY_DRIVER_MAGIC;
  1829. serial_driver.driver_name = "wanpipe_tty"; 
  1830. serial_driver.name = "ttyW";
  1831. serial_driver.major = WAN_TTY_MAJOR;
  1832. serial_driver.minor_start = WAN_TTY_MINOR;
  1833. serial_driver.num = NR_PORTS; 
  1834. serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
  1835. serial_driver.subtype = SERIAL_TYPE_NORMAL;
  1836. serial_driver.init_termios = tty_std_termios;
  1837. serial_driver.init_termios.c_cflag =
  1838. B9600 | CS8 | CREAD | HUPCL | CLOCAL;
  1839. serial_driver.flags = TTY_DRIVER_REAL_RAW;
  1840. serial_driver.refcount = &serial_refcount;
  1841. serial_driver.table = serial_table;
  1842. serial_driver.termios = serial_termios;
  1843. serial_driver.termios_locked = serial_termios_locked;
  1844. serial_driver.open = wanpipe_tty_open;
  1845. serial_driver.close = wanpipe_tty_close;
  1846. serial_driver.write = wanpipe_tty_write;
  1847. serial_driver.put_char = wanpipe_tty_put_char;
  1848. serial_driver.flush_chars = wanpipe_tty_flush_chars;
  1849. serial_driver.write_room = wanpipe_tty_write_room;
  1850. serial_driver.chars_in_buffer = wanpipe_tty_chars_in_buffer;
  1851. serial_driver.flush_buffer = wanpipe_tty_flush_buffer;
  1852. //serial_driver.ioctl = wanpipe_tty_ioctl;
  1853. serial_driver.throttle = wanpipe_tty_throttle;
  1854. serial_driver.unthrottle = wanpipe_tty_unthrottle;
  1855. serial_driver.send_xchar = wanpipe_tty_send_xchar;
  1856. serial_driver.set_termios = wanpipe_tty_set_termios;
  1857. serial_driver.stop = wanpipe_tty_stop;
  1858. serial_driver.start = wanpipe_tty_start;
  1859. serial_driver.hangup = wanpipe_tty_hangup;
  1860. serial_driver.break_ctl = wanpipe_tty_break;
  1861. serial_driver.wait_until_sent = wanpipe_tty_wait_until_sent;
  1862. serial_driver.read_proc = wanpipe_tty_read_proc;
  1863. /*
  1864.  * The callout device is just like normal device except for
  1865.  * major number and the subtype code.
  1866.  */
  1867. callout_driver = serial_driver;
  1868. callout_driver.name = "cuw";
  1869. callout_driver.major = TTYAUX_MAJOR;
  1870. callout_driver.subtype = SERIAL_TYPE_CALLOUT;
  1871. callout_driver.read_proc = 0;
  1872. callout_driver.proc_entry = 0;
  1873. if (tty_register_driver(&serial_driver)){
  1874. printk(KERN_INFO "%s: Failed to register serial driver!n",
  1875. card->devname);
  1876. }
  1877. if (tty_register_driver(&callout_driver)){
  1878. printk(KERN_INFO "%s: Failed to register callout driver!n",
  1879. card->devname);
  1880. }
  1881. }
  1882. /* The subsequent ports must comply to the initial configuration */
  1883. if (tty_driver_mode != card->u.c.async_mode){
  1884. printk(KERN_INFO "%s: Error: TTY Driver operation mode mismatch!n",
  1885. card->devname);
  1886. printk(KERN_INFO "%s: The TTY driver is configured for %s!n",
  1887. card->devname, tty_driver_mode ? "ASYNC" : "SYNC");
  1888. return -EINVAL;
  1889. }
  1890. tty_init_cnt++;
  1891. printk(KERN_INFO "%s: Initializing TTY %s Driver Minor %in",
  1892. card->devname,
  1893. tty_driver_mode ? "ASYNC" : "SYNC",
  1894. card->tty_minor);
  1895. tty_card_map[card->tty_minor] = card;
  1896. state = &rs_table[card->tty_minor];
  1897. state->magic = SSTATE_MAGIC;
  1898. state->line = 0;
  1899. state->type = PORT_UNKNOWN;
  1900. state->custom_divisor = 0;
  1901. state->close_delay = 5*HZ/10;
  1902. state->closing_wait = 30*HZ;
  1903. state->callout_termios = callout_driver.init_termios;
  1904. state->normal_termios = serial_driver.init_termios;
  1905. state->icount.cts = state->icount.dsr = 
  1906. state->icount.rng = state->icount.dcd = 0;
  1907. state->icount.rx = state->icount.tx = 0;
  1908. state->icount.frame = state->icount.parity = 0;
  1909. state->icount.overrun = state->icount.brk = 0;
  1910. state->irq = card->wandev.irq; 
  1911. card->tty_task_queue.routine = tty_poll_task;
  1912. card->tty_task_queue.data = (void*)card;
  1913. return 0;
  1914. }
  1915. #endif
  1916. MODULE_LICENSE("GPL");
  1917. /****** End ****************************************************************/