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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: packet.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  2.  *
  3.  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  4.  *
  5.  * This software may be used and distributed according to the terms
  6.  * of the GNU General Public License, incorporated herein by reference.
  7.  *
  8.  * For more information, please contact gpl-info@spellcast.com or write:
  9.  *
  10.  *     SpellCaster Telecommunications Inc.
  11.  *     5621 Finch Avenue East, Unit #3
  12.  *     Scarborough, Ontario  Canada
  13.  *     M1B 2T9
  14.  *     +1 (416) 297-8565
  15.  *     +1 (416) 297-6433 Facsimile
  16.  */
  17. #define __NO_VERSION__
  18. #include "includes.h"
  19. #include "hardware.h"
  20. #include "message.h"
  21. #include "card.h"
  22. extern board *adapter[];
  23. extern unsigned int cinst;
  24. extern int get_card_from_id(int);
  25. extern int indicate_status(int, int,ulong, char*);
  26. extern void *memcpy_toshmem(int, void *, const void *, size_t);
  27. extern void *memcpy_fromshmem(int, void *, const void *, size_t);
  28. extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
  29.                 unsigned int, unsigned int, unsigned int, unsigned int *);
  30. int sndpkt(int devId, int channel, struct sk_buff *data)
  31. {
  32. LLData ReqLnkWrite;
  33. int status;
  34. int card;
  35. unsigned long len;
  36. card = get_card_from_id(devId);
  37. if(!IS_VALID_CARD(card)) {
  38. pr_debug("invalid param: %d is not a valid card idn", card);
  39. return -ENODEV;
  40. }
  41. pr_debug("%s: sndpkt: frst = 0x%x nxt = %d  f = %d n = %dn",
  42. adapter[card]->devicename,
  43. adapter[card]->channel[channel].first_sendbuf,
  44. adapter[card]->channel[channel].next_sendbuf,
  45. adapter[card]->channel[channel].free_sendbufs,
  46. adapter[card]->channel[channel].num_sendbufs);
  47. if(!adapter[card]->channel[channel].free_sendbufs) {
  48. pr_debug("%s: out of TX buffersn", adapter[card]->devicename);
  49. return -EINVAL;
  50. }
  51. if(data->len > BUFFER_SIZE) {
  52. pr_debug("%s: data overflows buffer size (data > buffer)n", adapter[card]->devicename);
  53. return -EINVAL;
  54. }
  55. ReqLnkWrite.buff_offset = adapter[card]->channel[channel].next_sendbuf *
  56. BUFFER_SIZE + adapter[card]->channel[channel].first_sendbuf;
  57. ReqLnkWrite.msg_len = data->len; /* sk_buff size */
  58. pr_debug("%s: writing %d bytes to buffer offset 0x%xn", adapter[card]->devicename,
  59. ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset);
  60. memcpy_toshmem(card, (char *)ReqLnkWrite.buff_offset, data->data, ReqLnkWrite.msg_len);
  61. /*
  62.  * sendmessage
  63.  */
  64. pr_debug("%s: sndpkt size=%d, buf_offset=0x%x buf_indx=%dn",
  65. adapter[card]->devicename,
  66. ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset,
  67. adapter[card]->channel[channel].next_sendbuf);
  68. status = sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkWrite,
  69. channel+1, sizeof(LLData), (unsigned int*)&ReqLnkWrite);
  70. len = data->len;
  71. if(status) {
  72. pr_debug("%s: failed to send packet, status = %dn", adapter[card]->devicename, status);
  73. return -1;
  74. }
  75. else {
  76. adapter[card]->channel[channel].free_sendbufs--;
  77. adapter[card]->channel[channel].next_sendbuf =
  78. ++adapter[card]->channel[channel].next_sendbuf ==
  79. adapter[card]->channel[channel].num_sendbufs ? 0 :
  80. adapter[card]->channel[channel].next_sendbuf;
  81. pr_debug("%s: packet sent successfullyn", adapter[card]->devicename);
  82. dev_kfree_skb(data);
  83. indicate_status(card,ISDN_STAT_BSENT,channel, (char *)&len);
  84. }
  85. return len;
  86. }
  87. void rcvpkt(int card, RspMessage *rcvmsg)
  88. {
  89. LLData newll;
  90. struct sk_buff *skb;
  91. if(!IS_VALID_CARD(card)) {
  92. pr_debug("invalid param: %d is not a valid card idn", card);
  93. return;
  94. }
  95. switch(rcvmsg->rsp_status){
  96. case 0x01:
  97. case 0x02:
  98. case 0x70:
  99. pr_debug("%s: error status code: 0x%xn", adapter[card]->devicename, rcvmsg->rsp_status);
  100. return;
  101. case 0x00: 
  102.     if (!(skb = dev_alloc_skb(rcvmsg->msg_data.response.msg_len))) {
  103. printk(KERN_WARNING "%s: rcvpkt out of memory, dropping packetn",
  104. adapter[card]->devicename);
  105. return;
  106. }
  107. skb_put(skb, rcvmsg->msg_data.response.msg_len);
  108. pr_debug("%s: getting data from offset: 0x%xn",
  109. adapter[card]->devicename,rcvmsg->msg_data.response.buff_offset);
  110. memcpy_fromshmem(card,
  111. skb_put(skb, rcvmsg->msg_data.response.msg_len),
  112.   (char *)rcvmsg->msg_data.response.buff_offset,
  113. rcvmsg->msg_data.response.msg_len);
  114. adapter[card]->card->rcvcallb_skb(adapter[card]->driverId,
  115. rcvmsg->phy_link_no-1, skb);
  116. case 0x03:
  117. /*
  118.    * Recycle the buffer
  119.    */
  120. pr_debug("%s: buffer size : %dn", adapter[card]->devicename, BUFFER_SIZE);
  121. /* memset_shmem(card, rcvmsg->msg_data.response.buff_offset, 0, BUFFER_SIZE); */
  122. newll.buff_offset = rcvmsg->msg_data.response.buff_offset;
  123. newll.msg_len = BUFFER_SIZE;
  124. pr_debug("%s: recycled buffer at offset 0x%x size %dn", adapter[card]->devicename,
  125. newll.buff_offset, newll.msg_len);
  126. sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkRead,
  127. rcvmsg->phy_link_no, sizeof(LLData), (unsigned int *)&newll);
  128. }
  129. }
  130. int setup_buffers(int card, int c)
  131. {
  132. unsigned int nBuffers, i, cBase;
  133. unsigned int buffer_size;
  134. LLData RcvBuffOffset;
  135. if(!IS_VALID_CARD(card)) {
  136. pr_debug("invalid param: %d is not a valid card idn", card);
  137. return -ENODEV;
  138. }
  139. /*
  140.  * Calculate the buffer offsets (send/recv/send/recv)
  141.  */
  142. pr_debug("%s: setting up channel buffer space in shared RAMn", adapter[card]->devicename);
  143. buffer_size = BUFFER_SIZE;
  144. nBuffers = ((adapter[card]->ramsize - BUFFER_BASE) / buffer_size) / 2;
  145. nBuffers = nBuffers > BUFFERS_MAX ? BUFFERS_MAX : nBuffers;
  146. pr_debug("%s: calculating buffer space: %d buffers, %d bign", adapter[card]->devicename,
  147. nBuffers, buffer_size);
  148. if(nBuffers < 2) {
  149. pr_debug("%s: not enough buffer spacen", adapter[card]->devicename);
  150. return -1;
  151. }
  152. cBase = (nBuffers * buffer_size) * (c - 1);
  153. pr_debug("%s: channel buffer offset from shared RAM: 0x%xn", adapter[card]->devicename, cBase);
  154. adapter[card]->channel[c-1].first_sendbuf = BUFFER_BASE + cBase;
  155. adapter[card]->channel[c-1].num_sendbufs = nBuffers / 2;
  156. adapter[card]->channel[c-1].free_sendbufs = nBuffers / 2;
  157. adapter[card]->channel[c-1].next_sendbuf = 0;
  158. pr_debug("%s: send buffer setup complete: first=0x%x n=%d f=%d, nxt=%dn",
  159. adapter[card]->devicename,
  160. adapter[card]->channel[c-1].first_sendbuf,
  161. adapter[card]->channel[c-1].num_sendbufs,
  162. adapter[card]->channel[c-1].free_sendbufs,
  163. adapter[card]->channel[c-1].next_sendbuf);
  164. /*
  165.  * Prep the receive buffers
  166.  */
  167. pr_debug("%s: adding %d RecvBuffers:n", adapter[card]->devicename, nBuffers /2);
  168. for (i = 0 ; i < nBuffers / 2; i++) {
  169. RcvBuffOffset.buff_offset = 
  170. ((adapter[card]->channel[c-1].first_sendbuf +
  171. (nBuffers / 2) * buffer_size) + (buffer_size * i));
  172. RcvBuffOffset.msg_len = buffer_size;
  173. pr_debug("%s: adding RcvBuffer #%d offset=0x%x sz=%d bufsz:%dn",
  174. adapter[card]->devicename,
  175. i + 1, RcvBuffOffset.buff_offset, 
  176. RcvBuffOffset.msg_len,buffer_size);
  177. sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkRead,
  178. c, sizeof(LLData), (unsigned int *)&RcvBuffOffset);
  179. return 0;
  180. }
  181. int print_skb(int card,char *skb_p, int len){
  182. int i,data;
  183. pr_debug("%s: data at 0x%x len: 0x%xn",adapter[card]->devicename,
  184. skb_p,len);
  185. for(i=1;i<=len;i++,skb_p++){
  186. data = (int) (0xff & (*skb_p));
  187. pr_debug("%s: data =  0x%x",adapter[card]->devicename,data);
  188. if(!(i%4))
  189. pr_debug(" ");
  190. if(!(i%32))
  191. pr_debug("n");
  192. }
  193. pr_debug("n");
  194. return 0;
  195. }