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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [s390/] [net/] [netiucv.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * $Id: netiucv.c,v 1.1.1.1 2004-04-15 02:05:58 phoenix Exp $
3
 *
4
 * IUCV network driver
5
 *
6
 * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
7
 * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
8
 *
9
 * Documentation used:
10
 *  the source of the original IUCV driver by:
11
 *    Stefan Hegewald <hegewald@de.ibm.com>
12
 *    Hartmut Penner <hpenner@de.ibm.com>
13
 *    Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
14
 *    Martin Schwidefsky (schwidefsky@de.ibm.com)
15
 *    Alan Altmark (Alan_Altmark@us.ibm.com)  Sept. 2000
16
 *
17
 * This program is free software; you can redistribute it and/or modify
18
 * it under the terms of the GNU General Public License as published by
19
 * the Free Software Foundation; either version 2, or (at your option)
20
 * any later version.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
 * GNU General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU General Public License
28
 * along with this program; if not, write to the Free Software
29
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30
 *
31
 * RELEASE-TAG: IUCV network driver $Revision: 1.1.1.1 $
32
 *
33
 */
34
 
35
#include <linux/version.h>
36
#include <linux/module.h>
37
#include <linux/init.h>
38
#include <linux/kernel.h>
39
#include <linux/slab.h>
40
#include <linux/errno.h>
41
#include <linux/types.h>
42
#include <linux/interrupt.h>
43
#include <linux/timer.h>
44
#include <linux/sched.h>
45
 
46
#include <linux/signal.h>
47
#include <linux/string.h>
48
#include <linux/proc_fs.h>
49
 
50
#include <linux/ip.h>
51
#include <linux/if_arp.h>
52
#include <linux/tcp.h>
53
#include <linux/skbuff.h>
54
#include <linux/ctype.h>
55
#include <net/dst.h>
56
 
57
#include <asm/io.h>
58
#include <asm/bitops.h>
59
#include <asm/uaccess.h>
60
 
61
#include "iucv.h"
62
#include "fsm.h"
63
 
64
#undef DEBUG
65
 
66
#ifdef MODULE
67
MODULE_AUTHOR
68
    ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)");
69
MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
70
MODULE_PARM (iucv, "1s");
71
MODULE_PARM_DESC (iucv,
72
                  "Specify the initial remote userids for iucv0 .. iucvn:\n"
73
                  "iucv=userid0:userid1:...:useridN");
74
#endif
75
 
76
static char *iucv = "";
77
 
78
/**
79
 * compatibility stuff
80
 */
81
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
82
typedef struct net_device net_device;
83
#else
84
typedef struct device net_device;
85
#endif
86
 
87
 
88
/**
89
 * Per connection profiling data
90
 */
91
typedef struct connection_profile_t {
92
        unsigned long maxmulti;
93
        unsigned long maxcqueue;
94
        unsigned long doios_single;
95
        unsigned long doios_multi;
96
        unsigned long txlen;
97
        unsigned long tx_time;
98
        struct timeval send_stamp;
99
        unsigned long tx_pending;
100
        unsigned long tx_max_pending;
101
} connection_profile;
102
 
103
/**
104
 * Representation of one iucv connection
105
 */
106
typedef struct iucv_connection_t {
107
        struct iucv_connection_t *next;
108
        iucv_handle_t            handle;
109
        __u16                    pathid;
110
        struct sk_buff           *rx_buff;
111
        struct sk_buff           *tx_buff;
112
        struct sk_buff_head      collect_queue;
113
        struct sk_buff_head      commit_queue;
114
        spinlock_t               collect_lock;
115
        int                      collect_len;
116
        int                      max_buffsize;
117
        int                      flags;
118
        fsm_timer                timer;
119
        int                      retry;
120
        fsm_instance             *fsm;
121
        net_device               *netdev;
122
        connection_profile       prof;
123
        char                     userid[9];
124
} iucv_connection;
125
 
126
#define CONN_FLAGS_BUFSIZE_CHANGED 1
127
 
128
/**
129
 * Linked list of all connection structs.
130
 */
131
iucv_connection *connections;
132
 
133
/**
134
 * Representation of event-data for the
135
 * connection state machine.
136
 */
137
typedef struct iucv_event_t {
138
        iucv_connection *conn;
139
        void            *data;
140
} iucv_event;
141
 
142
/**
143
 * Private part of the network device structure
144
 */
145
typedef struct netiucv_priv_t {
146
        struct net_device_stats stats;
147
#if LINUX_VERSION_CODE >= 0x02032D
148
        unsigned long           tbusy;
149
#endif
150
        fsm_instance            *fsm;
151
        iucv_connection         *conn;
152
        struct proc_dir_entry   *proc_dentry;
153
        struct proc_dir_entry   *proc_stat_entry;
154
        struct proc_dir_entry   *proc_buffer_entry;
155
        struct proc_dir_entry   *proc_user_entry;
156
        int                     proc_registered;
157
} netiucv_priv;
158
 
159
/**
160
 * Link level header for a packet.
161
 */
162
typedef struct ll_header_t {
163
        __u16 next;
164
} ll_header;
165
 
166
#define NETIUCV_HDRLEN           (sizeof(ll_header))
167
#define NETIUCV_BUFSIZE_MAX      32768
168
#define NETIUCV_BUFSIZE_DEFAULT  NETIUCV_BUFSIZE_MAX
169
#define NETIUCV_MTU_MAX          (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN)
170
#define NETIUCV_MTU_DEFAULT      9216
171
#define NETIUCV_QUEUELEN_DEFAULT 50
172
#define NETIUCV_TIMEOUT_5SEC     5000
173
 
174
/**
175
 * Compatibility macros for busy handling
176
 * of network devices.
177
 */
178
#if LINUX_VERSION_CODE < 0x02032D
179
static __inline__ void netiucv_clear_busy(net_device *dev)
180
{
181
        clear_bit(0 ,(void *)&dev->tbusy);
182
        mark_bh(NET_BH);
183
}
184
 
185
static __inline__ int netiucv_test_and_set_busy(net_device *dev)
186
{
187
        return(test_and_set_bit(0, (void *)&dev->tbusy));
188
}
189
 
190
#define SET_DEVICE_START(device, value) dev->start = value
191
#else
192
static __inline__ void netiucv_clear_busy(net_device *dev)
193
{
194
        clear_bit(0, &(((netiucv_priv *)dev->priv)->tbusy));
195
        netif_wake_queue(dev);
196
}
197
 
198
static __inline__ int netiucv_test_and_set_busy(net_device *dev)
199
{
200
        netif_stop_queue(dev);
201
        return test_and_set_bit(0, &((netiucv_priv *)dev->priv)->tbusy);
202
}
203
 
204
#define SET_DEVICE_START(device, value)
205
#endif
206
 
207
#if LINUX_VERSION_CODE < 0x020400
208
#  define dev_kfree_skb_irq(a) dev_kfree_skb(a)
209
#endif
210
 
211
__u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
212
__u8 iucvMagic[16] = {
213
        0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
214
        0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
215
};
216
 
217
/**
218
 * This mask means the 16-byte IUCV "magic" and the origin userid must
219
 * match exactly as specified in order to give connection_pending()
220
 * control.
221
 */
222
__u8 mask[] = {
223
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
224
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
225
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
226
};
227
 
228
/**
229
 * Convert an iucv userId to its printable
230
 * form (strip whitespace at end).
231
 *
232
 * @param An iucv userId
233
 *
234
 * @returns The printable string (static data!!)
235
 */
236
static __inline__ char *
237
netiucv_printname(char *name)
238
{
239
        static char tmp[9];
240
        char *p = tmp;
241
        memcpy(tmp, name, 8);
242
        tmp[8] = '\0';
243
        while (*p && (!isspace(*p)))
244
                p++;
245
        *p = '\0';
246
        return tmp;
247
}
248
 
249
/**
250
 * States of the interface statemachine.
251
 */
252
enum dev_states {
253
        DEV_STATE_STOPPED,
254
        DEV_STATE_STARTWAIT,
255
        DEV_STATE_STOPWAIT,
256
        DEV_STATE_RUNNING,
257
        /**
258
         * MUST be always the last element!!
259
         */
260
        NR_DEV_STATES
261
};
262
 
263
static const char *dev_state_names[] = {
264
        "Stopped",
265
        "StartWait",
266
        "StopWait",
267
        "Running",
268
};
269
 
270
/**
271
 * Events of the interface statemachine.
272
 */
273
enum dev_events {
274
        DEV_EVENT_START,
275
        DEV_EVENT_STOP,
276
        DEV_EVENT_CONUP,
277
        DEV_EVENT_CONDOWN,
278
        /**
279
         * MUST be always the last element!!
280
         */
281
        NR_DEV_EVENTS
282
};
283
 
284
static const char *dev_event_names[] = {
285
        "Start",
286
        "Stop",
287
        "Connection up",
288
        "Connection down",
289
};
290
 
291
/**
292
 * Events of the connection statemachine
293
 */
294
enum conn_events {
295
        /**
296
         * Events, representing callbacks from
297
         * lowlevel iucv layer)
298
         */
299
        CONN_EVENT_CONN_REQ,
300
        CONN_EVENT_CONN_ACK,
301
        CONN_EVENT_CONN_REJ,
302
        CONN_EVENT_CONN_SUS,
303
        CONN_EVENT_CONN_RES,
304
        CONN_EVENT_RX,
305
        CONN_EVENT_TXDONE,
306
 
307
        /**
308
         * Events, representing errors return codes from
309
         * calls to lowlevel iucv layer
310
         */
311
 
312
        /**
313
         * Event, representing timer expiry.
314
         */
315
        CONN_EVENT_TIMER,
316
 
317
        /**
318
         * Events, representing commands from upper levels.
319
         */
320
        CONN_EVENT_START,
321
        CONN_EVENT_STOP,
322
 
323
        /**
324
         * MUST be always the last element!!
325
         */
326
        NR_CONN_EVENTS,
327
};
328
 
329
static const char *conn_event_names[] = {
330
        "Remote connection request",
331
        "Remote connection acknowledge",
332
        "Remote connection reject",
333
        "Connection suspended",
334
        "Connection resumed",
335
        "Data received",
336
        "Data sent",
337
 
338
        "Timer",
339
 
340
        "Start",
341
        "Stop",
342
};
343
 
