packet.c 6.5 KB

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