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