344
/**
345
 * States of the connection statemachine.
346
 */
347
enum conn_states {
348
        /**
349
         * Connection not assigned to any device,
350
         * initial state, invalid
351
         */
352
        CONN_STATE_INVALID,
353
 
354
        /**
355
         * Userid assigned but not operating
356
         */
357
        CONN_STATE_STOPPED,
358
 
359
        /**
360
         * Connection registered,
361
         * no connection request sent yet,
362
         * no connection request received
363
         */
364
        CONN_STATE_STARTWAIT,
365
 
366
        /**
367
         * Connection registered and connection request sent,
368
         * no acknowledge and no connection request received yet.
369
         */
370
        CONN_STATE_SETUPWAIT,
371
 
372
        /**
373
         * Connection up and running idle
374
         */
375
        CONN_STATE_IDLE,
376
 
377
        /**
378
         * Data sent, awaiting CONN_EVENT_TXDONE
379
         */
380
        CONN_STATE_TX,
381
 
382
        /**
383
         * Terminating
384
         */
385
        CONN_STATE_TERM,
386
 
387
        /**
388
         * Error during registration.
389
         */
390
        CONN_STATE_REGERR,
391
 
392
        /**
393
         * Error during registration.
394
         */
395
        CONN_STATE_CONNERR,
396
 
397
        /**
398
         * MUST be always the last element!!
399
         */
400
        NR_CONN_STATES,
401
};
402
 
403
static const char *conn_state_names[] = {
404
        "Invalid",
405
        "Stopped",
406
        "StartWait",
407
        "SetupWait",
408
        "Idle",
409
        "TX",
410
        "Terminating",
411
        "Registration error",
412
        "Connect error",
413
};
414
 
415
 
416
/**
417
 * Callback-wrappers, called from lowlevel iucv layer.
418
 *****************************************************************************/
419
 
420
static void
421
netiucv_callback_rx(iucv_MessagePending *eib, void *pgm_data)
422
{
423
        iucv_connection *conn = (iucv_connection *)pgm_data;
424
        iucv_event ev;
425
 
426
        ev.conn = conn;
427
        ev.data = (void *)eib;
428
 
429
        fsm_event(conn->fsm, CONN_EVENT_RX, &ev);
430
}
431
 
432
static void
433
netiucv_callback_txdone(iucv_MessageComplete *eib, void *pgm_data)
434
{
435
        iucv_connection *conn = (iucv_connection *)pgm_data;
436
        iucv_event ev;
437
 
438
        ev.conn = conn;
439
        ev.data = (void *)eib;
440
        fsm_event(conn->fsm, CONN_EVENT_TXDONE, &ev);
441
}
442
 
443
static void
444
netiucv_callback_connack(iucv_ConnectionComplete *eib, void *pgm_data)
445
{
446
        iucv_connection *conn = (iucv_connection *)pgm_data;
447
        iucv_event ev;
448
 
449
#ifdef DEBUG
450
        printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
451
#endif
452
 
453
        ev.conn = conn;
454
        ev.data = (void *)eib;
455
        fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, &ev);
456
}
457
 
458
static void
459
netiucv_callback_connreq(iucv_ConnectionPending *eib, void *pgm_data)
460
{
461
        iucv_connection *conn = (iucv_connection *)pgm_data;
462
        iucv_event ev;
463
 
464
        ev.conn = conn;
465
        ev.data = (void *)eib;
466
        fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev);
467
}
468
 
469
static void
470
netiucv_callback_connrej(iucv_ConnectionSevered *eib, void *pgm_data)
471
{
472
        iucv_connection *conn = (iucv_connection *)pgm_data;
473
        iucv_event ev;
474
 
475
        ev.conn = conn;
476
        ev.data = (void *)eib;
477
        fsm_event(conn->fsm, CONN_EVENT_CONN_REJ, &ev);
478
}
479
 
480
static void
481
netiucv_callback_connsusp(iucv_ConnectionQuiesced *eib, void *pgm_data)
482
{
483
        iucv_connection *conn = (iucv_connection *)pgm_data;
484
        iucv_event ev;
485
 
486
        ev.conn = conn;
487
        ev.data = (void *)eib;
488
        fsm_event(conn->fsm, CONN_EVENT_CONN_SUS, &ev);
489
}
490
 
491
static void
492
netiucv_callback_connres(iucv_ConnectionResumed *eib, void *pgm_data)
493
{
494
        iucv_connection *conn = (iucv_connection *)pgm_data;
495
        iucv_event ev;
496
 
497
        ev.conn = conn;
498
        ev.data = (void *)eib;
499
        fsm_event(conn->fsm, CONN_EVENT_CONN_RES, &ev);
500
}
501
 
502
static iucv_interrupt_ops_t netiucv_ops = {
503
        ConnectionPending:  netiucv_callback_connreq,
504
        ConnectionComplete: netiucv_callback_connack,
505
        ConnectionSevered:  netiucv_callback_connrej,
506
        ConnectionQuiesced: netiucv_callback_connsusp,
507
        ConnectionResumed:  netiucv_callback_connres,
508
        MessagePending:     netiucv_callback_rx,
509
        MessageComplete:    netiucv_callback_txdone
510
};
511
 
512
/**
513
 * Dummy NOP action for all statemachines
514
 */
515
static void
516
fsm_action_nop(fsm_instance *fi, int event, void *arg)
517
{
518
}
519
 
520
/**
521
 * Actions of the connection statemachine
522
 *****************************************************************************/
523
 
524
/**
525
 * Helper function for conn_action_rx()
526
 * Unpack a just received skb and hand it over to
527
 * upper layers.
528
 *
529
 * @param conn The connection where this skb has been received.
530
 * @param pskb The received skb.
531
 */
532
//static __inline__ void
533
static void
534
netiucv_unpack_skb(iucv_connection *conn, struct sk_buff *pskb)
535
{
536
        net_device     *dev = conn->netdev;
537
        netiucv_priv   *privptr = (netiucv_priv *)dev->priv;
538
        __u16          offset = 0;
539
 
540
        skb_put(pskb, NETIUCV_HDRLEN);
541
        pskb->dev = dev;
542
        pskb->ip_summed = CHECKSUM_NONE;
543
        pskb->protocol = ntohs(ETH_P_IP);
544
 
545
        while (1) {
546
                struct sk_buff *skb;
547
                ll_header *header = (ll_header *)pskb->data;
548
 
549
                if (header->next == 0)
550
                        break;
551
 
552
                skb_pull(pskb, NETIUCV_HDRLEN);
553
                header->next -= offset;
554
                offset += header->next;
555
                header->next -= NETIUCV_HDRLEN;
556
                if (skb_tailroom(pskb) < header->next) {
557
                        printk(KERN_WARNING
558
                               "%s: Illegal next field in iucv header: %d > %d\n",
559
                               dev->name, header->next, skb_tailroom(pskb));
560
                        return;
561
                }
562
                skb_put(pskb, header->next);
563
                pskb->mac.raw = pskb->data;
564
                skb = dev_alloc_skb(pskb->len);
565
                if (!skb) {
566
                        printk(KERN_WARNING
567
                               "%s Out of memory in netiucv_unpack_skb\n",
568
                               dev->name);
569
                        privptr->stats.rx_dropped++;
570
                        return;
571
                }
572
                memcpy(skb_put(skb, pskb->len), pskb->data, pskb->len);
573
                skb->mac.raw = skb->data;
574
                skb->dev = pskb->dev;
575
                skb->protocol = pskb->protocol;
576
                pskb->ip_summed = CHECKSUM_UNNECESSARY;
577
                netif_rx(skb);
578
                privptr->stats.rx_packets++;
579
                privptr->stats.rx_bytes += skb->len;
580
                skb_pull(pskb, header->next);
581
                skb_put(pskb, NETIUCV_HDRLEN);
582
        }
583
}
584
 
585
static void
586
conn_action_rx(fsm_instance *fi, int event, void *arg)
587
{
588
        iucv_event *ev = (iucv_event *)arg;
589
        iucv_connection *conn = ev->conn;
590
        iucv_MessagePending *eib = (iucv_MessagePending *)ev->data;
591
        netiucv_priv *privptr = (netiucv_priv *)conn->netdev->priv;
592
 
593
        __u16 msglen = eib->ln1msg2.ipbfln1f;
594
        int rc;
595
 
596
#ifdef DEBUG
597
        printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
598
#endif
599
        if (!conn->netdev) {
600
                /* FRITZ: How to tell iucv LL to drop the msg? */
601
                printk(KERN_WARNING
602
                       "Received data for unlinked connection\n");
603
                return;
604
        }
605
        if (msglen > conn->max_buffsize) {
606
                /* FRITZ: How to tell iucv LL to drop the msg? */
607
                privptr->stats.rx_dropped++;
608
                return;
609
        }
610
        conn->rx_buff->data = conn->rx_buff->tail = conn->rx_buff->head;
611
        conn->rx_buff->len = 0;
612
        rc = iucv_receive(conn->pathid, eib->ipmsgid, eib->iptrgcls,
613
                          conn->rx_buff->data, msglen, NULL, NULL, NULL);
614
        if (rc != 0 || msglen < 5) {
615
                privptr->stats.rx_errors++;
616
                return;
617
        }
618
        netiucv_unpack_skb(conn, conn->rx_buff);
619
}
620
 
