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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [lapb/] [lapb_iface.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      LAPB release 002
3
 *
4
 *      This code REQUIRES 2.1.15 or higher/ NET3.038
5
 *
6
 *      This module:
7
 *              This module is free software; you can redistribute it and/or
8
 *              modify it under the terms of the GNU General Public License
9
 *              as published by the Free Software Foundation; either version
10
 *              2 of the License, or (at your option) any later version.
11
 *
12
 *      History
13
 *      LAPB 001        Jonathan Naylor Started Coding
14
 *      LAPB 002        Jonathan Naylor New timer architecture.
15
 *      2000-10-29      Henner Eisen    lapb_data_indication() return status.
16
 */
17
 
18
#include <linux/module.h>
19
#include <linux/errno.h>
20
#include <linux/types.h>
21
#include <linux/socket.h>
22
#include <linux/in.h>
23
#include <linux/kernel.h>
24
#include <linux/sched.h>
25
#include <linux/timer.h>
26
#include <linux/string.h>
27
#include <linux/sockios.h>
28
#include <linux/net.h>
29
#include <linux/inet.h>
30
#include <linux/if_arp.h>
31
#include <linux/skbuff.h>
32
#include <net/sock.h>
33
#include <asm/uaccess.h>
34
#include <asm/system.h>
35
#include <linux/fcntl.h>
36
#include <linux/mm.h>
37
#include <linux/interrupt.h>
38
#include <linux/stat.h>
39
#include <linux/init.h>
40
#include <net/lapb.h>
41
 
42
static lapb_cb *volatile lapb_list /* = NULL initially */;
43
 
44
/*
45
 *      Free an allocated lapb control block. This is done to centralise
46
 *      the MOD count code.
47
 */
48
static void lapb_free_cb(lapb_cb *lapb)
49
{
50
        kfree(lapb);
51
 
52
        MOD_DEC_USE_COUNT;
53
}
54
 
55
/*
56
 *      Socket removal during an interrupt is now safe.
57
 */
58
static void lapb_remove_cb(lapb_cb *lapb)
59
{
60
        lapb_cb *s;
61
        unsigned long flags;
62
 
63
        save_flags(flags); cli();
64
 
65
        if ((s = lapb_list) == lapb) {
66
                lapb_list = s->next;
67
                restore_flags(flags);
68
                return;
69
        }
70
 
71
        while (s != NULL && s->next != NULL) {
72
                if (s->next == lapb) {
73
                        s->next = lapb->next;
74
                        restore_flags(flags);
75
                        return;
76
                }
77
 
78
                s = s->next;
79
        }
80
 
81
        restore_flags(flags);
82
}
83
 
84
/*
85
 *      Add a socket to the bound sockets list.
86
 */
87
static void lapb_insert_cb(lapb_cb *lapb)
88
{
89
        unsigned long flags;
90
 
91
        save_flags(flags); cli();
92
 
93
        lapb->next = lapb_list;
94
        lapb_list  = lapb;
95
 
96
        restore_flags(flags);
97
}
98
 
99
/*
100
 *      Convert the integer token used by the device driver into a pointer
101
 *      to a LAPB control structure.
102
 */
103
static lapb_cb *lapb_tokentostruct(void *token)
104
{
105
        lapb_cb *lapb;
106
 
107
        for (lapb = lapb_list; lapb != NULL; lapb = lapb->next)
108
                if (lapb->token == token)
109
                        return lapb;
110
 
111
        return NULL;
112
}
113
 
114
/*
115
 *      Create an empty LAPB control block.
116
 */
117
static lapb_cb *lapb_create_cb(void)
118
{
119
        lapb_cb *lapb;
120
 
121
        if ((lapb = kmalloc(sizeof(*lapb), GFP_ATOMIC)) == NULL)
122
                return NULL;
123
 
124
        MOD_INC_USE_COUNT;
125
 
126
        memset(lapb, 0x00, sizeof(*lapb));
127
 
128
        skb_queue_head_init(&lapb->write_queue);
129
        skb_queue_head_init(&lapb->ack_queue);
130
 
131
        init_timer(&lapb->t1timer);
132
        init_timer(&lapb->t2timer);
133
 
134
        lapb->t1      = LAPB_DEFAULT_T1;
135
        lapb->t2      = LAPB_DEFAULT_T2;
136
        lapb->n2      = LAPB_DEFAULT_N2;
137
        lapb->mode    = LAPB_DEFAULT_MODE;
138
        lapb->window  = LAPB_DEFAULT_WINDOW;
139
        lapb->state   = LAPB_STATE_0;
140
 
141
        return lapb;
142
}
143
 
144
int lapb_register(void *token, struct lapb_register_struct *callbacks)
145
{
146
        lapb_cb *lapb;
147
 
148
        if (lapb_tokentostruct(token) != NULL)
149
                return LAPB_BADTOKEN;
150
 
151
        if ((lapb = lapb_create_cb()) == NULL)
152
                return LAPB_NOMEM;
153
 
154
        lapb->token     = token;
155
        lapb->callbacks = *callbacks;
156
 
157
        lapb_insert_cb(lapb);
158
 
159
        lapb_start_t1timer(lapb);
160
 
161
        return LAPB_OK;
162
}
163
 
164
int lapb_unregister(void *token)
165
{
166
        lapb_cb *lapb;
167
 
168
        if ((lapb = lapb_tokentostruct(token)) == NULL)
169
                return LAPB_BADTOKEN;
170
 
171
        lapb_stop_t1timer(lapb);
172
        lapb_stop_t2timer(lapb);
173
 
174
        lapb_clear_queues(lapb);
175
 
176
        lapb_remove_cb(lapb);
177
 
178
        lapb_free_cb(lapb);
179
 
180
        return LAPB_OK;
181
}
182
 
183
int lapb_getparms(void *token, struct lapb_parms_struct *parms)
184
{
185
        lapb_cb *lapb;
186
 
187
        if ((lapb = lapb_tokentostruct(token)) == NULL)
188
                return LAPB_BADTOKEN;
189
 
190
        parms->t1      = lapb->t1 / HZ;
191
        parms->t2      = lapb->t2 / HZ;
192
        parms->n2      = lapb->n2;
193
        parms->n2count = lapb->n2count;
194
        parms->state   = lapb->state;
195
        parms->window  = lapb->window;
196
        parms->mode    = lapb->mode;
197
 
198
        if (!timer_pending(&lapb->t1timer))
199
                parms->t1timer = 0;
200
        else
201
                parms->t1timer = (lapb->t1timer.expires - jiffies) / HZ;
202
 
203
        if (!timer_pending(&lapb->t2timer))
204
                parms->t2timer = 0;
205
        else
206
                parms->t2timer = (lapb->t2timer.expires - jiffies) / HZ;
207
 
208
        return LAPB_OK;
209
}
210
 
211
int lapb_setparms(void *token, struct lapb_parms_struct *parms)
212
{
213
        lapb_cb *lapb;
214
 
215
        if ((lapb = lapb_tokentostruct(token)) == NULL)
216
                return LAPB_BADTOKEN;
217
 
218
        if (parms->t1 < 1)
219
                return LAPB_INVALUE;
220
 
221
        if (parms->t2 < 1)
222
                return LAPB_INVALUE;
223
 
224
        if (parms->n2 < 1)
225
                return LAPB_INVALUE;
226
 
227
        if (lapb->state == LAPB_STATE_0) {
228
                if (parms->mode & LAPB_EXTENDED) {
229
                        if (parms->window < 1 || parms->window > 127)
230
                                return LAPB_INVALUE;
231
                } else {
232
                        if (parms->window < 1 || parms->window > 7)
233
                                return LAPB_INVALUE;
234
                }
235
 
236
                lapb->mode    = parms->mode;
237
                lapb->window  = parms->window;
238
        }
239
 
240
        lapb->t1    = parms->t1 * HZ;
241
        lapb->t2    = parms->t2 * HZ;
242
        lapb->n2    = parms->n2;
243
 
244
        return LAPB_OK;
245
}
246
 
247
int lapb_connect_request(void *token)
248
{
249
        lapb_cb *lapb;
250
 
251
        if ((lapb = lapb_tokentostruct(token)) == NULL)
252
                return LAPB_BADTOKEN;
253
 
254
        switch (lapb->state) {
255
                case LAPB_STATE_1:
256
                        return LAPB_OK;
257
                case LAPB_STATE_3:
258
                case LAPB_STATE_4:
259
                        return LAPB_CONNECTED;
260
        }
261
 
262
        lapb_establish_data_link(lapb);
263
 
264
#if LAPB_DEBUG > 0
265
        printk(KERN_DEBUG "lapb: (%p) S0 -> S1\n", lapb->token);
266
#endif
267
 
268
        lapb->state = LAPB_STATE_1;
269
 
270
        return LAPB_OK;
271
}
272
 
273
int lapb_disconnect_request(void *token)
274
{
275
        lapb_cb *lapb;
276
 
277
        if ((lapb = lapb_tokentostruct(token)) == NULL)
278
                return LAPB_BADTOKEN;
279
 
280
        switch (lapb->state) {
281
                case LAPB_STATE_0:
282
                        return LAPB_NOTCONNECTED;
283
 
284
                case LAPB_STATE_1:
285
#if LAPB_DEBUG > 1
286
                        printk(KERN_DEBUG "lapb: (%p) S1 TX DISC(1)\n", lapb->token);
287
#endif
288
#if LAPB_DEBUG > 0
289
                        printk(KERN_DEBUG "lapb: (%p) S1 -> S0\n", lapb->token);
290
#endif
291
                        lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND);
292
                        lapb->state = LAPB_STATE_0;
293
                        lapb_start_t1timer(lapb);
294
                        return LAPB_NOTCONNECTED;
295
 
296
                case LAPB_STATE_2:
297
                        return LAPB_OK;
298
        }
299
 
300
        lapb_clear_queues(lapb);
301
        lapb->n2count = 0;
302
        lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND);
