2 * $Id: packet.c,v 1.4 1998/02/12 23:08:50 keil Exp $
3 * Copyright (C) 1996 SpellCaster Telecommunications Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * For more information, please contact gpl-info@spellcast.com or write:
21 * SpellCaster Telecommunications Inc.
22 * 5621 Finch Avenue East, Unit #3
23 * Scarborough, Ontario Canada
26 * +1 (416) 297-6433 Facsimile
29 #define __NO_VERSION__
35 extern board
*adapter
[];
36 extern unsigned int cinst
;
38 extern int get_card_from_id(int);
39 extern int indicate_status(int, int,ulong
, char*);
40 extern void *memcpy_toshmem(int, void *, const void *, size_t);
41 extern void *memcpy_fromshmem(int, void *, const void *, size_t);
42 extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
43 unsigned int, unsigned int, unsigned int, unsigned int *);
45 int sndpkt(int devId
, int channel
, struct sk_buff
*data
)
52 card
= get_card_from_id(devId
);
54 if(!IS_VALID_CARD(card
)) {
55 pr_debug("Invalid param: %d is not a valid card id\n", card
);
59 pr_debug("%s: Send Packet: frst = 0x%x nxt = %d f = %d n = %d\n",
60 adapter
[card
]->devicename
,
61 adapter
[card
]->channel
[channel
].first_sendbuf
,
62 adapter
[card
]->channel
[channel
].next_sendbuf
,
63 adapter
[card
]->channel
[channel
].free_sendbufs
,
64 adapter
[card
]->channel
[channel
].num_sendbufs
);
66 if(!adapter
[card
]->channel
[channel
].free_sendbufs
) {
67 pr_debug("%s: Out out TX buffers\n", adapter
[card
]->devicename
);
71 if(data
->len
> BUFFER_SIZE
) {
72 pr_debug("%s: Data overflows buffer size (data > buffer)\n", adapter
[card
]->devicename
);
76 ReqLnkWrite
.buff_offset
= adapter
[card
]->channel
[channel
].next_sendbuf
*
77 BUFFER_SIZE
+ adapter
[card
]->channel
[channel
].first_sendbuf
;
78 ReqLnkWrite
.msg_len
= data
->len
; /* sk_buff size */
79 pr_debug("%s: Writing %d bytes to buffer offset 0x%x\n", adapter
[card
]->devicename
,
80 ReqLnkWrite
.msg_len
, ReqLnkWrite
.buff_offset
);
81 memcpy_toshmem(card
, (char *)ReqLnkWrite
.buff_offset
, data
->data
, ReqLnkWrite
.msg_len
);
86 pr_debug("%s: Send Packet size=%d, buf_offset=0x%x buf_indx=%d\n",
87 adapter
[card
]->devicename
,
88 ReqLnkWrite
.msg_len
, ReqLnkWrite
.buff_offset
,
89 adapter
[card
]->channel
[channel
].next_sendbuf
);
91 status
= sendmessage(card
, CEPID
, ceReqTypeLnk
, ceReqClass1
, ceReqLnkWrite
,
92 channel
+1, sizeof(LLData
), (unsigned int*)&ReqLnkWrite
);
95 pr_debug("%s: Failed to send packet, status = %d\n", adapter
[card
]->devicename
, status
);
99 adapter
[card
]->channel
[channel
].free_sendbufs
--;
100 adapter
[card
]->channel
[channel
].next_sendbuf
=
101 ++adapter
[card
]->channel
[channel
].next_sendbuf
==
102 adapter
[card
]->channel
[channel
].num_sendbufs
? 0 :
103 adapter
[card
]->channel
[channel
].next_sendbuf
;
104 pr_debug("%s: Packet sent successfully\n", adapter
[card
]->devicename
);
106 indicate_status(card
,ISDN_STAT_BSENT
,channel
, (char *)&len
);
111 void rcvpkt(int card
, RspMessage
*rcvmsg
)
116 if(!IS_VALID_CARD(card
)) {
117 pr_debug("Invalid param: %d is not a valid card id\n", card
);
121 switch(rcvmsg
->rsp_status
){
125 pr_debug("%s: Error status code: 0x%x\n", adapter
[card
]->devicename
, rcvmsg
->rsp_status
);
128 if (!(skb
= dev_alloc_skb(rcvmsg
->msg_data
.response
.msg_len
))) {
129 printk(KERN_WARNING
"%s: rcvpkt out of memory, dropping packet\n",
130 adapter
[card
]->devicename
);
133 skb_put(skb
, rcvmsg
->msg_data
.response
.msg_len
);
134 pr_debug("%s: getting data from offset: 0x%x\n",
135 adapter
[card
]->devicename
,rcvmsg
->msg_data
.response
.buff_offset
);
136 memcpy_fromshmem(card
,
137 skb_put(skb
, rcvmsg
->msg_data
.response
.msg_len
),
138 (char *)rcvmsg
->msg_data
.response
.buff_offset
,
139 rcvmsg
->msg_data
.response
.msg_len
);
140 adapter
[card
]->card
->rcvcallb_skb(adapter
[card
]->driverId
,
141 rcvmsg
->phy_link_no
-1, skb
);
147 pr_debug("%s: Buffer size : %d\n", adapter
[card
]->devicename
, BUFFER_SIZE
);
148 /* memset_shmem(card, rcvmsg->msg_data.response.buff_offset, 0, BUFFER_SIZE); */
149 newll
.buff_offset
= rcvmsg
->msg_data
.response
.buff_offset
;
150 newll
.msg_len
= BUFFER_SIZE
;
151 pr_debug("%s: recycled buffer at offset 0x%x size %d\n", adapter
[card
]->devicename
,
152 newll
.buff_offset
, newll
.msg_len
);
153 sendmessage(card
, CEPID
, ceReqTypeLnk
, ceReqClass1
, ceReqLnkRead
,
154 rcvmsg
->phy_link_no
, sizeof(LLData
), (unsigned int *)&newll
);
159 int setup_buffers(int card
, int c
)
161 unsigned int nBuffers
, i
, cBase
;
162 unsigned int buffer_size
;
163 LLData RcvBuffOffset
;
165 if(!IS_VALID_CARD(card
)) {
166 pr_debug("Invalid param: %d is not a valid card id\n", card
);
171 * Calculate the buffer offsets (send/recv/send/recv)
173 pr_debug("%s: Seting up channel buffer space in shared RAM\n", adapter
[card
]->devicename
);
174 buffer_size
= BUFFER_SIZE
;
175 nBuffers
= ((adapter
[card
]->ramsize
- BUFFER_BASE
) / buffer_size
) / 2;
176 nBuffers
= nBuffers
> BUFFERS_MAX
? BUFFERS_MAX
: nBuffers
;
177 pr_debug("%s: Calculating buffer space: %d buffers, %d big\n", adapter
[card
]->devicename
,
178 nBuffers
, buffer_size
);
180 pr_debug("%s: Not enough buffer space\n", adapter
[card
]->devicename
);
183 cBase
= (nBuffers
* buffer_size
) * (c
- 1);
184 pr_debug("%s: Channel buffer offset from Shared RAM: 0x%x\n", adapter
[card
]->devicename
, cBase
);
185 adapter
[card
]->channel
[c
-1].first_sendbuf
= BUFFER_BASE
+ cBase
;
186 adapter
[card
]->channel
[c
-1].num_sendbufs
= nBuffers
/ 2;
187 adapter
[card
]->channel
[c
-1].free_sendbufs
= nBuffers
/ 2;
188 adapter
[card
]->channel
[c
-1].next_sendbuf
= 0;
189 pr_debug("%s: Send buffer setup complete: first=0x%x n=%d f=%d, nxt=%d\n",
190 adapter
[card
]->devicename
,
191 adapter
[card
]->channel
[c
-1].first_sendbuf
,
192 adapter
[card
]->channel
[c
-1].num_sendbufs
,
193 adapter
[card
]->channel
[c
-1].free_sendbufs
,
194 adapter
[card
]->channel
[c
-1].next_sendbuf
);
197 * Prep the receive buffers
199 pr_debug("%s: Adding %d RecvBuffers:\n", adapter
[card
]->devicename
, nBuffers
/2);
200 for (i
= 0 ; i
< nBuffers
/ 2; i
++) {
201 RcvBuffOffset
.buff_offset
=
202 ((adapter
[card
]->channel
[c
-1].first_sendbuf
+
203 (nBuffers
/ 2) * buffer_size
) + (buffer_size
* i
));
204 RcvBuffOffset
.msg_len
= buffer_size
;
205 pr_debug("%s: Adding RcvBuffer #%d offset=0x%x sz=%d buffsz:%d\n",
206 adapter
[card
]->devicename
,
207 i
+ 1, RcvBuffOffset
.buff_offset
,
208 RcvBuffOffset
.msg_len
,buffer_size
);
209 sendmessage(card
, CEPID
, ceReqTypeLnk
, ceReqClass1
, ceReqLnkRead
,
210 c
, sizeof(LLData
), (unsigned int *)&RcvBuffOffset
);
215 int print_skb(int card
,char *skb_p
, int len
){
217 pr_debug("%s: data at 0x%x len: 0x%x\n",adapter
[card
]->devicename
,
219 for(i
=1;i
<=len
;i
++,skb_p
++){
220 data
= (int) (0xff & (*skb_p
));
221 pr_debug("%s: data = 0x%x",adapter
[card
]->devicename
,data
);