packet.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /* $Id: packet.c,v 1.5.8.1 2001/09/23 22:24:59 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. #include "includes.h"
  18. #include "hardware.h"
  19. #include "message.h"
  20. #include "card.h"
  21. extern board *sc_adapter[];
  22. extern unsigned int cinst;
  23. extern int get_card_from_id(int);
  24. extern int indicate_status(int, int,ulong, char*);
  25. extern void memcpy_toshmem(int, void *, const void *, size_t);
  26. extern void memcpy_fromshmem(int, void *, const void *, size_t);
  27. extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
  28. unsigned int, unsigned int, unsigned int, unsigned int *);
  29. int sndpkt(int devId, int channel, struct sk_buff *data)
  30. {
  31. LLData ReqLnkWrite;
  32. int status;
  33. int card;
  34. unsigned long len;
  35. card = get_card_from_id(devId);
  36. if(!IS_VALID_CARD(card)) {
  37. pr_debug("invalid param: %d is not a valid card id\n", card);
  38. return -ENODEV;
  39. }
  40. pr_debug("%s: sndpkt: frst = 0x%x nxt = %d f = %d n = %d\n",
  41. sc_adapter[card]->devicename,
  42. sc_adapter[card]->channel[channel].first_sendbuf,
  43. sc_adapter[card]->channel[channel].next_sendbuf,
  44. sc_adapter[card]->channel[channel].free_sendbufs,
  45. sc_adapter[card]->channel[channel].num_sendbufs);
  46. if(!sc_adapter[card]->channel[channel].free_sendbufs) {
  47. pr_debug("%s: out of TX buffers\n",
  48. sc_adapter[card]->devicename);
  49. return -EINVAL;
  50. }
  51. if(data->len > BUFFER_SIZE) {
  52. pr_debug("%s: data overflows buffer size (data > buffer)\n",
  53. sc_adapter[card]->devicename);
  54. return -EINVAL;
  55. }
  56. ReqLnkWrite.buff_offset = sc_adapter[card]->channel[channel].next_sendbuf *
  57. BUFFER_SIZE + sc_adapter[card]->channel[channel].first_sendbuf;
  58. ReqLnkWrite.msg_len = data->len; /* sk_buff size */
  59. pr_debug("%s: writing %d bytes to buffer offset 0x%x\n",
  60. sc_adapter[card]->devicename,
  61. ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset);
  62. memcpy_toshmem(card, (char *)ReqLnkWrite.buff_offset, data->data, ReqLnkWrite.msg_len);
  63. /*
  64. * sendmessage
  65. */
  66. pr_debug("%s: sndpkt size=%d, buf_offset=0x%x buf_indx=%d\n",
  67. sc_adapter[card]->devicename,
  68. ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset,
  69. sc_adapter[card]->channel[channel].next_sendbuf);
  70. status = sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkWrite,
  71. channel+1, sizeof(LLData), (unsigned int*)&ReqLnkWrite);
  72. len = data->len;
  73. if(status) {
  74. pr_debug("%s: failed to send packet, status = %d\n",
  75. sc_adapter[card]->devicename, status);
  76. return -1;
  77. }
  78. else {
  79. sc_adapter[card]->channel[channel].free_sendbufs--;
  80. sc_adapter[card]->channel[channel].next_sendbuf =
  81. ++sc_adapter[card]->channel[channel].next_sendbuf ==
  82. sc_adapter[card]->channel[channel].num_sendbufs ? 0 :
  83. sc_adapter[card]->channel[channel].next_sendbuf;
  84. pr_debug("%s: packet sent successfully\n", sc_adapter[card]->devicename);
  85. dev_kfree_skb(data);
  86. indicate_status(card,ISDN_STAT_BSENT,channel, (char *)&len);
  87. }
  88. return len;
  89. }
  90. void rcvpkt(int card, RspMessage *rcvmsg)
  91. {
  92. LLData newll;
  93. struct sk_buff *skb;
  94. if(!IS_VALID_CARD(card)) {
  95. pr_debug("invalid param: %d is not a valid card id\n", card);
  96. return;
  97. }
  98. switch(rcvmsg->rsp_status){
  99. case 0x01:
  100. case 0x02:
  101. case 0x70:
  102. pr_debug("%s: error status code: 0x%x\n",
  103. sc_adapter[card]->devicename, rcvmsg->rsp_status);
  104. return;
  105. case 0x00:
  106. if (!(skb = dev_alloc_skb(rcvmsg->msg_data.response.msg_len))) {
  107. printk(KERN_WARNING "%s: rcvpkt out of memory, dropping packet\n",
  108. sc_adapter[card]->devicename);
  109. return;
  110. }
  111. skb_put(skb, rcvmsg->msg_data.response.msg_len);
  112. pr_debug("%s: getting data from offset: 0x%x\n",
  113. sc_adapter[card]->devicename,
  114. rcvmsg->msg_data.response.buff_offset);
  115. memcpy_fromshmem(card,
  116. skb_put(skb, rcvmsg->msg_data.response.msg_len),
  117. (char *)rcvmsg->msg_data.response.buff_offset,
  118. rcvmsg->msg_data.response.msg_len);
  119. sc_adapter[card]->card->rcvcallb_skb(sc_adapter[card]->driverId,
  120. rcvmsg->phy_link_no-1, skb);
  121. case 0x03:
  122. /*
  123. * Recycle the buffer
  124. */
  125. pr_debug("%s: buffer size : %d\n",
  126. sc_adapter[card]->devicename, BUFFER_SIZE);
  127. /* memset_shmem(card, rcvmsg->msg_data.response.buff_offset, 0, BUFFER_SIZE); */
  128. newll.buff_offset = rcvmsg->msg_data.response.buff_offset;
  129. newll.msg_len = BUFFER_SIZE;
  130. pr_debug("%s: recycled buffer at offset 0x%x size %d\n",
  131. sc_adapter[card]->devicename,
  132. newll.buff_offset, newll.msg_len);
  133. sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkRead,
  134. rcvmsg->phy_link_no, sizeof(LLData), (unsigned int *)&newll);
  135. }
  136. }
  137. int setup_buffers(int card, int c)
  138. {
  139. unsigned int nBuffers, i, cBase;
  140. unsigned int buffer_size;
  141. LLData RcvBuffOffset;
  142. if(!IS_VALID_CARD(card)) {
  143. pr_debug("invalid param: %d is not a valid card id\n", card);
  144. return -ENODEV;
  145. }
  146. /*
  147. * Calculate the buffer offsets (send/recv/send/recv)
  148. */
  149. pr_debug("%s: setting up channel buffer space in shared RAM\n",
  150. sc_adapter[card]->devicename);
  151. buffer_size = BUFFER_SIZE;
  152. nBuffers = ((sc_adapter[card]->ramsize - BUFFER_BASE) / buffer_size) / 2;
  153. nBuffers = nBuffers > BUFFERS_MAX ? BUFFERS_MAX : nBuffers;
  154. pr_debug("%s: calculating buffer space: %d buffers, %d big\n",
  155. sc_adapter[card]->devicename,
  156. nBuffers, buffer_size);
  157. if(nBuffers < 2) {
  158. pr_debug("%s: not enough buffer space\n",
  159. sc_adapter[card]->devicename);
  160. return -1;
  161. }
  162. cBase = (nBuffers * buffer_size) * (c - 1);
  163. pr_debug("%s: channel buffer offset from shared RAM: 0x%x\n",
  164. sc_adapter[card]->devicename, cBase);
  165. sc_adapter[card]->channel[c-1].first_sendbuf = BUFFER_BASE + cBase;
  166. sc_adapter[card]->channel[c-1].num_sendbufs = nBuffers / 2;
  167. sc_adapter[card]->channel[c-1].free_sendbufs = nBuffers / 2;
  168. sc_adapter[card]->channel[c-1].next_sendbuf = 0;
  169. pr_debug("%s: send buffer setup complete: first=0x%x n=%d f=%d, nxt=%d\n",
  170. sc_adapter[card]->devicename,
  171. sc_adapter[card]->channel[c-1].first_sendbuf,
  172. sc_adapter[card]->channel[c-1].num_sendbufs,
  173. sc_adapter[card]->channel[c-1].free_sendbufs,
  174. sc_adapter[card]->channel[c-1].next_sendbuf);
  175. /*
  176. * Prep the receive buffers
  177. */
  178. pr_debug("%s: adding %d RecvBuffers:\n",
  179. sc_adapter[card]->devicename, nBuffers /2);
  180. for (i = 0 ; i < nBuffers / 2; i++) {
  181. RcvBuffOffset.buff_offset =
  182. ((sc_adapter[card]->channel[c-1].first_sendbuf +
  183. (nBuffers / 2) * buffer_size) + (buffer_size * i));
  184. RcvBuffOffset.msg_len = buffer_size;
  185. pr_debug("%s: adding RcvBuffer #%d offset=0x%x sz=%d bufsz:%d\n",
  186. sc_adapter[card]->devicename,
  187. i + 1, RcvBuffOffset.buff_offset,
  188. RcvBuffOffset.msg_len,buffer_size);
  189. sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkRead,
  190. c, sizeof(LLData), (unsigned int *)&RcvBuffOffset);
  191. }
  192. return 0;
  193. }