303
        lapb_start_t1timer(lapb);
304
        lapb_stop_t2timer(lapb);
305
        lapb->state = LAPB_STATE_2;
306
 
307
#if LAPB_DEBUG > 1
308
        printk(KERN_DEBUG "lapb: (%p) S3 DISC(1)\n", lapb->token);
309
#endif
310
#if LAPB_DEBUG > 0
311
        printk(KERN_DEBUG "lapb: (%p) S3 -> S2\n", lapb->token);
312
#endif
313
 
314
        return LAPB_OK;
315
}
316
 
317
int lapb_data_request(void *token, struct sk_buff *skb)
318
{
319
        lapb_cb *lapb;
320
 
321
        if ((lapb = lapb_tokentostruct(token)) == NULL)
322
                return LAPB_BADTOKEN;
323
 
324
        if (lapb->state != LAPB_STATE_3 && lapb->state != LAPB_STATE_4)
325
                return LAPB_NOTCONNECTED;
326
 
327
        skb_queue_tail(&lapb->write_queue, skb);
328
 
329
        lapb_kick(lapb);
330
 
331
        return LAPB_OK;
332
}
333
 
334
int lapb_data_received(void *token, struct sk_buff *skb)
335
{
336
        lapb_cb *lapb;
337
 
338
        if ((lapb = lapb_tokentostruct(token)) == NULL)
339
                return LAPB_BADTOKEN;
340
 
341
        lapb_data_input(lapb, skb);
342
 
343
        return LAPB_OK;
344
}
345
 