621
static void
622
conn_action_txdone(fsm_instance *fi, int event, void *arg)
623
{
624
        iucv_event *ev = (iucv_event *)arg;
625
        iucv_connection *conn = ev->conn;
626
        iucv_MessageComplete *eib = (iucv_MessageComplete *)ev->data;
627
        netiucv_priv *privptr = NULL;
628
                                 /* Shut up, gcc! skb is always below 2G. */
629
        __u32 single_flag = eib->ipmsgtag;
630
        __u32 txbytes = 0;
631
        __u32 txpackets = 0;
632
        __u32 stat_maxcq = 0;
633
        struct sk_buff *skb;
634
        unsigned long saveflags;
635
        ll_header header;
636
 
637
#ifdef DEBUG
638
        printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
639
#endif
640
        fsm_deltimer(&conn->timer);
641
        if (conn && conn->netdev && conn->netdev->priv)
642
                privptr = (netiucv_priv *)conn->netdev->priv;
643
        conn->prof.tx_pending--;
644
        if (single_flag) {
645
                if ((skb = skb_dequeue(&conn->commit_queue))) {
646
                        atomic_dec(&skb->users);
647
                        dev_kfree_skb_any(skb);
648
                }
649
                if (privptr) {
650
                        privptr->stats.tx_packets++;
651
                        privptr->stats.tx_bytes +=
652
                                (skb->len - NETIUCV_HDRLEN - NETIUCV_HDRLEN);
653
                }
654
        }
655
        conn->tx_buff->data = conn->tx_buff->tail = conn->tx_buff->head;
656
        conn->tx_buff->len = 0;
657
        spin_lock_irqsave(&conn->collect_lock, saveflags);
658
        while ((skb = skb_dequeue(&conn->collect_queue))) {
659
                header.next = conn->tx_buff->len + skb->len + NETIUCV_HDRLEN;
660
                memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header,
661
                       NETIUCV_HDRLEN);
662
                memcpy(skb_put(conn->tx_buff, skb->len), skb->data, skb->len);
663
                txbytes += skb->len;
664
                txpackets++;
665
                stat_maxcq++;
666
                atomic_dec(&skb->users);
667
                dev_kfree_skb_any(skb);
668
        }
669
        if (conn->collect_len > conn->prof.maxmulti)
670
                conn->prof.maxmulti = conn->collect_len;
671
        conn->collect_len = 0;
672
        spin_unlock_irqrestore(&conn->collect_lock, saveflags);
673
        if (conn->tx_buff->len) {
674
                int rc;
675
 
676
                header.next = 0;
677
                memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header,
678
                       NETIUCV_HDRLEN);
679
 
680
                fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC,
681
                             CONN_EVENT_TIMER, conn);
682
                conn->prof.send_stamp = xtime;
683
                rc = iucv_send(conn->pathid, NULL, 0, 0, 0, 0,
684
                               conn->tx_buff->data, conn->tx_buff->len);
685
                conn->prof.doios_multi++;
686
                conn->prof.txlen += conn->tx_buff->len;
687
                conn->prof.tx_pending++;
688
                if (conn->prof.tx_pending > conn->prof.tx_max_pending)
689
                        conn->prof.tx_max_pending = conn->prof.tx_pending;
690
                if (rc != 0) {
691
                        fsm_deltimer(&conn->timer);
692
                        conn->prof.tx_pending--;
693
                        fsm_newstate(fi, CONN_STATE_IDLE);
694
                        if (privptr)
695
                                privptr->stats.tx_errors += txpackets;
696
                        printk(KERN_DEBUG "iucv_send returned %08x\n",
697
                               rc);
698
                } else {
699
                        if (privptr) {
700
                                privptr->stats.tx_packets += txpackets;
701
                                privptr->stats.tx_bytes += txbytes;
702
                        }
703
                        if (stat_maxcq > conn->prof.maxcqueue)
704
                                conn->prof.maxcqueue = stat_maxcq;
705
                }
706
        } else
707
                fsm_newstate(fi, CONN_STATE_IDLE);
708
}
709
 
710
static void
711
conn_action_connaccept(fsm_instance *fi, int event, void *arg)
712
{
713
        iucv_event *ev = (iucv_event *)arg;
714
        iucv_connection *conn = ev->conn;
715
        iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data;
716
        net_device *netdev = conn->netdev;
717
        netiucv_priv *privptr = (netiucv_priv *)netdev->priv;
718
        int rc;
719
        __u16 msglimit;
720
        __u8 udata[16];
721
 
722
#ifdef DEBUG
723
        printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
724
#endif
725
        rc = iucv_accept(eib->ippathid, NETIUCV_QUEUELEN_DEFAULT, udata, 0,
726
                         conn->handle, conn, NULL, &msglimit);
727
        if (rc != 0) {
728
                printk(KERN_WARNING
729
                       "%s: IUCV accept failed with error %d\n",
730
                       netdev->name, rc);
731
                return;
732
        }
733
        fsm_newstate(fi, CONN_STATE_IDLE);
734
        conn->pathid = eib->ippathid;
735
        netdev->tx_queue_len = msglimit;
736
        fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev);
737
}
738
 
739
static void
740
conn_action_connreject(fsm_instance *fi, int event, void *arg)
741
{
742
        iucv_event *ev = (iucv_event *)arg;
743
        // iucv_connection *conn = ev->conn;
744
        iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data;
745
        __u8 udata[16];
746
 
747
#ifdef DEBUG
748
        printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
749
#endif
750
        iucv_sever(eib->ippathid, udata);
751
}
752
 
753
static void
754
conn_action_connack(fsm_instance *fi, int event, void *arg)
755
{
756
        iucv_event *ev = (iucv_event *)arg;
757
        iucv_connection *conn = ev->conn;
758
        iucv_ConnectionComplete *eib = (iucv_ConnectionComplete *)ev->data;
759
        net_device *netdev = conn->netdev;
760
        netiucv_priv *privptr = (netiucv_priv *)netdev->priv;
761
 
762
#ifdef DEBUG
763
        printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
764
#endif
765
        fsm_newstate(fi, CONN_STATE_IDLE);
766
        conn->pathid = eib->ippathid;
767
        netdev->tx_queue_len = eib->ipmsglim;
768
        fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev);
769
}
770
 
771
static void
772
conn_action_connsever(fsm_instance *fi, int event, void *arg)
773
{
774
        iucv_event *ev = (iucv_event *)arg;
775
        iucv_connection *conn = ev->conn;
776
        // iucv_ConnectionSevered *eib = (iucv_ConnectionSevered *)ev->data;
777
        net_device *netdev = conn->netdev;
778
        netiucv_priv *privptr = (netiucv_priv *)netdev->priv;
779
        int state = fsm_getstate(fi);
780
 
781
#ifdef DEBUG
782
        printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
783
#endif
784
        switch (state) {
785
                case CONN_STATE_SETUPWAIT:
786
                        printk(KERN_INFO "%s: Remote dropped connection\n",
787
                               netdev->name);
788
                        conn->handle = 0;
789
                        fsm_newstate(fi, CONN_STATE_STOPPED);
790
                        fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);
791
                        break;
792
                case CONN_STATE_IDLE:
793
                case CONN_STATE_TX:
794
                        printk(KERN_INFO "%s: Remote dropped connection\n",
795
                               netdev->name);
796
                        if (conn->handle)
797
                                iucv_unregister_program(conn->handle);
798
                        conn->handle = 0;
799
                        fsm_newstate(fi, CONN_STATE_STOPPED);
800
                        fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);
801
                        break;
802
        }
803
}
804
 
805
static void
806
conn_action_start(fsm_instance *fi, int event, void *arg)
807
{
808
        iucv_event *ev = (iucv_event *)arg;
809
        iucv_connection *conn = ev->conn;
810
 
811
        int rc;
812
 
813
#ifdef DEBUG
814
        printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
815
#endif
816
        if (conn->handle == 0) {
817
                conn->handle =
818
                        iucv_register_program(iucvMagic, conn->userid, mask,
819
                                              &netiucv_ops, conn);
820
                fsm_newstate(fi, CONN_STATE_STARTWAIT);
821
                if (conn->handle <= 0) {
822
                        fsm_newstate(fi, CONN_STATE_REGERR);
823
                        conn->handle = 0;
824
                        return;
825
                }
826
#ifdef DEBUG
827
                printk(KERN_DEBUG "%s('%s'): registered successfully\n",
828
                       conn->netdev->name, conn->userid);
829
#endif
830
        }
831
#ifdef DEBUG
832
        printk(KERN_DEBUG "%s('%s'): connecting ...\n",
833
               conn->netdev->name, conn->userid);
834
#endif
835
 
836
        /* We must set the state before calling iucv_connect because the callback
837
         * handler could be called at any point after the connection request is
838
         * sent. */
839
 
840
        fsm_newstate(fi, CONN_STATE_SETUPWAIT);
841
        rc = iucv_connect(&(conn->pathid), NETIUCV_QUEUELEN_DEFAULT, iucvMagic,
842
                          conn->userid, iucv_host, 0, NULL, NULL, conn->handle,
843
                          conn);
844
        switch (rc) {
845
                case 0:
846
                        return;
847
                case 11:
848
                        printk(KERN_NOTICE
849
                               "%s: User %s is currently not available.\n",
850
                               conn->netdev->name,
851
                               netiucv_printname(conn->userid));
852
                        fsm_newstate(fi, CONN_STATE_STARTWAIT);
853
                        return;
854
                case 12:
855
                        printk(KERN_NOTICE
856
                               "%s: User %s is currently not ready.\n",
857
                               conn->netdev->name,
858
                               netiucv_printname(conn->userid));
859
                        fsm_newstate(fi, CONN_STATE_STARTWAIT);
860
                        return;
861
                case 13:
862
                        printk(KERN_WARNING
863
                               "%s: Too many IUCV connections.\n",
864
                               conn->netdev->name);
865
                        fsm_newstate(fi, CONN_STATE_CONNERR);
866
                        break;
867
                case 14:
868
                        printk(KERN_WARNING
869
                               "%s: User %s has too many IUCV connections.\n",
870
                               conn->netdev->name,
871
                               netiucv_printname(conn->userid));
872
                        fsm_newstate(fi, CONN_STATE_CONNERR);
873
                        break;
874
                case 15:
875
                        printk(KERN_WARNING
876
                               "%s: No IUCV authorization in CP directory.\n",
877
                               conn->netdev->name);
878
                        fsm_newstate(fi, CONN_STATE_CONNERR);
879
                        break;
880
                default:
881
                        printk(KERN_WARNING
882
                               "%s: iucv_connect returned error %d\n",
883
                               conn->netdev->name, rc);
884
                        fsm_newstate(fi, CONN_STATE_CONNERR);
885
                        break;
886
        }
887
        iucv_unregister_program(conn->handle);
888
        conn->handle = 0;
889
}
890
 
