OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [isdn/] [tpam/] [tpam_nco.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* $Id: tpam_nco.c,v 1.1.1.1 2004-04-15 02:03:59 phoenix Exp $
2
 *
3
 * Turbo PAM ISDN driver for Linux.
4
 * (Kernel Driver - Low Level NCO Manipulation)
5
 *
6
 * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
7
 *
8
 * This software may be used and distributed according to the terms
9
 * of the GNU General Public License, incorporated herein by reference.
10
 *
11
 * For all support questions please contact: <support@auvertech.fr>
12
 *
13
 */
14
 
15
#include <linux/pci.h>
16
#include <linux/sched.h>
17
#include <linux/tqueue.h>
18
#include <linux/interrupt.h>
19
#include <asm/io.h>
20
 
21
#include "tpam.h"
22
 
23
/* Local function prototypes */
24
static struct sk_buff *build_NCOpacket(u16, u16, u16, u16, u16);
25
static int extract_NCOParameter(struct sk_buff *, u8, void *, u16);
26
 
27
/*
28
 * Build a NCO packet (PCI message).
29
 *
30
 *      messageID: the message type (ID_*)
31
 *      size: size of the TLV block
32
 *      data_size: size of the data block
33
 *      ack: packet needs to send ack upon send
34
 *      ack_size: size of data to be acknowledged upon send
35
 *
36
 * Return: the sk_buff filled with the NCO packet, or NULL if error.
37
 */
38
static struct sk_buff *build_NCOpacket(u16 messageID, u16 size,
39
                                       u16 data_size, u16 ack,
40
                                       u16 ack_size) {
41
        struct sk_buff *skb;
42
        skb_header *h;
43
        pci_mpb *p;
44
        u16 finalsize;
45
 
46
        /* reserve enough space for the sk_buff header, the pci * header,
47
         * size bytes for the TLV block, size bytes for the data and 4 more
48
         * bytes in order to make sure we can write dwords to the board. */
49
        finalsize = sizeof(skb_header) + sizeof(pci_mpb) + size + data_size + 4;
50
 
51
        /* allocate the sk_buff */
52
        if (!(skb = alloc_skb(finalsize, GFP_ATOMIC))) {
53
                printk(KERN_ERR "TurboPAM(make_NCOpacket): alloc_skb failed\n");
54
                return NULL;
55
        }
56
 
57
        /* construct the skb_header */
58
        h = (skb_header *)skb_put(skb, sizeof(skb_header));
59
        h->size = sizeof(pci_mpb) + size;
60
        h->data_size = data_size;
61
        h->ack = ack;
62
        h->ack_size = ack_size;
63
 
64
        /* construct the pci_mpb */
65
        p = (pci_mpb *)skb_put(skb, sizeof(pci_mpb));
66
        p->exID = 0;
67
        p->flags = 0;
68
        p->errorCode = 0;
69
        p->messageID = messageID;
70
        p->maximumBlockTLVSize = MPB_MAXIMUMBLOCKTLVSIZE;
71
        p->actualBlockTLVSize = size;
72
        p->maximumDataSize = MPB_MAXIMUMDATASIZE;
73
        p->actualDataSize = data_size;
74
        return skb;
75
}
76
 
77
/*
78
 * Build a ACreateNCOReq message.
79
 *
80
 *      phone: the local phone number.
81
 *
82
 * Return: the sk_buff filled with the NCO packet, or NULL if error.
83
 */
84
struct sk_buff *build_ACreateNCOReq(const u8 *phone) {
85
        struct sk_buff *skb;
86
        u8 *tlv;
87
 
88
        dprintk("TurboPAM(build_ACreateNCOReq): phone=%s\n", phone);
89
 
90
        /* build the NCO packet */
91
        if (!(skb = build_NCOpacket(ID_ACreateNCOReq, 23 + strlen(phone), 0, 0, 0)))
92
                return NULL;
93
 
94
        /* add the parameters */
95
        tlv = (u8 *)skb_put(skb, 3);
96
        *tlv = PAR_NCOType;
97
        *(tlv+1) = 1;
98
        *(tlv+2) = 5;   /* mistery value... */
99
 
100
        tlv = (u8 *)skb_put(skb, 4);
101
        *tlv = PAR_U3Protocol;
102
        *(tlv+1) = 2;
103
        *(tlv+2) = 4;   /* no level 3 protocol */
104
        *(tlv+3) = 1;   /* HDLC in level 2 */
105
 
106
        tlv = (u8 *)skb_put(skb, 3);
107
        *tlv = PAR_Cdirection;
108
        *(tlv+1) = 1;
109
        *(tlv+2) = 3; /* PCI_DIRECTION_BOTH */
110
 
111
        tlv = (u8 *)skb_put(skb, 3);
112
        *tlv = PAR_Udirection;
113
        *(tlv+1) = 1;
114
        *(tlv+2) = 3; /* PCI_DIRECTION_BOTH */
115
 
116
        tlv = (u8 *)skb_put(skb, 4);
117
        *tlv = PAR_BearerCap;
118
        *(tlv+1) = 2;
119
        *(tlv+2) = 0x88;
120
        *(tlv+3) = 0x90;
121
 
122
        tlv = (u8 *)skb_put(skb, 6 + strlen(phone));
123
        *tlv = PAR_CallingNumber;
124
        *(tlv+1) = strlen(phone) + 4;
125
        *(tlv+2) = 0x01; /* international */
126
        *(tlv+3) = 0x01; /* isdn */
127
        *(tlv+4) = 0x00;
128
        *(tlv+5) = 0x00;
129
        memcpy(tlv + 6, phone, strlen(phone));
130
 
131
        return skb;
132
}
133
 
134
/*
135
 * Build a ADestroyNCOReq message.
136
 *
137
 *      ncoid: the NCO id.
138
 *
139
 * Return: the sk_buff filled with the NCO packet, or NULL if error.
140
 */
141
struct sk_buff *build_ADestroyNCOReq(u32 ncoid) {
142
        struct sk_buff *skb;
143
        u8 *tlv;
144
 
145
        dprintk("TurboPAM(build_ADestroyNCOReq): ncoid=%lu\n",
146
                (unsigned long)ncoid);
147
 
148
        /* build the NCO packet */
149
        if (!(skb = build_NCOpacket(ID_ADestroyNCOReq, 6, 0, 0, 0)))
150
                return NULL;
151
 
152
        /* add the parameters */
153
        tlv = (u8 *)skb_put(skb, 6);
154
        *tlv = PAR_NCOID;
155
        *(tlv+1) = 4;
156
        *((u32 *)(tlv+2)) = ncoid;
157
 
158
        return skb;
159
}
160
 
161
/*
162
 * Build a CConnectReq message.
163
 *
164
 *      ncoid: the NCO id.
165
 *      called: the destination phone number
166
 *      hdlc: type of connection: 1 (HDLC) or 0(modem)
167
 *
168
 * Return: the sk_buff filled with the NCO packet, or NULL if error.
169
 */
170
struct sk_buff *build_CConnectReq(u32 ncoid, const u8 *called, u8 hdlc) {
171
        struct sk_buff *skb;
172
        u8 *tlv;
173
 
174
        dprintk("TurboPAM(build_CConnectReq): ncoid=%lu, called=%s, hdlc=%d\n",
175
                (unsigned long)ncoid, called, hdlc);
176
 
177
        /* build the NCO packet */
178
        if (!(skb = build_NCOpacket(ID_CConnectReq, 20 + strlen(called), 0, 0, 0)))
179
                return NULL;
180
 
181
        /* add the parameters */
182
        tlv = (u8 *)skb_put(skb, 6);
183
        *tlv = PAR_NCOID;
184
        *(tlv+1) = 4;
185
        *((u32 *)(tlv+2)) = ncoid;
186
 
187
        tlv = (u8 *)skb_put(skb, 4 + strlen(called));
188
        *tlv = PAR_CalledNumber;
189
        *(tlv+1) = strlen(called) + 2;
190
        *(tlv+2) = 0x01; /* international */
191
        *(tlv+3) = 0x01; /* isdn */
192
        memcpy(tlv + 4, called, strlen(called));
193
 
194
        tlv = (u8 *)skb_put(skb, 3);
195
        *tlv = PAR_BearerCap;
196
        *(tlv+1) = 1;
197
        *(tlv+2) = hdlc ? 0x88 /* HDLC */ : 0x80 /* MODEM */;
198
 
199
        tlv = (u8 *)skb_put(skb, 4);
200
        *tlv = PAR_HLC;
201
        *(tlv+1) = 2;
202
        *(tlv+2) = 0x2;
203
        *(tlv+3) = 0x7f;
204
 
205
        tlv = (u8 *)skb_put(skb, 3);
206
        *tlv = PAR_Facility;
207
        *(tlv+1) = 1;
208
        *(tlv+2) = 2;
209
 
210
        return skb;
211
}
212
 
213
/*
214
 * Build a CConnectRsp message.
215
 *
216
 *      ncoid: the NCO id.
217
 *
218
 * Return: the sk_buff filled with the NCO packet, or NULL if error.
219
 */
220
struct sk_buff *build_CConnectRsp(u32 ncoid) {
221
        struct sk_buff *skb;
222
        u8 *tlv;
223
 
224
        dprintk("TurboPAM(build_CConnectRsp): ncoid=%lu\n",
225
                (unsigned long)ncoid);
226
 
227
        /* build the NCO packet */
228
        if (!(skb = build_NCOpacket(ID_CConnectRsp, 6, 0, 0, 0)))
229
                return NULL;
230
 
231
        /* add the parameters */
232
        tlv = (u8 *)skb_put(skb, 6);
233
        *tlv = PAR_NCOID;
234
        *(tlv+1) = 4;
235
        *((u32 *)(tlv+2)) = ncoid;
236
 
237
        return skb;
238
}
239
 
240
/*
241
 * Build a CDisconnectReq message.
242
 *
243
 *      ncoid: the NCO id.
244
 *
245
 * Return: the sk_buff filled with the NCO packet, or NULL if error.
246
 */
247
struct sk_buff *build_CDisconnectReq(u32 ncoid) {
248
        struct sk_buff *skb;
249
        u8 *tlv;
250
 
251
        dprintk("TurboPAM(build_CDisconnectReq): ncoid=%lu\n",
252
                (unsigned long)ncoid);
253
 
254
        /* build the NCO packet */
255
        if (!(skb = build_NCOpacket(ID_CDisconnectReq, 6, 0, 0, 0)))
256
                return NULL;
257
 
258
        /* add the parameters */
259
        tlv = (u8 *)skb_put(skb, 6);
260
        *tlv = PAR_NCOID;
261
        *(tlv+1) = 4;
262
        *((u32 *)(tlv+2)) = ncoid;
263
 
264
        return skb;
265
}
266
 
267
/*
268
 * Build a CDisconnectRsp message.
269
 *
270
 *      ncoid: the NCO id.
271
 *
272
 * Return: the sk_buff filled with the NCO packet, or NULL if error.
273
 */
274
struct sk_buff *build_CDisconnectRsp(u32 ncoid) {
275
        struct sk_buff *skb;
276
        u8 *tlv;
277
 
278
        dprintk("TurboPAM(build_CDisconnectRsp): ncoid=%lu\n",
279
                (unsigned long)ncoid);
280
 
281
        /* build the NCO packet */
282
        if (!(skb = build_NCOpacket(ID_CDisconnectRsp, 6, 0, 0, 0)))
283
                return NULL;
284
 
285
        /* add the parameters */
286
        tlv = (u8 *)skb_put(skb, 6);
287
        *tlv = PAR_NCOID;
288
        *(tlv+1) = 4;
289
        *((u32 *)(tlv+2)) = ncoid;
290
 
291
        return skb;
292
}
293
 
294
/*
295
 * Build a U3DataReq message.
296
 *
297
 *      ncoid: the NCO id.
298
 *      data: the data to be send
299
 *      len: length of the data
300
 *      ack: send ack upon send
301
 *      ack_size: size of data to be acknowledged upon send
302
 *
303
 * Return: the sk_buff filled with the NCO packet, or NULL if error.
304
 */
305
struct sk_buff *build_U3DataReq(u32 ncoid, void *data, u16 len,
306
                                u16 ack, u16 ack_size) {
307
        struct sk_buff *skb;
308
        u8 *tlv;
309
        void *p;
310
 
311
        dprintk("TurboPAM(build_U3DataReq): "
312
                "ncoid=%lu, len=%d, ack=%d, ack_size=%d\n",
313
                (unsigned long)ncoid, len, ack, ack_size);
314
 
315
        /* build the NCO packet */
316
        if (!(skb = build_NCOpacket(ID_U3DataReq, 6, len, ack, ack_size)))
317
                return NULL;
318
 
319
        /* add the parameters */
320
        tlv = (u8 *)skb_put(skb, 6);
321
        *tlv = PAR_NCOID;
322
        *(tlv+1) = 4;
323
        *((u32 *)(tlv+2)) = ncoid;
324
 
325
        p = skb_put(skb, len);
326
        memcpy(p, data, len);
327
 
328
        return skb;
329
}
330
 
331
/*
332
 * Extract a parameter from a TLV block.
333
 *
334
 *      skb: sk_buff containing the PCI message
335
 *      type: parameter to search for (PARAM_*)
336
 *      value: to be filled with the value of the parameter
337
 *      len: maximum length of the parameter value
338
 *
339
 * Return: 0 if OK, <0 if error.
340
 */
341
static int extract_NCOParameter(struct sk_buff *skb, u8 type,
342
                                void *value, u16 len) {
343
        void *buffer = (void *)skb->data;
344
        pci_mpb *p;
345
        void * bufferend;
346
        u8 valtype;
347
        u16 vallen;
348
 
349
        /* calculate the start and end of the TLV block */
350
        buffer += sizeof(skb_header);
351
        p = (pci_mpb *)buffer;
352
        buffer += sizeof(pci_mpb);
353
        bufferend = buffer + p->actualBlockTLVSize;
354
 
355
        /* walk through the parameters */
356
        while (buffer < bufferend) {
357
 
358
                /* parameter type */
359
                valtype = *((u8 *)buffer++);
360
                /* parameter length */
361
                vallen = *((u8 *)buffer++);
362
                if (vallen == 0xff) {
363
                        /* parameter length is on 2 bytes */
364
                        vallen = *((u8 *)buffer++);
365
                        vallen <<= 8;
366
                        vallen |= *((u8 *)buffer++);
367
                }
368
                /* got the right parameter */
369
                if (valtype == type) {
370
                        /* not enough space for returning the value */
371
                        if (vallen > len)
372
                                return -1;
373
                        /* OK, return it */
374
                        memcpy(value, buffer, vallen);
375
                        return 0;
376
                }
377
                buffer += vallen;
378
        }
379
        return -1;
380
}
381
 
382
/*
383
 * Parse a ACreateNCOCnf message.
384
 *
385
 *      skb: the sk_buff containing the message
386
 *      status: to be filled with the status field value
387
 *      ncoid: to be filled with the ncoid field value
388
 *
389
 * Return: 0 if OK, <0 if error.
390
 */
391
int parse_ACreateNCOCnf(struct sk_buff *skb, u8 *status, u32 *ncoid) {
392
 
393
        /* extract the status */
394
        if (extract_NCOParameter(skb, PAR_CompletionStatus, status, 1)) {
395
                printk(KERN_ERR "TurboPAM(parse_ACreateNCOCnf): "
396
                       "CompletionStatus not found\n");
397
                return -1;
398
        }
399
 
400
        if (*status) {
401
                dprintk("TurboPAM(parse_ACreateNCOCnf): status=%d\n", *status);
402
                return 0;
403
        }
404
 
405
        /* extract the ncoid */
406
        if (extract_NCOParameter(skb, PAR_NCOID, ncoid, 4)) {
407
                printk(KERN_ERR "TurboPAM(parse_ACreateNCOCnf): "
408
                       "NCOID not found\n");
409
                return -1;
410
        }
411
 
412
        dprintk("TurboPAM(parse_ACreateNCOCnf): ncoid=%lu, status=%d\n",
413
                (unsigned long)*ncoid, *status);
414
        return 0;
415
}
416
 
417
/*
418
 * Parse a ADestroyNCOCnf message. Not used in the driver.
419
 *
420
 *      skb: the sk_buff containing the message
421
 *      status: to be filled with the status field value
422
 *      ncoid: to be filled with the ncoid field value
423
 *
424
 * Return: 0 if OK, <0 if error.
425
 */
426
int parse_ADestroyNCOCnf(struct sk_buff *skb, u8 *status, u32 *ncoid) {
427
 
428
        /* extract the status */
429
        if (extract_NCOParameter(skb, PAR_CompletionStatus, status, 1)) {
430
                printk(KERN_ERR "TurboPAM(parse_ADestroyNCOCnf): "
431
                       "CompletionStatus not found\n");
432
                return -1;
433
        }
434
 
435
        if (*status) {
436
                dprintk("TurboPAM(parse_ADestroyNCOCnf): status=%d\n", *status);
437
                return 0;
438
        }
439
 
440
        /* extract the ncoid */
441
        if (extract_NCOParameter(skb, PAR_NCOID, ncoid, 4)) {
442
                printk(KERN_ERR "TurboPAM(parse_ADestroyNCOCnf): "
443
                       "NCOID not found\n");
444
                return -1;
445
        }
446
 
447
        dprintk("TurboPAM(parse_ADestroyNCOCnf): ncoid=%lu, status=%d\n",
448
                (unsigned long)*ncoid, *status);
449
        return 0;
450
}
451
 
452
/*
453
 * Parse a CConnectCnf message.
454
 *
455
 *      skb: the sk_buff containing the message
456
 *      ncoid: to be filled with the ncoid field value
457
 *
458
 * Return: 0 if OK, <0 if error.
459
 */
460
int parse_CConnectCnf(struct sk_buff *skb, u32 *ncoid) {
461
 
462
        /* extract the ncoid */
463
        if (extract_NCOParameter(skb, PAR_NCOID, ncoid, 4)) {
464
                printk(KERN_ERR "TurboPAM(parse_CConnectCnf): "
465
                       "NCOID not found\n");
466
                return -1;
467
        }
468
        dprintk("TurboPAM(parse_CConnectCnf): ncoid=%lu\n",
469
                (unsigned long)*ncoid);
470
        return 0;
471
}
472
 
473
/*
474
 * Parse a CConnectInd message.
475
 *
476
 *      skb: the sk_buff containing the message
477
 *      ncoid: to be filled with the ncoid field value
478
 *      hdlc: to be filled with 1 if the incoming connection is a HDLC one,
479
 *              with 0 if the incoming connection is a modem one
480
 *      calling: to be filled with the calling phone number value
481
 *      called: to be filled with the called phone number value
482
 *      plan: to be filled with the plan value
483
 *      screen: to be filled with the screen value
484
 *
485
 * Return: 0 if OK, <0 if error.
486
 */
487
int parse_CConnectInd(struct sk_buff *skb, u32 *ncoid, u8 *hdlc,
488
                      u8 *calling, u8 *called, u8 *plan, u8 *screen) {
489
        u8 phone[PHONE_MAXIMUMSIZE + 4];
490
 
491
        /* extract the ncoid */
492
        if (extract_NCOParameter(skb, PAR_NCOID, ncoid, 4)) {
493
                printk(KERN_ERR "TurboPAM(parse_CConnectInd): "
494
                       "NCOID not found\n");
495
                return -1;
496
        }
497
 
498
        /* extract the bearer capability field */
499
        if (extract_NCOParameter(skb, PAR_BearerCap, hdlc, 1)) {
500
                printk(KERN_ERR "TurboPAM(parse_CConnectInd): "
501
                       "BearerCap not found\n");
502
                return -1;
503
        }
504
        *hdlc = (*hdlc == 0x88) ? 1 : 0;
505
 
506
        /* extract the calling number / plan / screen */
507
        if (extract_NCOParameter(skb, PAR_CallingNumber, phone,
508
                                 PHONE_MAXIMUMSIZE + 4)) {
509
                printk(KERN_ERR "TurboPAM(parse_CConnectInd): "
510
                       "CallingNumber not found\n");
511
                return -1;
512
        }
513
        memcpy(calling, phone + 4, PHONE_MAXIMUMSIZE);
514
        *plan = phone[1];
515
        *screen = phone[3];
516
 
517
        /* extract the called number */
518
        if (extract_NCOParameter(skb, PAR_CalledNumber, phone,
519
                                 PHONE_MAXIMUMSIZE + 2)) {
520
                printk(KERN_ERR "TurboPAM(parse_CConnectInd): "
521
                       "CalledNumber not found\n");
522
                return -1;
523
        }
524
        memcpy(called, phone + 2, PHONE_MAXIMUMSIZE);
525
 
526
        dprintk("TurboPAM(parse_CConnectInd): "
527
                "ncoid=%lu, hdlc=%d, plan=%d, scr=%d, calling=%s, called=%s\n",
528
                (unsigned long)*ncoid, *hdlc, *plan, *screen, calling, called);
529
        return 0;
530
}
531
 
532
/*
533
 * Parse a CDisconnectCnf message.
534
 *
535
 *      skb: the sk_buff containing the message
536
 *      ncoid: to be filled with the ncoid field value
537
 *      causetopuf: to be filled with the cause field value
538
 *
539
 * Return: 0 if OK, <0 if error.
540
 */
541
int parse_CDisconnectCnf(struct sk_buff *skb, u32 *ncoid, u32 *causetopuf) {
542
 
543
        /* extract the ncoid */
544
        if (extract_NCOParameter(skb, PAR_NCOID, ncoid, 4)) {
545
                printk(KERN_ERR "TurboPAM(parse_CDisconnectCnf): "
546
                       "NCOID not found\n");
547
                return -1;
548
        }
549
 
550
        /* extract the cause of disconnection */
551
        if (extract_NCOParameter(skb, PAR_CauseToPUF, causetopuf, 4)) {
552
                printk(KERN_ERR "TurboPAM(parse_CDisconnectCnf): "
553
                       "CauseToPUF not found\n");
554
                return -1;
555
        }
556
 
557
        dprintk("TurboPAM(parse_CDisconnectCnf): ncoid=%lu, causetopuf=%lu\n",
558
                (unsigned long)*ncoid, (unsigned long)*causetopuf);
559
        return 0;
560
}
561
 
562
/*
563
 * Parse a CDisconnectInd message.
564
 *
565
 *      skb: the sk_buff containing the message
566
 *      ncoid: to be filled with the ncoid field value
567
 *      causetopuf: to be filled with the cause field value
568
 *
569
 * Return: 0 if OK, <0 if error.
570
 */
571
int parse_CDisconnectInd(struct sk_buff *skb, u32 *ncoid, u32 *causetopuf) {
572
 
573
        /* extract the ncoid */
574
        if (extract_NCOParameter(skb, PAR_NCOID, ncoid, 4)) {
575
                printk(KERN_ERR "TurboPAM(parse_CDisconnectInd): "
576
                       "NCOID not found\n");
577
                return -1;
578
        }
579
 
580
        /* extract the cause of disconnection */
581
        if (extract_NCOParameter(skb, PAR_CauseToPUF, causetopuf, 4)) {
582
                printk(KERN_ERR "TurboPAM(parse_CDisconnectInd): "
583
                       "CauseToPUF not found\n");
584
                return -1;
585
        }
586
 
587
        dprintk("TurboPAM(parse_CDisconnectInd): ncoid=%lu, causetopuf=%lu\n",
588
                (unsigned long)*ncoid, (unsigned long)*causetopuf);
589
        return 0;
590
}
591
 
592
/*
593
 * Parse a U3ReadyToReceiveInd message.
594
 *
595
 *      skb: the sk_buff containing the message
596
 *      ncoid: to be filled with the ncoid field value
597
 *      ready: to be filled with the ready field value
598
 *
599
 * Return: 0 if OK, <0 if error.
600
 */
601
int parse_U3ReadyToReceiveInd(struct sk_buff *skb, u32 *ncoid, u8 *ready) {
602
 
603
        /* extract the ncoid */
604
        if (extract_NCOParameter(skb, PAR_NCOID, ncoid, 4)) {
605
                printk(KERN_ERR "TurboPAM(parse_U3ReadyToReceiveInd): "
606
                       "NCOID not found\n");
607
                return -1;
608
        }
609
 
610
        /* extract the ready flag */
611
        if (extract_NCOParameter(skb, PAR_ReadyFlag, ready, 1)) {
612
                printk(KERN_ERR "TurboPAM(parse_U3ReadyToReceiveInd): "
613
                       "ReadyFlag not found\n");
614
                return -1;
615
        }
616
 
617
        dprintk("TurboPAM(parse_U3ReadyToReceiveInd): ncoid=%lu, ready=%d\n",
618
                (unsigned long)*ncoid, *ready);
619
        return 0;
620
}
621
 
622
/*
623
 * Parse a U3DataInd message.
624
 *
625
 *      skb: the sk_buff containing the message + data
626
 *      ncoid: to be filled with the ncoid field value
627
 *      data: to be filled with the data
628
 *      ready: to be filled with the data length
629
 *
630
 * Return: 0 if OK, <0 if error.
631
 */
632
int parse_U3DataInd(struct sk_buff *skb, u32 *ncoid, u8 **data, u16 *len) {
633
        pci_mpb *p;
634
 
635
        /* extract the ncoid */
636
        if (extract_NCOParameter(skb, PAR_NCOID, ncoid, 4) == -1) {
637
                printk(KERN_ERR "TurboPAM(parse_U3DataInd): NCOID not found\n");
638
                return -1;
639
        }
640
 
641
        /* get a pointer to the beginning of the data block and its length */
642
        p = (pci_mpb *)(skb->data + sizeof(skb_header));
643
        *len = p->actualDataSize;
644
        skb_pull(skb,
645
                 sizeof(skb_header) + sizeof(pci_mpb) + p->actualBlockTLVSize);
646
        *data = skb->data;
647
 
648
        dprintk("TurboPAM(parse_U3DataInd): ncoid=%lu, datalen=%d\n",
649
                (unsigned long)*ncoid, *len);
650
        return 0;
651
}
652
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.