346
void lapb_connect_confirmation(lapb_cb *lapb, int reason)
347
{
348
        if (lapb->callbacks.connect_confirmation != NULL)
349
                (lapb->callbacks.connect_confirmation)(lapb->token, reason);
350
}
351
 
352
void lapb_connect_indication(lapb_cb *lapb, int reason)
353
{
354
        if (lapb->callbacks.connect_indication != NULL)
355
                (lapb->callbacks.connect_indication)(lapb->token, reason);
356
}
357
 
358
void lapb_disconnect_confirmation(lapb_cb *lapb, int reason)
359
{
360
        if (lapb->callbacks.disconnect_confirmation != NULL)
361
                (lapb->callbacks.disconnect_confirmation)(lapb->token, reason);
362
}
363
 
364
void lapb_disconnect_indication(lapb_cb *lapb, int reason)
365
{
366
        if (lapb->callbacks.disconnect_indication != NULL)
367
                (lapb->callbacks.disconnect_indication)(lapb->token, reason);
368
}
369
 
370
int lapb_data_indication(lapb_cb *lapb, struct sk_buff *skb)
371
{
372
        if (lapb->callbacks.data_indication != NULL) {
373
                return (lapb->callbacks.data_indication)(lapb->token, skb);
374
        }
375
        kfree_skb(skb);
376
        return NET_RX_CN_HIGH; /* For now; must be != NET_RX_DROP */
377
}
378
 
379
int lapb_data_transmit(lapb_cb *lapb, struct sk_buff *skb)
380
{
381
        int used = 0;
382
 
383
        if (lapb->callbacks.data_transmit != NULL) {
384
                (lapb->callbacks.data_transmit)(lapb->token, skb);
385
                used = 1;
386
        }
387
 
388
        return used;
389
}
390
 
391
EXPORT_SYMBOL(lapb_register);
392
EXPORT_SYMBOL(lapb_unregister);
393
EXPORT_SYMBOL(lapb_getparms);
394
EXPORT_SYMBOL(lapb_setparms);
395
EXPORT_SYMBOL(lapb_connect_request);
396
EXPORT_SYMBOL(lapb_disconnect_request);
397
EXPORT_SYMBOL(lapb_data_request);
398
EXPORT_SYMBOL(lapb_data_received);
399
 
400
static char banner[] __initdata = KERN_INFO "NET4: LAPB for Linux. Version 0.01 for NET4.0\n";
401
 
402
static int __init lapb_init(void)
403
{
404
        printk(banner);
405
        return 0;
406
}
407
 
408
MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
409
MODULE_DESCRIPTION("The X.25 Link Access Procedure B link layer protocol");
410
MODULE_LICENSE("GPL");
411
 
412
module_init(lapb_init);

powered by: WebSVN 2.1.0

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