891
static void
892
netiucv_purge_skb_queue(struct sk_buff_head *q)
893
{
894
        struct sk_buff *skb;
895
 
896
        while ((skb = skb_dequeue(q))) {
897
                atomic_dec(&skb->users);
898
                dev_kfree_skb_any(skb);
899
        }
900
}
901
 
902
static void
903
conn_action_stop(fsm_instance *fi, int event, void *arg)
904
{
905
        iucv_event *ev = (iucv_event *)arg;
906
        iucv_connection *conn = ev->conn;
907
        net_device *netdev = conn->netdev;
908
        netiucv_priv *privptr = (netiucv_priv *)netdev->priv;
909
 
910
#ifdef DEBUG
911
        printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
912
#endif
913
        fsm_newstate(fi, CONN_STATE_STOPPED);
914
        netiucv_purge_skb_queue(&conn->collect_queue);
915
        if (conn->handle)
916
                iucv_unregister_program(conn->handle);
917
        conn->handle = 0;
918
        netiucv_purge_skb_queue(&conn->commit_queue);
919
        fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);
920
}
921
 
922
static void
923
conn_action_inval(fsm_instance *fi, int event, void *arg)
924
{
925
        iucv_event *ev = (iucv_event *)arg;
926
        iucv_connection *conn = ev->conn;
927
        net_device *netdev = conn->netdev;
928
 
929
        printk(KERN_WARNING
930
               "%s: Cannot connect without username\n",
931
               netdev->name);
932
}
933
 
934
static const fsm_node conn_fsm[] = {
935
        { CONN_STATE_INVALID,   CONN_EVENT_START,    conn_action_inval      },
936
        { CONN_STATE_STOPPED,   CONN_EVENT_START,    conn_action_start      },
937
        { CONN_STATE_STARTWAIT, CONN_EVENT_START,    conn_action_start      },
938
 
939
        { CONN_STATE_STARTWAIT, CONN_EVENT_STOP,     conn_action_stop       },
940
        { CONN_STATE_SETUPWAIT, CONN_EVENT_STOP,     conn_action_stop       },
941
        { CONN_STATE_IDLE,      CONN_EVENT_STOP,     conn_action_stop       },
942
        { CONN_STATE_TX,        CONN_EVENT_STOP,     conn_action_stop       },
943
        { CONN_STATE_REGERR,    CONN_EVENT_STOP,     conn_action_stop       },
944
        { CONN_STATE_CONNERR,   CONN_EVENT_STOP,     conn_action_stop       },
945
 
946
        { CONN_STATE_STOPPED,   CONN_EVENT_CONN_REQ, conn_action_connreject },
947
        { CONN_STATE_STARTWAIT, CONN_EVENT_CONN_REQ, conn_action_connaccept },
948
        { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_REQ, conn_action_connaccept },
949
        { CONN_STATE_IDLE,      CONN_EVENT_CONN_REQ, conn_action_connreject },
950
        { CONN_STATE_TX,        CONN_EVENT_CONN_REQ, conn_action_connreject },
951
 
952
        { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_ACK, conn_action_connack    },
953
 
954
        { CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_REJ, conn_action_connsever  },
955
        { CONN_STATE_IDLE,      CONN_EVENT_CONN_REJ, conn_action_connsever  },
956
        { CONN_STATE_TX,        CONN_EVENT_CONN_REJ, conn_action_connsever  },
957
 
958
        { CONN_STATE_IDLE,      CONN_EVENT_RX,       conn_action_rx         },
959
        { CONN_STATE_TX,        CONN_EVENT_RX,       conn_action_rx         },
960
 
961
        { CONN_STATE_TX,        CONN_EVENT_TXDONE,   conn_action_txdone     },
962
        { CONN_STATE_IDLE,      CONN_EVENT_TXDONE,   conn_action_txdone     },
963
};
964
 
965
static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node);
966
 
967
 
968
/**
969
 * Actions for interface - statemachine.
970
 *****************************************************************************/
971
 
972
/**
973
 * Startup connection by sending CONN_EVENT_START to it.
974
 *
975
 * @param fi    An instance of an interface statemachine.
976
 * @param event The event, just happened.
977
 * @param arg   Generic pointer, casted from net_device * upon call.
978
 */
979
static void
980
dev_action_start(fsm_instance *fi, int event, void *arg)
981
{
982
        net_device   *dev = (net_device *)arg;
983
        netiucv_priv *privptr = dev->priv;
984
        iucv_event   ev;
985
 
986
#ifdef DEBUG
987
        printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
988
#endif
989
        ev.conn = privptr->conn;
990
        fsm_newstate(fi, DEV_STATE_STARTWAIT);
991
        fsm_event(privptr->conn->fsm, CONN_EVENT_START, &ev);
992
}
993
 
994
/**
995
 * Shutdown connection by sending CONN_EVENT_STOP to it.
996
 *
997
 * @param fi    An instance of an interface statemachine.
998
 * @param event The event, just happened.
999
 * @param arg   Generic pointer, casted from net_device * upon call.
1000
 */
1001
static void
1002
dev_action_stop(fsm_instance *fi, int event, void *arg)
1003
{
1004
        net_device   *dev = (net_device *)arg;
1005
        netiucv_priv *privptr = dev->priv;
1006
        iucv_event   ev;
1007
 
1008
#ifdef DEBUG
1009
        printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
1010
#endif
1011
        ev.conn = privptr->conn;
1012
 
1013
        fsm_newstate(fi, DEV_STATE_STOPWAIT);
1014
        fsm_event(privptr->conn->fsm, CONN_EVENT_STOP, &ev);
1015
}
1016
 
1017
/**
1018
 * Called from connection statemachine
1019
 * when a connection is up and running.
1020
 *
1021
 * @param fi    An instance of an interface statemachine.
1022
 * @param event The event, just happened.
1023
 * @param arg   Generic pointer, casted from net_device * upon call.
1024
 */
1025
static void
1026
dev_action_connup(fsm_instance *fi, int event, void *arg)
1027
{
1028
        net_device   *dev = (net_device *)arg;
1029
 
1030
#ifdef DEBUG
1031
        printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
1032
#endif
1033
        switch (fsm_getstate(fi)) {
1034
                case DEV_STATE_STARTWAIT:
1035
                        fsm_newstate(fi, DEV_STATE_RUNNING);
1036
                        printk(KERN_INFO
1037
                               "%s: connected with remote side\n",
1038
                               dev->name);
1039
                        break;
1040
                case DEV_STATE_STOPWAIT:
1041
                        printk(KERN_INFO
1042
                               "%s: got connection UP event during shutdown!!\n",
1043
                               dev->name);
1044
                        break;
1045
        }
1046
}
1047
 
1048
/**
1049
 * Called from connection statemachine
1050
 * when a connection has been shutdown.
1051
 *
1052
 * @param fi    An instance of an interface statemachine.
1053
 * @param event The event, just happened.
1054
 * @param arg   Generic pointer, casted from net_device * upon call.
1055
 */
1056
static void
1057
dev_action_conndown(fsm_instance *fi, int event, void *arg)
1058
{
1059
        net_device   *dev = (net_device *)arg;
1060
        netiucv_priv *privptr = dev->priv;
1061
        iucv_event   ev;
1062
 
1063
#ifdef DEBUG
1064
        printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
1065
#endif
1066
        switch (fsm_getstate(fi)) {
1067
                case DEV_STATE_RUNNING:
1068
                        fsm_newstate(fi, DEV_STATE_STARTWAIT);
1069
                        ev.conn = privptr->conn;
1070
                        fsm_event(privptr->conn->fsm, CONN_EVENT_START, &ev);
1071
                        break;
1072
                case DEV_STATE_STARTWAIT:
1073
                        break;
1074
                case DEV_STATE_STOPWAIT:
1075
                        fsm_newstate(fi, DEV_STATE_STOPPED);
1076
                        break;
1077
        }
1078
}
1079
 
1080
static const fsm_node dev_fsm[] = {
1081
        { DEV_STATE_STOPPED,   DEV_EVENT_START,   dev_action_start    },
1082
 
1083
        { DEV_STATE_STOPWAIT,  DEV_EVENT_START,   dev_action_start    },
1084
        { DEV_STATE_STOPWAIT,  DEV_EVENT_CONDOWN, dev_action_conndown },
1085
 
1086
        { DEV_STATE_STARTWAIT, DEV_EVENT_STOP,    dev_action_stop     },
1087
        { DEV_STATE_STARTWAIT, DEV_EVENT_CONUP,   dev_action_connup   },
1088
        { DEV_STATE_STARTWAIT, DEV_EVENT_CONDOWN, dev_action_conndown },
1089
 
1090
        { DEV_STATE_RUNNING,   DEV_EVENT_STOP,    dev_action_stop     },
1091
        { DEV_STATE_RUNNING,   DEV_EVENT_CONDOWN, dev_action_conndown },
1092
        { DEV_STATE_RUNNING,   DEV_EVENT_CONUP,   fsm_action_nop      },
1093
};
1094
 
1095
static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node);
1096
 
1097
/**
1098
 * Transmit a packet.
1099
 * This is a helper function for netiucv_tx().
1100
 *
1101
 * @param conn Connection to be used for sending.
1102
 * @param skb Pointer to struct sk_buff of packet to send.
1103
 *            The linklevel header has already been set up
1104
 *            by netiucv_tx().
1105
 *
1106
 * @return 0 on success, -ERRNO on failure. (Never fails.)
1107
 */
1108
static int
1109
netiucv_transmit_skb(iucv_connection *conn, struct sk_buff *skb) {
1110
        unsigned long saveflags;
1111
        ll_header header;
1112
        int       rc = 0;
1113
 
1114
        if (fsm_getstate(conn->fsm) != CONN_STATE_IDLE) {
1115
                int l = skb->len + NETIUCV_HDRLEN;
1116
 
1117
                spin_lock_irqsave(&conn->collect_lock, saveflags);
1118
                if (conn->collect_len + l >
1119
                    (conn->max_buffsize - NETIUCV_HDRLEN))
1120
                        rc = -EBUSY;
1121
                else {
1122
                        atomic_inc(&skb->users);
1123
                        skb_queue_tail(&conn->collect_queue, skb);
1124
                        conn->collect_len += l;
1125
                }
1126
                spin_unlock_irqrestore(&conn->collect_lock, saveflags);
1127
        } else {
1128
                struct sk_buff *nskb = skb;
1129
                /**
1130
                 * Copy the skb to a new allocated skb in lowmem only if the
1131
                 * data is located above 2G in memory or tailroom is < 2.
1132
                 */
1133
                unsigned long hi =
1134
                        ((unsigned long)(skb->tail + NETIUCV_HDRLEN)) >> 31;
1135
                int copied = 0;
1136
                if (hi || (skb_tailroom(skb) < 2)) {
1137
                        nskb = alloc_skb(skb->len + NETIUCV_HDRLEN +
1138
                                         NETIUCV_HDRLEN, GFP_ATOMIC | GFP_DMA);
1139
                        if (!nskb) {
1140
                                printk(KERN_WARNING
1141
                                       "%s: Could not allocate tx_skb\n",
1142
                                       conn->netdev->name);
1143
                                rc = -ENOMEM;
1144
                        } else {
1145
                                skb_reserve(nskb, NETIUCV_HDRLEN);
1146
                                memcpy(skb_put(nskb, skb->len),
1147
                                       skb->data, skb->len);
1148
                        }
1149
                        copied = 1;
1150
                }
1151
                /**
1152
                 * skb now is below 2G and has enough room. Add headers.
1153
                 */
1154
                header.next = nskb->len + NETIUCV_HDRLEN;
1155
                memcpy(skb_push(nskb, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN);
1156
                header.next = 0;
1157
                memcpy(skb_put(nskb, NETIUCV_HDRLEN), &header,  NETIUCV_HDRLEN);
1158
 
1159
                conn->retry = 0;
1160
                fsm_newstate(conn->fsm, CONN_STATE_TX);
1161
                fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC,
1162
                             CONN_EVENT_TIMER, conn);
1163
                conn->prof.send_stamp = xtime;
1164
 
1165
                rc = iucv_send(conn->pathid, NULL, 0, 0, 1 /* single_flag */,
1166
                               0, nskb->data, nskb->len);
1167
                conn->prof.doios_single++;
1168
                conn->prof.txlen += skb->len;
1169
                conn->prof.tx_pending++;
1170
                if (conn->prof.tx_pending > conn->prof.tx_max_pending)
1171
                        conn->prof.tx_max_pending = conn->prof.tx_pending;
1172
                if (rc != 0) {
1173
                        netiucv_priv *privptr;
1174
                        fsm_deltimer(&conn->timer);
1175
                        fsm_newstate(conn->fsm, CONN_STATE_IDLE);
1176
                        conn->prof.tx_pending--;
1177
                        privptr = (netiucv_priv *)conn->netdev->priv;
1178
                        if (privptr)
1179
                                privptr->stats.tx_errors++;
1180
                        if (copied)
1181
                                dev_kfree_skb(nskb);
1182
                        else {
1183
                                /**
1184
                                 * Remove our headers. They get added
1185
                                 * again on retransmit.
1186
                                 */
1187
                                skb_pull(skb, NETIUCV_HDRLEN);
1188
                                skb_trim(skb, skb->len - NETIUCV_HDRLEN);
1189
                        }
1190
                        printk(KERN_DEBUG "iucv_send returned %08x\n",
1191
                               rc);
1192
                } else {
1193
                        if (copied)
1194
                                dev_kfree_skb(skb);
1195
                        atomic_inc(&nskb->users);
1196
                        skb_queue_tail(&conn->commit_queue, nskb);
1197
                }
1198
        }
1199
 
1200
        return rc;
1201
}
1202
 
1203
/**
1204
 * Interface API for upper network layers
1205
 *****************************************************************************/
1206
 
1207
/**
1208
 * Open an interface.
1209
 * Called from generic network layer when ifconfig up is run.
1210
 *
1211
 * @param dev Pointer to interface struct.
1212
 *
1213
 * @return 0 on success, -ERRNO on failure. (Never fails.)
1214
 */
1215
static int
1216
netiucv_open(net_device *dev) {
1217
        MOD_INC_USE_COUNT;
1218
        SET_DEVICE_START(dev, 1);
1219
        fsm_event(((netiucv_priv *)dev->priv)->fsm, DEV_EVENT_START, dev);
1220
        return 0;
1221
}
1222
 
1223
/**
1224
 * Close an interface.
1225
 * Called from generic network layer when ifconfig down is run.
1226
 *
1227
 * @param dev Pointer to interface struct.
1228
 *
1229
 * @return 0 on success, -ERRNO on failure. (Never fails.)
1230
 */
1231
static int
1232
netiucv_close(net_device *dev) {
1233
        SET_DEVICE_START(dev, 0);
1234
        fsm_event(((netiucv_priv *)dev->priv)->fsm, DEV_EVENT_STOP, dev);
1235
        MOD_DEC_USE_COUNT;
1236
        return 0;
1237
}
1238
 
1239
/**
1240
 * Start transmission of a packet.
1241
 * Called from generic network device layer.
1242
 *
1243
 * @param skb Pointer to buffer containing the packet.
1244
 * @param dev Pointer to interface struct.
1245
 *
1246
 * @return 0 if packet consumed, !0 if packet rejected.
1247
 *         Note: If we return !0, then the packet is free'd by
1248
 *               the generic network layer.
1249
 */
1250
static int netiucv_tx(struct sk_buff *skb, net_device *dev)
1251
{
1252
        int          rc = 0;
1253
        netiucv_priv *privptr = (netiucv_priv *)dev->priv;
1254
 
1255
        /**
1256
         * Some sanity checks ...
1257
         */
1258
        if (skb == NULL) {
1259
                printk(KERN_WARNING "%s: NULL sk_buff passed\n", dev->name);
1260
                privptr->stats.tx_dropped++;
1261
                return 0;
1262
        }
1263
        if (skb_headroom(skb) < (NETIUCV_HDRLEN)) {
1264
                printk(KERN_WARNING
1265
                       "%s: Got sk_buff with head room < %ld bytes\n",
1266
                       dev->name, NETIUCV_HDRLEN);
1267
                dev_kfree_skb(skb);
1268
                privptr->stats.tx_dropped++;
1269
                return 0;
1270
        }
1271
 
1272
        /**
1273
         * If connection is not running, try to restart it
1274
         * notify anybody about a link failure and throw
1275
         * away packet.
1276
         */
1277
        if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {
1278
                fsm_event(privptr->fsm, DEV_EVENT_START, dev);
1279
                dst_link_failure(skb);
1280
                dev_kfree_skb(skb);
1281
                privptr->stats.tx_dropped++;
1282
                privptr->stats.tx_errors++;
1283
                privptr->stats.tx_carrier_errors++;
1284
                return 0;
1285
        }
1286
 
1287
        if (netiucv_test_and_set_busy(dev))
1288
                return -EBUSY;
1289
 
1290
        dev->trans_start = jiffies;
1291
        if (netiucv_transmit_skb(privptr->conn, skb) != 0)
1292
                rc = 1;
1293
        netiucv_clear_busy(dev);
1294
        return rc;
1295
}
1296
 
1297
/**
1298
 * Returns interface statistics of a device.
1299
 *
1300
 * @param dev Pointer to interface struct.
1301
 *
1302
 * @return Pointer to stats struct of this interface.
1303
 */
1304
static struct net_device_stats *
1305
netiucv_stats (net_device * dev)
1306
{
1307
        return &((netiucv_priv *)dev->priv)->stats;
1308
}
1309
 
1310
/**
1311
 * Sets MTU of an interface.
1312
 *
1313
 * @param dev     Pointer to interface struct.
1314
 * @param new_mtu The new MTU to use for this interface.
1315
 *
1316
 * @return 0 on success, -EINVAL if MTU is out of valid range.
1317
 *         (valid range is 576 .. NETIUCV_MTU_MAX).
1318
 */
1319
static int
1320
netiucv_change_mtu (net_device * dev, int new_mtu)
1321
{
1322
        if ((new_mtu < 576) || (new_mtu > NETIUCV_MTU_MAX))
1323
                return -EINVAL;
1324
        dev->mtu = new_mtu;
1325
        return 0;
1326
}
1327
 
1328
 
1329
/**
1330
 * procfs related structures and routines
1331
 *****************************************************************************/
1332
 
1333
static net_device *
1334
find_netdev_by_ino(unsigned long ino)
1335
{
1336
        iucv_connection *conn = connections;
1337
        net_device *dev = NULL;
1338
        netiucv_priv *privptr;
1339
 
1340
        while (conn) {
1341
                if (conn->netdev != dev) {
1342
                        dev = conn->netdev;
1343
                        privptr = (netiucv_priv *)dev->priv;
1344
 
1345
                        if ((privptr->proc_buffer_entry->low_ino == ino) ||
1346
                            (privptr->proc_user_entry->low_ino == ino)   ||
1347
                            (privptr->proc_stat_entry->low_ino == ino)     )
1348
                                return dev;
1349
                }
1350
                conn = conn->next;
1351
        }
1352
        return NULL;
1353
}
1354
 
1355
#if LINUX_VERSION_CODE < 0x020363
1356
/**
1357
 * Lock the module, if someone changes into
1358
 * our proc directory.
1359
 */
1360
static void
1361
netiucv_fill_inode(struct inode *inode, int fill)
1362
{
1363
        if (fill) {
1364
                MOD_INC_USE_COUNT;
1365
        } else
1366
                MOD_DEC_USE_COUNT;
1367
}
1368
#endif
1369
 
1370
#define CTRL_BUFSIZE 40
1371
 
1372
static int
1373
netiucv_buffer_open(struct inode *inode, struct file *file)
1374
{
1375
        file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL);
1376
        if (file->private_data == NULL)
1377
                return -ENOMEM;
1378
        MOD_INC_USE_COUNT;
1379
        return 0;
1380
}
1381
 
1382
static int
1383
netiucv_buffer_close(struct inode *inode, struct file *file)
1384
{
1385
        kfree(file->private_data);
1386
        MOD_DEC_USE_COUNT;
1387
        return 0;
1388
}
1389
 
1390
static ssize_t
1391
netiucv_buffer_write(struct file *file, const char *buf, size_t count,
1392
                           loff_t *off)
1393
{
1394
        unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
1395
        net_device   *dev;
1396
        netiucv_priv *privptr;
1397
        char         *e;
1398
        int          bs1;
1399
        char         tmp[CTRL_BUFSIZE];
1400
 
1401
        if (!(dev = find_netdev_by_ino(ino)))
1402
                return -ENODEV;
1403
        if (off != &file->f_pos)
1404
                return -ESPIPE;
1405
 
1406
        privptr = (netiucv_priv *)dev->priv;
1407
 
1408
        if (count >= CTRL_BUFSIZE-1)
1409
                return -EINVAL;
1410
 
1411
        if (copy_from_user(tmp, buf, count))
1412
                return -EFAULT;
1413
        tmp[count+1] = '\0';
1414
        bs1 = simple_strtoul(tmp, &e, 0);
1415
 
1416
        if ((bs1 > NETIUCV_BUFSIZE_MAX) ||
1417
            (e && (!isspace(*e))))
1418
                return -EINVAL;
1419
        if ((dev->flags & IFF_RUNNING) &&
1420
            (bs1 < (dev->mtu + NETIUCV_HDRLEN + 2)))
1421
                return -EINVAL;
1422
        if (bs1 < (576 + NETIUCV_HDRLEN + NETIUCV_HDRLEN))
1423
                return -EINVAL;
1424
 
1425
 
1426
        privptr->conn->max_buffsize = bs1;
1427
        if (!(dev->flags & IFF_RUNNING))
1428
                dev->mtu = bs1 - NETIUCV_HDRLEN - NETIUCV_HDRLEN;
1429
        privptr->conn->flags |= CONN_FLAGS_BUFSIZE_CHANGED;
1430
 
1431
        return count;
1432
}
1433
 
1434
static ssize_t
1435
netiucv_buffer_read(struct file *file, char *buf, size_t count, loff_t *off)
1436
{
1437
        unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
1438
        char *sbuf = (char *)file->private_data;
1439
        net_device *dev;
1440
        netiucv_priv *privptr;
1441
        ssize_t ret = 0;
1442
        char *p = sbuf;
1443
        int l;
1444
 
1445
        if (!(dev = find_netdev_by_ino(ino)))
1446
                return -ENODEV;
1447
        if (off != &file->f_pos)
1448
                return -ESPIPE;
1449
 
1450
        privptr = (netiucv_priv *)dev->priv;
1451
 
1452
        if (file->f_pos == 0)
1453
                sprintf(sbuf, "%d\n", privptr->conn->max_buffsize);
1454
 
1455
        l = strlen(sbuf);
1456
        p = sbuf;
1457
        if (file->f_pos < l) {
1458
                p += file->f_pos;
1459
                l = strlen(p);
1460
                ret = (count > l) ? l : count;
1461
                if (copy_to_user(buf, p, ret))
1462
                        return -EFAULT;
1463
        }
1464
        file->f_pos += ret;
1465
        return ret;
1466
}
1467
 
1468
static int
1469
netiucv_user_open(struct inode *inode, struct file *file)
1470
{
1471
        file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL);
1472
        if (file->private_data == NULL)
1473
                return -ENOMEM;
1474
        MOD_INC_USE_COUNT;
1475
        return 0;
1476
}
1477
 
1478
static int
1479
netiucv_user_close(struct inode *inode, struct file *file)
1480
{
1481
        kfree(file->private_data);
1482
        MOD_DEC_USE_COUNT;
1483
        return 0;
1484
}
1485
 
1486
static ssize_t
1487
netiucv_user_write(struct file *file, const char *buf, size_t count,
1488
                           loff_t *off)
1489
{
1490
        unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
1491
        net_device   *dev;
1492
        netiucv_priv *privptr;
1493
        int          i;
1494
        char         *p;
1495
        char         tmp[CTRL_BUFSIZE];
1496
        char         user[9];
1497
 
1498
        if (!(dev = find_netdev_by_ino(ino)))
1499
                return -ENODEV;
1500
        if (off != &file->f_pos)
1501
                return -ESPIPE;
1502
 
1503
        privptr = (netiucv_priv *)dev->priv;
1504
 
1505
        if (count >= CTRL_BUFSIZE-1)
1506
                return -EINVAL;
1507
 
1508
        if (copy_from_user(tmp, buf, count))
1509
                return -EFAULT;
1510
        tmp[count+1] = '\0';
1511
 
1512
        memset(user, ' ', sizeof(user));
1513
        user[8] = '\0';
1514
        for (p = tmp, i = 0; *p && (!isspace(*p)); p++) {
1515
                if (i > 7)
1516
                        return -EINVAL;
1517
                user[i++] = *p;
1518
        }
1519
 
1520
        if (memcmp(user, privptr->conn->userid, 8) != 0) {
1521
                /* username changed */
1522
                if (dev->flags & IFF_RUNNING)
1523
                        return -EBUSY;
1524
        }
1525
        memcpy(privptr->conn->userid, user, 9);
1526
        return count;
1527
}
1528
 
1529
static ssize_t
1530
netiucv_user_read(struct file *file, char *buf, size_t count, loff_t *off)
1531
{
1532
        unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
1533
        char *sbuf = (char *)file->private_data;
1534
        net_device *dev;
1535
        netiucv_priv *privptr;
1536
        ssize_t ret = 0;
1537
        char *p = sbuf;
1538
        int l;
1539
 
1540
        if (!(dev = find_netdev_by_ino(ino)))
1541
                return -ENODEV;
1542
        if (off != &file->f_pos)
1543
                return -ESPIPE;
1544
 
1545
        privptr = (netiucv_priv *)dev->priv;
1546
 
1547
 
1548
        if (file->f_pos == 0)
1549
                sprintf(sbuf, "%s\n",
1550
                        netiucv_printname(privptr->conn->userid));
1551
 
1552
        l = strlen(sbuf);
1553
        p = sbuf;
1554
        if (file->f_pos < l) {
1555
                p += file->f_pos;
1556
                l = strlen(p);
1557
                ret = (count > l) ? l : count;
1558
                if (copy_to_user(buf, p, ret))
1559
                        return -EFAULT;
1560
        }
1561
        file->f_pos += ret;
1562
        return ret;
1563
}
1564
 
1565
#define STATS_BUFSIZE 2048
1566
 
1567
static int
1568
netiucv_stat_open(struct inode *inode, struct file *file)
1569
{
1570
        file->private_data = kmalloc(STATS_BUFSIZE, GFP_KERNEL);
1571
        if (file->private_data == NULL)
1572
                return -ENOMEM;
1573
        MOD_INC_USE_COUNT;
1574
        return 0;
1575
}
1576
 
1577
static int
1578
netiucv_stat_close(struct inode *inode, struct file *file)
1579
{
1580
        kfree(file->private_data);
1581
        MOD_DEC_USE_COUNT;
1582
        return 0;
1583
}
1584
 
1585
static ssize_t
1586
netiucv_stat_write(struct file *file, const char *buf, size_t count, loff_t *off)
1587
{
1588
        unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
1589
        net_device *dev;
1590
        netiucv_priv *privptr;
1591
 
1592
        if (!(dev = find_netdev_by_ino(ino)))
1593
                return -ENODEV;
1594
        privptr = (netiucv_priv *)dev->priv;
1595
        memset(&(privptr->conn->prof), 0, sizeof(privptr->conn->prof));
1596
        return count;
1597
}
1598
 
1599
static ssize_t
1600
netiucv_stat_read(struct file *file, char *buf, size_t count, loff_t *off)
1601
{
1602
        unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
1603
        char *sbuf = (char *)file->private_data;
1604
        net_device *dev;
1605
        netiucv_priv *privptr;
1606
        ssize_t ret = 0;
1607
        char *p = sbuf;
1608
        int l;
1609
 
1610
        if (!(dev = find_netdev_by_ino(ino)))
1611
                return -ENODEV;
1612
        if (off != &file->f_pos)
1613
                return -ESPIPE;
1614
 
1615
        privptr = (netiucv_priv *)dev->priv;
1616
 
1617
        if (file->f_pos == 0) {
1618
                p += sprintf(p, "Device FSM state: %s\n",
1619
                             fsm_getstate_str(privptr->fsm));
1620
                p += sprintf(p, "Connection FSM state: %s\n",
1621
                             fsm_getstate_str(privptr->conn->fsm));
1622
                p += sprintf(p, "Max. TX buffer used: %ld\n",
1623
                             privptr->conn->prof.maxmulti);
1624
                p += sprintf(p, "Max. chained SKBs: %ld\n",
1625
                             privptr->conn->prof.maxcqueue);
1626
                p += sprintf(p, "TX single write ops: %ld\n",
1627
                             privptr->conn->prof.doios_single);
1628
                p += sprintf(p, "TX multi write ops: %ld\n",
1629
                             privptr->conn->prof.doios_multi);
1630
                p += sprintf(p, "Netto bytes written: %ld\n",
1631
                             privptr->conn->prof.txlen);
1632
                p += sprintf(p, "Max. TX IO-time: %ld\n",
1633
                             privptr->conn->prof.tx_time);
1634
                p += sprintf(p, "Pending transmits: %ld\n",
1635
                             privptr->conn->prof.tx_pending);
1636
                p += sprintf(p, "Max. pending transmits: %ld\n",
1637
                             privptr->conn->prof.tx_max_pending);
1638
        }
1639
        l = strlen(sbuf);
1640
        p = sbuf;
1641
        if (file->f_pos < l) {
1642
                p += file->f_pos;
1643
                l = strlen(p);
1644
                ret = (count > l) ? l : count;
1645
                if (copy_to_user(buf, p, ret))
1646
                        return -EFAULT;
1647
        }
1648
        file->f_pos += ret;
1649
        return ret;
1650
}
1651
 
1652
static struct file_operations netiucv_stat_fops = {
1653
        read:    netiucv_stat_read,
1654
        write:   netiucv_stat_write,
1655
        open:    netiucv_stat_open,
1656
        release: netiucv_stat_close,
1657
};
1658
 
1659
static struct file_operations netiucv_buffer_fops = {
1660
        read:    netiucv_buffer_read,
1661
        write:   netiucv_buffer_write,
1662
        open:    netiucv_buffer_open,
1663
        release: netiucv_buffer_close,
1664
};
1665
 
1666
static struct file_operations netiucv_user_fops = {
1667
        read:    netiucv_user_read,
1668
        write:   netiucv_user_write,
1669
        open:    netiucv_user_open,
1670
        release: netiucv_user_close,
1671
};
1672
 
1673
static struct inode_operations netiucv_stat_iops = {
1674
#if LINUX_VERSION_CODE < 0x020363
1675
        default_file_ops: &netiucv_stat_fops
1676
#endif
1677
};
1678
static struct inode_operations netiucv_buffer_iops = {
1679
#if LINUX_VERSION_CODE < 0x020363
1680
        default_file_ops: &netiucv_buffer_fops
1681
#endif
1682
};
1683
 
1684
static struct inode_operations netiucv_user_iops = {
1685
#if LINUX_VERSION_CODE < 0x020363
1686
        default_file_ops: &netiucv_user_fops
1687
#endif
1688
};
1689
 
1690
static struct proc_dir_entry stat_entry = {
1691
        0,                           /* low_ino */
1692
        10,                          /* namelen */
1693
        "statistics",                /* name    */
1694
        S_IFREG | S_IRUGO | S_IWUSR, /* mode    */
1695
        1,                           /* nlink   */
1696
        0,                           /* uid     */
1697
        0,                           /* gid     */
1698
        0,                           /* size    */
1699
        &netiucv_stat_iops           /* ops     */
1700
};
1701
 
1702
static struct proc_dir_entry buffer_entry = {
1703
        0,                           /* low_ino */
1704
        10,                          /* namelen */
1705
        "buffersize",                /* name    */
1706
        S_IFREG | S_IRUSR | S_IWUSR, /* mode    */
1707
        1,                           /* nlink   */
1708
        0,                           /* uid     */
1709
        0,                           /* gid     */
1710
        0,                           /* size    */
1711
        &netiucv_buffer_iops         /* ops     */
1712
};
1713
 
1714
static struct proc_dir_entry user_entry = {
1715
        0,                           /* low_ino */
1716
        8,                           /* namelen */
1717
        "username",                  /* name    */
1718
        S_IFREG | S_IRUSR | S_IWUSR, /* mode    */
1719
        1,                           /* nlink   */
1720
        0,                           /* uid     */
1721
        0,                           /* gid     */
1722
        0,                           /* size    */
1723
        &netiucv_user_iops           /* ops     */
1724
};
1725
 
1726
#if LINUX_VERSION_CODE < 0x020363
1727
static struct proc_dir_entry netiucv_dir = {
1728
        0,                           /* low_ino  */
1729
        4,                           /* namelen  */
1730
        "iucv",                      /* name     */
1731
        S_IFDIR | S_IRUGO | S_IXUGO, /* mode     */
1732
        2,                           /* nlink    */
1733
        0,                           /* uid      */
1734
        0,                           /* gid      */
1735
        0,                           /* size     */
1736
        0,                           /* ops      */
1737
        0,                           /* get_info */
1738
        netiucv_fill_inode           /* fill_ino (for locking) */
1739
};
1740
 
1741
static struct proc_dir_entry netiucv_template =
1742
{
1743
        0,                           /* low_ino  */
1744
        0,                           /* namelen  */
1745
        "",                          /* name     */
1746
        S_IFDIR | S_IRUGO | S_IXUGO, /* mode     */
1747
        2,                           /* nlink    */
1748
        0,                           /* uid      */
1749
        0,                           /* gid      */
1750
        0,                           /* size     */
1751
        0,                           /* ops      */
1752
        0,                           /* get_info */
1753
        netiucv_fill_inode           /* fill_ino (for locking) */
1754
};
1755
#else
1756
static struct proc_dir_entry *netiucv_dir = NULL;
1757
static struct proc_dir_entry *netiucv_template = NULL;
1758
#endif
1759
 
1760
/**
1761
 * Create the driver's main directory /proc/net/iucv
1762
 */
1763
static void
1764
netiucv_proc_create_main(void)
1765
{
1766
        /**
1767
         * If not registered, register main proc dir-entry now
1768
         */
1769
#if LINUX_VERSION_CODE > 0x020362
1770
#ifdef CONFIG_PROC_FS
1771
        if (!netiucv_dir)
1772
                netiucv_dir = proc_mkdir("iucv", proc_net);
1773
#endif
1774
#else
1775
        if (netiucv_dir.low_ino == 0)
1776
                proc_net_register(&netiucv_dir);
1777
#endif
1778
}
1779
 
1780
#ifdef MODULE
1781
/**
1782
 * Destroy /proc/net/iucv
1783
 */
1784
static void
1785
netiucv_proc_destroy_main(void)
1786
{
1787
#if LINUX_VERSION_CODE > 0x020362
1788
#ifdef CONFIG_PROC_FS
1789
        remove_proc_entry("iucv", proc_net);
1790
#endif
1791
#else
1792
        proc_net_unregister(netiucv_dir.low_ino);
1793
#endif
1794
}
1795
#endif MODULE
1796
 
1797
/**
1798
 * Create a device specific subdirectory in /proc/net/iucv/ with the
1799
 * same name like the device. In that directory, create 3 entries
1800
 * "statistics", "buffersize" and "username".
1801
 *
1802
 * @param dev The device for which the subdirectory should be created.
1803
 *
1804
 */
1805
static void
1806
netiucv_proc_create_sub(net_device *dev) {
1807
        netiucv_priv *privptr = dev->priv;
1808
 
1809
#if LINUX_VERSION_CODE > 0x020362
1810
        privptr->proc_dentry = proc_mkdir(dev->name, netiucv_dir);
1811
        privptr->proc_stat_entry =
1812
                create_proc_entry("statistics",
1813
                                  S_IFREG | S_IRUSR | S_IWUSR,
1814
                                  privptr->proc_dentry);
1815
        privptr->proc_stat_entry->proc_fops = &netiucv_stat_fops;
1816
        privptr->proc_stat_entry->proc_iops = &netiucv_stat_iops;
1817
        privptr->proc_buffer_entry =
1818
                create_proc_entry("buffersize",
1819
                                  S_IFREG | S_IRUSR | S_IWUSR,
1820
                                  privptr->proc_dentry);
1821
        privptr->proc_buffer_entry->proc_fops = &netiucv_buffer_fops;
1822
        privptr->proc_buffer_entry->proc_iops = &netiucv_buffer_iops;
1823
        privptr->proc_user_entry =
1824
                create_proc_entry("username",
1825
                                  S_IFREG | S_IRUSR | S_IWUSR,
1826
                                  privptr->proc_dentry);
1827
        privptr->proc_user_entry->proc_fops = &netiucv_user_fops;
1828
        privptr->proc_user_entry->proc_iops = &netiucv_user_iops;
1829
#else
1830
        privptr->proc_dentry->name = dev->name;
1831
        privptr->proc_dentry->namelen = strlen(dev->name);
1832
        proc_register(&netiucv_dir, privptr->proc_dentry);
1833
        proc_register(privptr->proc_dentry, privptr->proc_stat_entry);
1834
        proc_register(privptr->proc_dentry, privptr->proc_buffer_entry);
1835
        proc_register(privptr->proc_dentry, privptr->proc_user_entry);
1836
#endif
1837
        privptr->proc_registered = 1;
1838
}
1839
 
1840
 
1841
/**
1842
 * Destroy a device specific subdirectory.
1843
 *
1844
 * @param privptr Pointer to device private data.
1845
 */
1846
static void
1847
netiucv_proc_destroy_sub(netiucv_priv *privptr) {
1848
        if (!privptr->proc_registered)
1849
                return;
1850
#if LINUX_VERSION_CODE > 0x020362
1851
        remove_proc_entry("statistics", privptr->proc_dentry);
1852
        remove_proc_entry("buffersize", privptr->proc_dentry);
1853
        remove_proc_entry("username", privptr->proc_dentry);
1854
        remove_proc_entry(privptr->proc_dentry->name, netiucv_dir);
1855
#else
1856
        proc_unregister(privptr->proc_dentry,
1857
                        privptr->proc_stat_entry->low_ino);
1858
        proc_unregister(privptr->proc_dentry,
1859
                        privptr->proc_buffer_entry->low_ino);
1860
        proc_unregister(privptr->proc_dentry,
1861
                        privptr->proc_user_entry->low_ino);
1862
        proc_unregister(&netiucv_dir,
1863
                        privptr->proc_dentry->low_ino);
1864
#endif
1865
        privptr->proc_registered = 0;
1866
}
1867
 
1868
 
1869
/**
1870
 * Allocate and initialize a new connection structure.
1871
 * Add it to the list of connections;
1872
 */
1873
static iucv_connection *
1874
netiucv_new_connection(net_device *dev, char *username)
1875
{
1876
        iucv_connection **clist = &connections;
1877
        iucv_connection *conn =
1878
                (iucv_connection *)kmalloc(sizeof(iucv_connection), GFP_KERNEL);
1879
        if (conn) {
1880
                memset(conn, 0, sizeof(iucv_connection));
1881
                skb_queue_head_init(&conn->collect_queue);
1882
                skb_queue_head_init(&conn->commit_queue);
1883
                conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT;
1884
                conn->netdev = dev;
1885
 
1886
                conn->rx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, GFP_DMA);
1887
                if (!conn->rx_buff) {
1888
                        kfree(conn);
1889
                        return NULL;
1890
                }
1891
                conn->tx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, GFP_DMA);
1892
                if (!conn->tx_buff) {
1893
                        kfree_skb(conn->rx_buff);
1894
                        kfree(conn);
1895
                        return NULL;
1896
                }
1897
                conn->fsm = init_fsm("netiucvconn", conn_state_names,
1898
                                     conn_event_names, NR_CONN_STATES,
1899
                                     NR_CONN_EVENTS, conn_fsm, CONN_FSM_LEN,
1900
                                     GFP_KERNEL);
1901
                if (!conn->fsm) {
1902
                        kfree_skb(conn->tx_buff);
1903
                        kfree_skb(conn->rx_buff);
1904
                        kfree(conn);
1905
                        return NULL;
1906
                }
1907
                fsm_settimer(conn->fsm, &conn->timer);
1908
                fsm_newstate(conn->fsm, CONN_STATE_INVALID);
1909
 
1910
                if (username) {
1911
                        memcpy(conn->userid, username, 9);
1912
                        fsm_newstate(conn->fsm, CONN_STATE_STOPPED);
1913
                }
1914
 
1915
                conn->next = *clist;
1916
                *clist = conn;
1917
        }
1918
        return conn;
1919
}
1920
 
1921
/**
1922
 * Release a connection structure and remove it from the
1923
 * list of connections.
1924
 */
1925
static void
1926
netiucv_remove_connection(iucv_connection *conn)
1927
{
1928
        iucv_connection **clist = &connections;
1929
 
1930
        if (conn == NULL)
1931
                return;
1932
        while (*clist) {
1933
                if (*clist == conn) {
1934
                        *clist = conn->next;
1935
                        if (conn->handle != 0) {
1936
                                iucv_unregister_program(conn->handle);
1937
                                conn->handle = 0;
1938
                        }
1939
                        fsm_deltimer(&conn->timer);
1940
                        kfree_fsm(conn->fsm);
1941
                        kfree_skb(conn->rx_buff);
1942
                        kfree_skb(conn->tx_buff);
1943
                        return;
1944
                }
1945
                clist = &((*clist)->next);
1946
        }
1947
}
1948
 
1949
/**
1950
 * Allocate and initialize everything of a net device.
1951
 */
1952
static net_device *
1953
netiucv_init_netdevice(int ifno, char *username)
1954
{
1955
        netiucv_priv *privptr;
1956
        int          priv_size;
1957
 
1958
        net_device *dev = kmalloc(sizeof(net_device)
1959
#if LINUX_VERSION_CODE < 0x020300
1960
                      + 11 /* name + zero */
1961
#endif
1962
                      , GFP_KERNEL);
1963
        if (!dev)
1964
                return NULL;
1965
        memset(dev, 0, sizeof(net_device));
1966
#if LINUX_VERSION_CODE < 0x020300
1967
        dev->name = (char *)dev + sizeof(net_device);
1968
#endif
1969
        sprintf(dev->name, "iucv%d", ifno);
1970
 
1971
        priv_size = sizeof(netiucv_priv) + sizeof(netiucv_template) +
1972
                sizeof(stat_entry) + sizeof(buffer_entry) + sizeof(user_entry);
1973
        dev->priv = kmalloc(priv_size, GFP_KERNEL);
1974
        if (dev->priv == NULL) {
1975
                kfree(dev);
1976
                return NULL;
1977
        }
1978
        memset(dev->priv, 0, priv_size);
1979
        privptr = (netiucv_priv *)dev->priv;
1980
        privptr->proc_dentry = (struct proc_dir_entry *)
1981
                (((char *)privptr) + sizeof(netiucv_priv));
1982
        privptr->proc_stat_entry = (struct proc_dir_entry *)
1983
                (((char *)privptr) + sizeof(netiucv_priv) +
1984
                 sizeof(netiucv_template));
1985
        privptr->proc_buffer_entry = (struct proc_dir_entry *)
1986
                (((char *)privptr) + sizeof(netiucv_priv) +
1987
                 sizeof(netiucv_template) + sizeof(stat_entry));
1988
        privptr->proc_user_entry = (struct proc_dir_entry *)
1989
                (((char *)privptr) + sizeof(netiucv_priv) +
1990
                 sizeof(netiucv_template) + sizeof(stat_entry) +
1991
                 sizeof(buffer_entry));
1992
        memcpy(privptr->proc_dentry, &netiucv_template,
1993
               sizeof(netiucv_template));
1994
        memcpy(privptr->proc_stat_entry, &stat_entry, sizeof(stat_entry));
1995
        memcpy(privptr->proc_buffer_entry, &buffer_entry, sizeof(buffer_entry));
1996
        memcpy(privptr->proc_user_entry, &user_entry, sizeof(user_entry));
1997
        privptr->fsm = init_fsm("netiucvdev", dev_state_names,
1998
                                dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS,
1999
                                dev_fsm, DEV_FSM_LEN, GFP_KERNEL);
2000
        if (privptr->fsm == NULL) {
2001
                kfree(privptr);
2002
                kfree(dev);
2003
                return NULL;
2004
        }
2005
        privptr->conn = netiucv_new_connection(dev, username);
2006
        if (!privptr->conn) {
2007
                kfree_fsm(privptr->fsm);
2008
                kfree(privptr);
2009
                kfree(dev);
2010
                return NULL;
2011
        }
2012
 
2013
        fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);
2014
        dev->mtu                 = NETIUCV_MTU_DEFAULT;
2015
        dev->hard_start_xmit     = netiucv_tx;
2016
        dev->open                = netiucv_open;
2017
        dev->stop                = netiucv_close;
2018
        dev->get_stats           = netiucv_stats;
2019
        dev->change_mtu          = netiucv_change_mtu;
2020
        dev->hard_header_len     = NETIUCV_HDRLEN;
2021
        dev->addr_len            = 0;
2022
        dev->type                = ARPHRD_SLIP;
2023
        dev->tx_queue_len        = NETIUCV_QUEUELEN_DEFAULT;
2024
        dev_init_buffers(dev);
2025
        dev->flags               = IFF_POINTOPOINT | IFF_NOARP;
2026
        return dev;
2027
}
2028
 
2029
/**
2030
 * Allocate and initialize everything of a net device.
2031
 */
2032
static void
2033
netiucv_free_netdevice(net_device *dev)
2034
{
2035
        netiucv_priv *privptr;
2036
 
2037
        if (!dev)
2038
                return;
2039
 
2040
        privptr = (netiucv_priv *)dev->priv;
2041
        if (privptr) {
2042
                if (privptr->conn)
2043
                        netiucv_remove_connection(privptr->conn);
2044
                if (privptr->fsm)
2045
                        kfree_fsm(privptr->fsm);
2046
                netiucv_proc_destroy_sub(privptr);
2047
                kfree(privptr);
2048
        }
2049
        kfree(dev);
2050
}
2051
 
2052
static void
2053
netiucv_banner(void)
2054
{
2055
        char vbuf[] = "$Revision: 1.1.1.1 $";
2056
        char *version = vbuf;
2057
 
2058
        if ((version = strchr(version, ':'))) {
2059
                char *p = strchr(version + 1, '$');
2060
                if (p)
2061
                        *p = '\0';
2062
        } else
2063
                version = " ??? ";
2064
        printk(KERN_INFO "NETIUCV driver Version%s initialized\n", version);
2065
}
2066
 
2067
#ifndef MODULE
2068
# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
2069
#  define init_return(a) return a
2070
static int __init
2071
iucv_setup(char *param)
2072
# else
2073
#  define init_return(a) return
2074
__initfunc (void iucv_setup(char *param, int *ints))
2075
# endif
2076
{
2077
        /**
2078
        * We do not parse parameters here because at the time of
2079
        * calling iucv_setup(), the kernel does not yet have
2080
        * memory management running. We delay this until probing
2081
        * is called.
2082
        */
2083
        iucv = param;
2084
        init_return(1);
2085
}
2086
 
2087
# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
2088
__setup ("iucv=", iucv_setup);
2089
# endif
2090
#else
2091
static void
2092
netiucv_exit(void)
2093
{
2094
        while (connections) {
2095
                net_device *dev = connections->netdev;
2096
                unregister_netdev(dev);
2097
                netiucv_free_netdevice(dev);
2098
        }
2099
        netiucv_proc_destroy_main();
2100
 
2101
        printk(KERN_INFO "NETIUCV driver unloaded\n");
2102
        return;
2103
}
2104
#endif
2105
 
2106
static int
2107
netiucv_init(void)
2108
{
2109
        char *p = iucv;
2110
        int ifno = 0;
2111
        int i = 0;
2112
        char username[10];
2113
 
2114
        netiucv_proc_create_main();
2115
        while (p) {
2116
                if (isalnum(*p) || (*p == '$')) {
2117
                        username[i++] = *p++;
2118
                        username[i] = '\0';
2119
                        if (i > 8) {
2120
                                printk(KERN_WARNING
2121
                                       "netiucv: Invalid user name '%s'\n",
2122
                                       username);
2123
                                while (*p && (*p != ':') && (*p != ','))
2124
                                        p++;
2125
                        }
2126
                } else {
2127
                        if (*p && (*p != ':') && (*p != ',')) {
2128
                                printk(KERN_WARNING
2129
                                       "netiucv: Invalid delimiter '%c'\n",
2130
                                       *p);
2131
                                while (*p && (*p != ':') && (*p != ','))
2132
                                        p++;
2133
                        } else {
2134
                                if (i) {
2135
                                        net_device *dev;
2136
 
2137
                                        while (i < 9)
2138
                                                username[i++] = ' ';
2139
                                        username[9] = '\0';
2140
                                        dev = netiucv_init_netdevice(ifno,
2141
                                                                     username);
2142
                                        if (!dev)
2143
                                                printk(KERN_WARNING
2144
                                                       "netiucv: Could not allocate network device structure for user '%s'\n", netiucv_printname(username));
2145
                                        else {
2146
                                                if (register_netdev(dev)) {
2147
                                                        printk(KERN_WARNING
2148
                                                               "netiucv: Could not register '%s'\n", dev->name);
2149
                                                        netiucv_free_netdevice(dev);
2150
                                                } else {
2151
                                                        printk(KERN_INFO "%s: '%s'\n", dev->name, netiucv_printname(username));
2152
                                                        netiucv_proc_create_sub(dev);
2153
                                                        ifno++;
2154
                                                }
2155
                                        }
2156
                                }
2157
                                if (!(*p))
2158
                                        break;
2159
                                i = 0;
2160
                                p++;
2161
                        }
2162
                }
2163
        }
2164
        netiucv_banner();
2165
        return 0;
2166
}
2167
 
2168
#ifdef MODULE
2169
module_init(netiucv_init);
2170
module_exit(netiucv_exit);
2171
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12))
2172
MODULE_LICENSE("GPL");
2173
#endif
2174
#endif

powered by: WebSVN 2.1.0

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