netiucv.c (71af75b6929458d85f63c0649dc26d6f4c19729e) netiucv.c (478a31403b365d2f7b35a0cae8ee3e0594dc5bb1)
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * IUCV network driver
4 *
5 * Copyright IBM Corp. 2001, 2009
6 *
7 * Author(s):
8 * Original netiucv driver:

--- 44 unchanged lines hidden (view full) ---

53
54#include <net/iucv/iucv.h>
55#include "fsm.h"
56
57MODULE_AUTHOR
58 ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)");
59MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
60
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * IUCV network driver
4 *
5 * Copyright IBM Corp. 2001, 2009
6 *
7 * Author(s):
8 * Original netiucv driver:

--- 44 unchanged lines hidden (view full) ---

53
54#include <net/iucv/iucv.h>
55#include "fsm.h"
56
57MODULE_AUTHOR
58 ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)");
59MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
60
61/**
61/*
62 * Debug Facility stuff
63 */
64#define IUCV_DBF_SETUP_NAME "iucv_setup"
65#define IUCV_DBF_SETUP_LEN 64
66#define IUCV_DBF_SETUP_PAGES 2
67#define IUCV_DBF_SETUP_NR_AREAS 1
68#define IUCV_DBF_SETUP_LEVEL 3
69

--- 32 unchanged lines hidden (view full) ---

102 } while (0)
103
104#define IUCV_DBF_SPRINTF(name,level,text...) \
105 do { \
106 debug_sprintf_event(iucv_dbf_trace, level, ##text ); \
107 debug_sprintf_event(iucv_dbf_trace, level, text ); \
108 } while (0)
109
62 * Debug Facility stuff
63 */
64#define IUCV_DBF_SETUP_NAME "iucv_setup"
65#define IUCV_DBF_SETUP_LEN 64
66#define IUCV_DBF_SETUP_PAGES 2
67#define IUCV_DBF_SETUP_NR_AREAS 1
68#define IUCV_DBF_SETUP_LEVEL 3
69

--- 32 unchanged lines hidden (view full) ---

102 } while (0)
103
104#define IUCV_DBF_SPRINTF(name,level,text...) \
105 do { \
106 debug_sprintf_event(iucv_dbf_trace, level, ##text ); \
107 debug_sprintf_event(iucv_dbf_trace, level, text ); \
108 } while (0)
109
110/**
110/*
111 * some more debug stuff
112 */
113#define PRINTK_HEADER " iucv: " /* for debugging */
114
115static struct device_driver netiucv_driver = {
116 .owner = THIS_MODULE,
117 .name = "netiucv",
118 .bus = &iucv_bus,
119};
120
111 * some more debug stuff
112 */
113#define PRINTK_HEADER " iucv: " /* for debugging */
114
115static struct device_driver netiucv_driver = {
116 .owner = THIS_MODULE,
117 .name = "netiucv",
118 .bus = &iucv_bus,
119};
120
121/**
121/*
122 * Per connection profiling data
123 */
124struct connection_profile {
125 unsigned long maxmulti;
126 unsigned long maxcqueue;
127 unsigned long doios_single;
128 unsigned long doios_multi;
129 unsigned long txlen;
130 unsigned long tx_time;
131 unsigned long send_stamp;
132 unsigned long tx_pending;
133 unsigned long tx_max_pending;
134};
135
122 * Per connection profiling data
123 */
124struct connection_profile {
125 unsigned long maxmulti;
126 unsigned long maxcqueue;
127 unsigned long doios_single;
128 unsigned long doios_multi;
129 unsigned long txlen;
130 unsigned long tx_time;
131 unsigned long send_stamp;
132 unsigned long tx_pending;
133 unsigned long tx_max_pending;
134};
135
136/**
136/*
137 * Representation of one iucv connection
138 */
139struct iucv_connection {
140 struct list_head list;
141 struct iucv_path *path;
142 struct sk_buff *rx_buff;
143 struct sk_buff *tx_buff;
144 struct sk_buff_head collect_queue;

--- 4 unchanged lines hidden (view full) ---

149 fsm_timer timer;
150 fsm_instance *fsm;
151 struct net_device *netdev;
152 struct connection_profile prof;
153 char userid[9];
154 char userdata[17];
155};
156
137 * Representation of one iucv connection
138 */
139struct iucv_connection {
140 struct list_head list;
141 struct iucv_path *path;
142 struct sk_buff *rx_buff;
143 struct sk_buff *tx_buff;
144 struct sk_buff_head collect_queue;

--- 4 unchanged lines hidden (view full) ---

149 fsm_timer timer;
150 fsm_instance *fsm;
151 struct net_device *netdev;
152 struct connection_profile prof;
153 char userid[9];
154 char userdata[17];
155};
156
157/**
157/*
158 * Linked list of all connection structs.
159 */
160static LIST_HEAD(iucv_connection_list);
161static DEFINE_RWLOCK(iucv_connection_rwlock);
162
158 * Linked list of all connection structs.
159 */
160static LIST_HEAD(iucv_connection_list);
161static DEFINE_RWLOCK(iucv_connection_rwlock);
162
163/**
163/*
164 * Representation of event-data for the
165 * connection state machine.
166 */
167struct iucv_event {
168 struct iucv_connection *conn;
169 void *data;
170};
171
164 * Representation of event-data for the
165 * connection state machine.
166 */
167struct iucv_event {
168 struct iucv_connection *conn;
169 void *data;
170};
171
172/**
172/*
173 * Private part of the network device structure
174 */
175struct netiucv_priv {
176 struct net_device_stats stats;
177 unsigned long tbusy;
178 fsm_instance *fsm;
179 struct iucv_connection *conn;
180 struct device *dev;
181};
182
173 * Private part of the network device structure
174 */
175struct netiucv_priv {
176 struct net_device_stats stats;
177 unsigned long tbusy;
178 fsm_instance *fsm;
179 struct iucv_connection *conn;
180 struct device *dev;
181};
182
183/**
183/*
184 * Link level header for a packet.
185 */
186struct ll_header {
187 u16 next;
188};
189
190#define NETIUCV_HDRLEN (sizeof(struct ll_header))
191#define NETIUCV_BUFSIZE_MAX 65537
192#define NETIUCV_BUFSIZE_DEFAULT NETIUCV_BUFSIZE_MAX
193#define NETIUCV_MTU_MAX (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN)
194#define NETIUCV_MTU_DEFAULT 9216
195#define NETIUCV_QUEUELEN_DEFAULT 50
196#define NETIUCV_TIMEOUT_5SEC 5000
197
184 * Link level header for a packet.
185 */
186struct ll_header {
187 u16 next;
188};
189
190#define NETIUCV_HDRLEN (sizeof(struct ll_header))
191#define NETIUCV_BUFSIZE_MAX 65537
192#define NETIUCV_BUFSIZE_DEFAULT NETIUCV_BUFSIZE_MAX
193#define NETIUCV_MTU_MAX (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN)
194#define NETIUCV_MTU_DEFAULT 9216
195#define NETIUCV_QUEUELEN_DEFAULT 50
196#define NETIUCV_TIMEOUT_5SEC 5000
197
198/**
198/*
199 * Compatibility macros for busy handling
200 * of network devices.
201 */
202static void netiucv_clear_busy(struct net_device *dev)
203{
204 struct netiucv_priv *priv = netdev_priv(dev);
205 clear_bit(0, &priv->tbusy);
206 netif_wake_queue(dev);

--- 11 unchanged lines hidden (view full) ---

218 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
219};
220
221static u8 iucvMagic_ebcdic[16] = {
222 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
223 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
224};
225
199 * Compatibility macros for busy handling
200 * of network devices.
201 */
202static void netiucv_clear_busy(struct net_device *dev)
203{
204 struct netiucv_priv *priv = netdev_priv(dev);
205 clear_bit(0, &priv->tbusy);
206 netif_wake_queue(dev);

--- 11 unchanged lines hidden (view full) ---

218 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
219};
220
221static u8 iucvMagic_ebcdic[16] = {
222 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
223 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
224};
225
226/**
226/*
227 * Convert an iucv userId to its printable
228 * form (strip whitespace at end).
229 *
230 * @param An iucv userId
231 *
232 * @returns The printable string (static data!!)
233 */
234static char *netiucv_printname(char *name, int len)

--- 22 unchanged lines hidden (view full) ---

257 EBCASC(tmp_udat, 16);
258 memcpy(tmp_udat, netiucv_printname(tmp_udat, 16), 16);
259 sprintf(buf, "%s.%s", tmp_uid, tmp_udat);
260 return buf;
261 } else
262 return netiucv_printname(conn->userid, 8);
263}
264
227 * Convert an iucv userId to its printable
228 * form (strip whitespace at end).
229 *
230 * @param An iucv userId
231 *
232 * @returns The printable string (static data!!)
233 */
234static char *netiucv_printname(char *name, int len)

--- 22 unchanged lines hidden (view full) ---

257 EBCASC(tmp_udat, 16);
258 memcpy(tmp_udat, netiucv_printname(tmp_udat, 16), 16);
259 sprintf(buf, "%s.%s", tmp_uid, tmp_udat);
260 return buf;
261 } else
262 return netiucv_printname(conn->userid, 8);
263}
264
265/**
265/*
266 * States of the interface statemachine.
267 */
268enum dev_states {
269 DEV_STATE_STOPPED,
270 DEV_STATE_STARTWAIT,
271 DEV_STATE_STOPWAIT,
272 DEV_STATE_RUNNING,
266 * States of the interface statemachine.
267 */
268enum dev_states {
269 DEV_STATE_STOPPED,
270 DEV_STATE_STARTWAIT,
271 DEV_STATE_STOPWAIT,
272 DEV_STATE_RUNNING,
273 /**
273 /*
274 * MUST be always the last element!!
275 */
276 NR_DEV_STATES
277};
278
279static const char *dev_state_names[] = {
280 "Stopped",
281 "StartWait",
282 "StopWait",
283 "Running",
284};
285
274 * MUST be always the last element!!
275 */
276 NR_DEV_STATES
277};
278
279static const char *dev_state_names[] = {
280 "Stopped",
281 "StartWait",
282 "StopWait",
283 "Running",
284};
285
286/**
286/*
287 * Events of the interface statemachine.
288 */
289enum dev_events {
290 DEV_EVENT_START,
291 DEV_EVENT_STOP,
292 DEV_EVENT_CONUP,
293 DEV_EVENT_CONDOWN,
287 * Events of the interface statemachine.
288 */
289enum dev_events {
290 DEV_EVENT_START,
291 DEV_EVENT_STOP,
292 DEV_EVENT_CONUP,
293 DEV_EVENT_CONDOWN,
294 /**
294 /*
295 * MUST be always the last element!!
296 */
297 NR_DEV_EVENTS
298};
299
300static const char *dev_event_names[] = {
301 "Start",
302 "Stop",
303 "Connection up",
304 "Connection down",
305};
306
295 * MUST be always the last element!!
296 */
297 NR_DEV_EVENTS
298};
299
300static const char *dev_event_names[] = {
301 "Start",
302 "Stop",
303 "Connection up",
304 "Connection down",
305};
306
307/**
307/*
308 * Events of the connection statemachine
309 */
310enum conn_events {
308 * Events of the connection statemachine
309 */
310enum conn_events {
311 /**
311 /*
312 * Events, representing callbacks from
313 * lowlevel iucv layer)
314 */
315 CONN_EVENT_CONN_REQ,
316 CONN_EVENT_CONN_ACK,
317 CONN_EVENT_CONN_REJ,
318 CONN_EVENT_CONN_SUS,
319 CONN_EVENT_CONN_RES,
320 CONN_EVENT_RX,
321 CONN_EVENT_TXDONE,
322
312 * Events, representing callbacks from
313 * lowlevel iucv layer)
314 */
315 CONN_EVENT_CONN_REQ,
316 CONN_EVENT_CONN_ACK,
317 CONN_EVENT_CONN_REJ,
318 CONN_EVENT_CONN_SUS,
319 CONN_EVENT_CONN_RES,
320 CONN_EVENT_RX,
321 CONN_EVENT_TXDONE,
322
323 /**
323 /*
324 * Events, representing errors return codes from
325 * calls to lowlevel iucv layer
326 */
327
324 * Events, representing errors return codes from
325 * calls to lowlevel iucv layer
326 */
327
328 /**
328 /*
329 * Event, representing timer expiry.
330 */
331 CONN_EVENT_TIMER,
332
329 * Event, representing timer expiry.
330 */
331 CONN_EVENT_TIMER,
332
333 /**
333 /*
334 * Events, representing commands from upper levels.
335 */
336 CONN_EVENT_START,
337 CONN_EVENT_STOP,
338
334 * Events, representing commands from upper levels.
335 */
336 CONN_EVENT_START,
337 CONN_EVENT_STOP,
338
339 /**
339 /*
340 * MUST be always the last element!!
341 */
342 NR_CONN_EVENTS,
343};
344
345static const char *conn_event_names[] = {
346 "Remote connection request",
347 "Remote connection acknowledge",

--- 4 unchanged lines hidden (view full) ---

352 "Data sent",
353
354 "Timer",
355
356 "Start",
357 "Stop",
358};
359
340 * MUST be always the last element!!
341 */
342 NR_CONN_EVENTS,
343};
344
345static const char *conn_event_names[] = {
346 "Remote connection request",
347 "Remote connection acknowledge",

--- 4 unchanged lines hidden (view full) ---

352 "Data sent",
353
354 "Timer",
355
356 "Start",
357 "Stop",
358};
359
360/**
360/*
361 * States of the connection statemachine.
362 */
363enum conn_states {
361 * States of the connection statemachine.
362 */
363enum conn_states {
364 /**
364 /*
365 * Connection not assigned to any device,
366 * initial state, invalid
367 */
368 CONN_STATE_INVALID,
369
365 * Connection not assigned to any device,
366 * initial state, invalid
367 */
368 CONN_STATE_INVALID,
369
370 /**
370 /*
371 * Userid assigned but not operating
372 */
373 CONN_STATE_STOPPED,
374
371 * Userid assigned but not operating
372 */
373 CONN_STATE_STOPPED,
374
375 /**
375 /*
376 * Connection registered,
377 * no connection request sent yet,
378 * no connection request received
379 */
380 CONN_STATE_STARTWAIT,
381
376 * Connection registered,
377 * no connection request sent yet,
378 * no connection request received
379 */
380 CONN_STATE_STARTWAIT,
381
382 /**
382 /*
383 * Connection registered and connection request sent,
384 * no acknowledge and no connection request received yet.
385 */
386 CONN_STATE_SETUPWAIT,
387
383 * Connection registered and connection request sent,
384 * no acknowledge and no connection request received yet.
385 */
386 CONN_STATE_SETUPWAIT,
387
388 /**
388 /*
389 * Connection up and running idle
390 */
391 CONN_STATE_IDLE,
392
389 * Connection up and running idle
390 */
391 CONN_STATE_IDLE,
392
393 /**
393 /*
394 * Data sent, awaiting CONN_EVENT_TXDONE
395 */
396 CONN_STATE_TX,
397
394 * Data sent, awaiting CONN_EVENT_TXDONE
395 */
396 CONN_STATE_TX,
397
398 /**
398 /*
399 * Error during registration.
400 */
401 CONN_STATE_REGERR,
402
399 * Error during registration.
400 */
401 CONN_STATE_REGERR,
402
403 /**
403 /*
404 * Error during registration.
405 */
406 CONN_STATE_CONNERR,
407
404 * Error during registration.
405 */
406 CONN_STATE_CONNERR,
407
408 /**
408 /*
409 * MUST be always the last element!!
410 */
411 NR_CONN_STATES,
412};
413
414static const char *conn_state_names[] = {
415 "Invalid",
416 "Stopped",
417 "StartWait",
418 "SetupWait",
419 "Idle",
420 "TX",
421 "Terminating",
422 "Registration error",
423 "Connect error",
424};
425
426
409 * MUST be always the last element!!
410 */
411 NR_CONN_STATES,
412};
413
414static const char *conn_state_names[] = {
415 "Invalid",
416 "Stopped",
417 "StartWait",
418 "SetupWait",
419 "Idle",
420 "TX",
421 "Terminating",
422 "Registration error",
423 "Connect error",
424};
425
426
427/**
427/*
428 * Debug Facility Stuff
429 */
430static debug_info_t *iucv_dbf_setup = NULL;
431static debug_info_t *iucv_dbf_data = NULL;
432static debug_info_t *iucv_dbf_trace = NULL;
433
434DEFINE_PER_CPU(char[256], iucv_dbf_txt_buf);
435

--- 115 unchanged lines hidden (view full) ---

551
552static void netiucv_callback_connres(struct iucv_path *path, u8 *ipuser)
553{
554 struct iucv_connection *conn = path->private;
555
556 fsm_event(conn->fsm, CONN_EVENT_CONN_RES, conn);
557}
558
428 * Debug Facility Stuff
429 */
430static debug_info_t *iucv_dbf_setup = NULL;
431static debug_info_t *iucv_dbf_data = NULL;
432static debug_info_t *iucv_dbf_trace = NULL;
433
434DEFINE_PER_CPU(char[256], iucv_dbf_txt_buf);
435

--- 115 unchanged lines hidden (view full) ---

551
552static void netiucv_callback_connres(struct iucv_path *path, u8 *ipuser)
553{
554 struct iucv_connection *conn = path->private;
555
556 fsm_event(conn->fsm, CONN_EVENT_CONN_RES, conn);
557}
558
559/**
559/*
560 * NOP action for statemachines
561 */
562static void netiucv_action_nop(fsm_instance *fi, int event, void *arg)
563{
564}
565
566/*
567 * Actions of the connection statemachine
568 */
569
560 * NOP action for statemachines
561 */
562static void netiucv_action_nop(fsm_instance *fi, int event, void *arg)
563{
564}
565
566/*
567 * Actions of the connection statemachine
568 */
569
570/**
570/*
571 * netiucv_unpack_skb
572 * @conn: The connection where this skb has been received.
573 * @pskb: The received skb.
574 *
575 * Unpack a just received skb and hand it over to upper layers.
576 * Helper function for conn_action_rx.
577 */
578static void netiucv_unpack_skb(struct iucv_connection *conn,

--- 409 unchanged lines hidden (view full) ---

988
989static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node);
990
991
992/*
993 * Actions for interface - statemachine.
994 */
995
571 * netiucv_unpack_skb
572 * @conn: The connection where this skb has been received.
573 * @pskb: The received skb.
574 *
575 * Unpack a just received skb and hand it over to upper layers.
576 * Helper function for conn_action_rx.
577 */
578static void netiucv_unpack_skb(struct iucv_connection *conn,

--- 409 unchanged lines hidden (view full) ---

988
989static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node);
990
991
992/*
993 * Actions for interface - statemachine.
994 */
995
996/**
996/*
997 * dev_action_start
998 * @fi: An instance of an interface statemachine.
999 * @event: The event, just happened.
1000 * @arg: Generic pointer, casted from struct net_device * upon call.
1001 *
1002 * Startup connection by sending CONN_EVENT_START to it.
1003 */
1004static void dev_action_start(fsm_instance *fi, int event, void *arg)
1005{
1006 struct net_device *dev = arg;
1007 struct netiucv_priv *privptr = netdev_priv(dev);
1008
1009 IUCV_DBF_TEXT(trace, 3, __func__);
1010
1011 fsm_newstate(fi, DEV_STATE_STARTWAIT);
1012 fsm_event(privptr->conn->fsm, CONN_EVENT_START, privptr->conn);
1013}
1014
997 * dev_action_start
998 * @fi: An instance of an interface statemachine.
999 * @event: The event, just happened.
1000 * @arg: Generic pointer, casted from struct net_device * upon call.
1001 *
1002 * Startup connection by sending CONN_EVENT_START to it.
1003 */
1004static void dev_action_start(fsm_instance *fi, int event, void *arg)
1005{
1006 struct net_device *dev = arg;
1007 struct netiucv_priv *privptr = netdev_priv(dev);
1008
1009 IUCV_DBF_TEXT(trace, 3, __func__);
1010
1011 fsm_newstate(fi, DEV_STATE_STARTWAIT);
1012 fsm_event(privptr->conn->fsm, CONN_EVENT_START, privptr->conn);
1013}
1014
1015/**
1015/*
1016 * Shutdown connection by sending CONN_EVENT_STOP to it.
1017 *
1018 * @param fi An instance of an interface statemachine.
1019 * @param event The event, just happened.
1020 * @param arg Generic pointer, casted from struct net_device * upon call.
1021 */
1022static void
1023dev_action_stop(fsm_instance *fi, int event, void *arg)

--- 5 unchanged lines hidden (view full) ---

1029 IUCV_DBF_TEXT(trace, 3, __func__);
1030
1031 ev.conn = privptr->conn;
1032
1033 fsm_newstate(fi, DEV_STATE_STOPWAIT);
1034 fsm_event(privptr->conn->fsm, CONN_EVENT_STOP, &ev);
1035}
1036
1016 * Shutdown connection by sending CONN_EVENT_STOP to it.
1017 *
1018 * @param fi An instance of an interface statemachine.
1019 * @param event The event, just happened.
1020 * @param arg Generic pointer, casted from struct net_device * upon call.
1021 */
1022static void
1023dev_action_stop(fsm_instance *fi, int event, void *arg)

--- 5 unchanged lines hidden (view full) ---

1029 IUCV_DBF_TEXT(trace, 3, __func__);
1030
1031 ev.conn = privptr->conn;
1032
1033 fsm_newstate(fi, DEV_STATE_STOPWAIT);
1034 fsm_event(privptr->conn->fsm, CONN_EVENT_STOP, &ev);
1035}
1036
1037/**
1037/*
1038 * Called from connection statemachine
1039 * when a connection is up and running.
1040 *
1041 * @param fi An instance of an interface statemachine.
1042 * @param event The event, just happened.
1043 * @param arg Generic pointer, casted from struct net_device * upon call.
1044 */
1045static void

--- 16 unchanged lines hidden (view full) ---

1062 break;
1063 case DEV_STATE_STOPWAIT:
1064 IUCV_DBF_TEXT(data, 2,
1065 "dev_action_connup: in DEV_STATE_STOPWAIT\n");
1066 break;
1067 }
1068}
1069
1038 * Called from connection statemachine
1039 * when a connection is up and running.
1040 *
1041 * @param fi An instance of an interface statemachine.
1042 * @param event The event, just happened.
1043 * @param arg Generic pointer, casted from struct net_device * upon call.
1044 */
1045static void

--- 16 unchanged lines hidden (view full) ---

1062 break;
1063 case DEV_STATE_STOPWAIT:
1064 IUCV_DBF_TEXT(data, 2,
1065 "dev_action_connup: in DEV_STATE_STOPWAIT\n");
1066 break;
1067 }
1068}
1069
1070/**
1070/*
1071 * Called from connection statemachine
1072 * when a connection has been shutdown.
1073 *
1074 * @param fi An instance of an interface statemachine.
1075 * @param event The event, just happened.
1076 * @param arg Generic pointer, casted from struct net_device * upon call.
1077 */
1078static void

--- 23 unchanged lines hidden (view full) ---

1102
1103 { DEV_STATE_RUNNING, DEV_EVENT_STOP, dev_action_stop },
1104 { DEV_STATE_RUNNING, DEV_EVENT_CONDOWN, dev_action_conndown },
1105 { DEV_STATE_RUNNING, DEV_EVENT_CONUP, netiucv_action_nop },
1106};
1107
1108static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node);
1109
1071 * Called from connection statemachine
1072 * when a connection has been shutdown.
1073 *
1074 * @param fi An instance of an interface statemachine.
1075 * @param event The event, just happened.
1076 * @param arg Generic pointer, casted from struct net_device * upon call.
1077 */
1078static void

--- 23 unchanged lines hidden (view full) ---

1102
1103 { DEV_STATE_RUNNING, DEV_EVENT_STOP, dev_action_stop },
1104 { DEV_STATE_RUNNING, DEV_EVENT_CONDOWN, dev_action_conndown },
1105 { DEV_STATE_RUNNING, DEV_EVENT_CONUP, netiucv_action_nop },
1106};
1107
1108static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node);
1109
1110/**
1110/*
1111 * Transmit a packet.
1112 * This is a helper function for netiucv_tx().
1113 *
1114 * @param conn Connection to be used for sending.
1115 * @param skb Pointer to struct sk_buff of packet to send.
1116 * The linklevel header has already been set up
1117 * by netiucv_tx().
1118 *

--- 20 unchanged lines hidden (view full) ---

1139 refcount_inc(&skb->users);
1140 skb_queue_tail(&conn->collect_queue, skb);
1141 conn->collect_len += l;
1142 rc = 0;
1143 }
1144 spin_unlock_irqrestore(&conn->collect_lock, saveflags);
1145 } else {
1146 struct sk_buff *nskb = skb;
1111 * Transmit a packet.
1112 * This is a helper function for netiucv_tx().
1113 *
1114 * @param conn Connection to be used for sending.
1115 * @param skb Pointer to struct sk_buff of packet to send.
1116 * The linklevel header has already been set up
1117 * by netiucv_tx().
1118 *

--- 20 unchanged lines hidden (view full) ---

1139 refcount_inc(&skb->users);
1140 skb_queue_tail(&conn->collect_queue, skb);
1141 conn->collect_len += l;
1142 rc = 0;
1143 }
1144 spin_unlock_irqrestore(&conn->collect_lock, saveflags);
1145 } else {
1146 struct sk_buff *nskb = skb;
1147 /**
1147 /*
1148 * Copy the skb to a new allocated skb in lowmem only if the
1149 * data is located above 2G in memory or tailroom is < 2.
1150 */
1151 unsigned long hi = ((unsigned long)(skb_tail_pointer(skb) +
1152 NETIUCV_HDRLEN)) >> 31;
1153 int copied = 0;
1154 if (hi || (skb_tailroom(skb) < 2)) {
1155 nskb = alloc_skb(skb->len + NETIUCV_HDRLEN +
1156 NETIUCV_HDRLEN, GFP_ATOMIC | GFP_DMA);
1157 if (!nskb) {
1158 IUCV_DBF_TEXT(data, 2, "alloc_skb failed\n");
1159 rc = -ENOMEM;
1160 return rc;
1161 } else {
1162 skb_reserve(nskb, NETIUCV_HDRLEN);
1163 skb_put_data(nskb, skb->data, skb->len);
1164 }
1165 copied = 1;
1166 }
1148 * Copy the skb to a new allocated skb in lowmem only if the
1149 * data is located above 2G in memory or tailroom is < 2.
1150 */
1151 unsigned long hi = ((unsigned long)(skb_tail_pointer(skb) +
1152 NETIUCV_HDRLEN)) >> 31;
1153 int copied = 0;
1154 if (hi || (skb_tailroom(skb) < 2)) {
1155 nskb = alloc_skb(skb->len + NETIUCV_HDRLEN +
1156 NETIUCV_HDRLEN, GFP_ATOMIC | GFP_DMA);
1157 if (!nskb) {
1158 IUCV_DBF_TEXT(data, 2, "alloc_skb failed\n");
1159 rc = -ENOMEM;
1160 return rc;
1161 } else {
1162 skb_reserve(nskb, NETIUCV_HDRLEN);
1163 skb_put_data(nskb, skb->data, skb->len);
1164 }
1165 copied = 1;
1166 }
1167 /**
1167 /*
1168 * skb now is below 2G and has enough room. Add headers.
1169 */
1170 header.next = nskb->len + NETIUCV_HDRLEN;
1171 memcpy(skb_push(nskb, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN);
1172 header.next = 0;
1173 skb_put_data(nskb, &header, NETIUCV_HDRLEN);
1174
1175 fsm_newstate(conn->fsm, CONN_STATE_TX);

--- 13 unchanged lines hidden (view full) ---

1189 fsm_newstate(conn->fsm, CONN_STATE_IDLE);
1190 conn->prof.tx_pending--;
1191 privptr = netdev_priv(conn->netdev);
1192 if (privptr)
1193 privptr->stats.tx_errors++;
1194 if (copied)
1195 dev_kfree_skb(nskb);
1196 else {
1168 * skb now is below 2G and has enough room. Add headers.
1169 */
1170 header.next = nskb->len + NETIUCV_HDRLEN;
1171 memcpy(skb_push(nskb, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN);
1172 header.next = 0;
1173 skb_put_data(nskb, &header, NETIUCV_HDRLEN);
1174
1175 fsm_newstate(conn->fsm, CONN_STATE_TX);

--- 13 unchanged lines hidden (view full) ---

1189 fsm_newstate(conn->fsm, CONN_STATE_IDLE);
1190 conn->prof.tx_pending--;
1191 privptr = netdev_priv(conn->netdev);
1192 if (privptr)
1193 privptr->stats.tx_errors++;
1194 if (copied)
1195 dev_kfree_skb(nskb);
1196 else {
1197 /**
1197 /*
1198 * Remove our headers. They get added
1199 * again on retransmit.
1200 */
1201 skb_pull(skb, NETIUCV_HDRLEN);
1202 skb_trim(skb, skb->len - NETIUCV_HDRLEN);
1203 }
1204 IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc);
1205 } else {

--- 6 unchanged lines hidden (view full) ---

1212
1213 return rc;
1214}
1215
1216/*
1217 * Interface API for upper network layers
1218 */
1219
1198 * Remove our headers. They get added
1199 * again on retransmit.
1200 */
1201 skb_pull(skb, NETIUCV_HDRLEN);
1202 skb_trim(skb, skb->len - NETIUCV_HDRLEN);
1203 }
1204 IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc);
1205 } else {

--- 6 unchanged lines hidden (view full) ---

1212
1213 return rc;
1214}
1215
1216/*
1217 * Interface API for upper network layers
1218 */
1219
1220/**
1220/*
1221 * Open an interface.
1222 * Called from generic network layer when ifconfig up is run.
1223 *
1224 * @param dev Pointer to interface struct.
1225 *
1226 * @return 0 on success, -ERRNO on failure. (Never fails.)
1227 */
1228static int netiucv_open(struct net_device *dev)
1229{
1230 struct netiucv_priv *priv = netdev_priv(dev);
1231
1232 fsm_event(priv->fsm, DEV_EVENT_START, dev);
1233 return 0;
1234}
1235
1221 * Open an interface.
1222 * Called from generic network layer when ifconfig up is run.
1223 *
1224 * @param dev Pointer to interface struct.
1225 *
1226 * @return 0 on success, -ERRNO on failure. (Never fails.)
1227 */
1228static int netiucv_open(struct net_device *dev)
1229{
1230 struct netiucv_priv *priv = netdev_priv(dev);
1231
1232 fsm_event(priv->fsm, DEV_EVENT_START, dev);
1233 return 0;
1234}
1235
1236/**
1236/*
1237 * Close an interface.
1238 * Called from generic network layer when ifconfig down is run.
1239 *
1240 * @param dev Pointer to interface struct.
1241 *
1242 * @return 0 on success, -ERRNO on failure. (Never fails.)
1243 */
1244static int netiucv_close(struct net_device *dev)
1245{
1246 struct netiucv_priv *priv = netdev_priv(dev);
1247
1248 fsm_event(priv->fsm, DEV_EVENT_STOP, dev);
1249 return 0;
1250}
1251
1237 * Close an interface.
1238 * Called from generic network layer when ifconfig down is run.
1239 *
1240 * @param dev Pointer to interface struct.
1241 *
1242 * @return 0 on success, -ERRNO on failure. (Never fails.)
1243 */
1244static int netiucv_close(struct net_device *dev)
1245{
1246 struct netiucv_priv *priv = netdev_priv(dev);
1247
1248 fsm_event(priv->fsm, DEV_EVENT_STOP, dev);
1249 return 0;
1250}
1251
1252/**
1252/*
1253 * Start transmission of a packet.
1254 * Called from generic network device layer.
1255 *
1256 * @param skb Pointer to buffer containing the packet.
1257 * @param dev Pointer to interface struct.
1258 *
1259 * @return 0 if packet consumed, !0 if packet rejected.
1260 * Note: If we return !0, then the packet is free'd by
1261 * the generic network layer.
1262 */
1263static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
1264{
1265 struct netiucv_priv *privptr = netdev_priv(dev);
1266 int rc;
1267
1268 IUCV_DBF_TEXT(trace, 4, __func__);
1253 * Start transmission of a packet.
1254 * Called from generic network device layer.
1255 *
1256 * @param skb Pointer to buffer containing the packet.
1257 * @param dev Pointer to interface struct.
1258 *
1259 * @return 0 if packet consumed, !0 if packet rejected.
1260 * Note: If we return !0, then the packet is free'd by
1261 * the generic network layer.
1262 */
1263static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
1264{
1265 struct netiucv_priv *privptr = netdev_priv(dev);
1266 int rc;
1267
1268 IUCV_DBF_TEXT(trace, 4, __func__);
1269 /**
1269 /*
1270 * Some sanity checks ...
1271 */
1272 if (skb == NULL) {
1273 IUCV_DBF_TEXT(data, 2, "netiucv_tx: skb is NULL\n");
1274 privptr->stats.tx_dropped++;
1275 return NETDEV_TX_OK;
1276 }
1277 if (skb_headroom(skb) < NETIUCV_HDRLEN) {
1278 IUCV_DBF_TEXT(data, 2,
1279 "netiucv_tx: skb_headroom < NETIUCV_HDRLEN\n");
1280 dev_kfree_skb(skb);
1281 privptr->stats.tx_dropped++;
1282 return NETDEV_TX_OK;
1283 }
1284
1270 * Some sanity checks ...
1271 */
1272 if (skb == NULL) {
1273 IUCV_DBF_TEXT(data, 2, "netiucv_tx: skb is NULL\n");
1274 privptr->stats.tx_dropped++;
1275 return NETDEV_TX_OK;
1276 }
1277 if (skb_headroom(skb) < NETIUCV_HDRLEN) {
1278 IUCV_DBF_TEXT(data, 2,
1279 "netiucv_tx: skb_headroom < NETIUCV_HDRLEN\n");
1280 dev_kfree_skb(skb);
1281 privptr->stats.tx_dropped++;
1282 return NETDEV_TX_OK;
1283 }
1284
1285 /**
1285 /*
1286 * If connection is not running, try to restart it
1287 * and throw away packet.
1288 */
1289 if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {
1290 dev_kfree_skb(skb);
1291 privptr->stats.tx_dropped++;
1292 privptr->stats.tx_errors++;
1293 privptr->stats.tx_carrier_errors++;

--- 5 unchanged lines hidden (view full) ---

1299 return NETDEV_TX_BUSY;
1300 }
1301 netif_trans_update(dev);
1302 rc = netiucv_transmit_skb(privptr->conn, skb);
1303 netiucv_clear_busy(dev);
1304 return rc ? NETDEV_TX_BUSY : NETDEV_TX_OK;
1305}
1306
1286 * If connection is not running, try to restart it
1287 * and throw away packet.
1288 */
1289 if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {
1290 dev_kfree_skb(skb);
1291 privptr->stats.tx_dropped++;
1292 privptr->stats.tx_errors++;
1293 privptr->stats.tx_carrier_errors++;

--- 5 unchanged lines hidden (view full) ---

1299 return NETDEV_TX_BUSY;
1300 }
1301 netif_trans_update(dev);
1302 rc = netiucv_transmit_skb(privptr->conn, skb);
1303 netiucv_clear_busy(dev);
1304 return rc ? NETDEV_TX_BUSY : NETDEV_TX_OK;
1305}
1306
1307/**
1307/*
1308 * netiucv_stats
1309 * @dev: Pointer to interface struct.
1310 *
1311 * Returns interface statistics of a device.
1312 *
1313 * Returns pointer to stats struct of this interface.
1314 */
1315static struct net_device_stats *netiucv_stats (struct net_device * dev)

--- 424 unchanged lines hidden (view full) ---

1740}
1741
1742static void netiucv_unregister_device(struct device *dev)
1743{
1744 IUCV_DBF_TEXT(trace, 3, __func__);
1745 device_unregister(dev);
1746}
1747
1308 * netiucv_stats
1309 * @dev: Pointer to interface struct.
1310 *
1311 * Returns interface statistics of a device.
1312 *
1313 * Returns pointer to stats struct of this interface.
1314 */
1315static struct net_device_stats *netiucv_stats (struct net_device * dev)

--- 424 unchanged lines hidden (view full) ---

1740}
1741
1742static void netiucv_unregister_device(struct device *dev)
1743{
1744 IUCV_DBF_TEXT(trace, 3, __func__);
1745 device_unregister(dev);
1746}
1747
1748/**
1748/*
1749 * Allocate and initialize a new connection structure.
1750 * Add it to the list of netiucv connections;
1751 */
1752static struct iucv_connection *netiucv_new_connection(struct net_device *dev,
1753 char *username,
1754 char *userdata)
1755{
1756 struct iucv_connection *conn;

--- 40 unchanged lines hidden (view full) ---

1797out_rx:
1798 kfree_skb(conn->rx_buff);
1799out_conn:
1800 kfree(conn);
1801out:
1802 return NULL;
1803}
1804
1749 * Allocate and initialize a new connection structure.
1750 * Add it to the list of netiucv connections;
1751 */
1752static struct iucv_connection *netiucv_new_connection(struct net_device *dev,
1753 char *username,
1754 char *userdata)
1755{
1756 struct iucv_connection *conn;

--- 40 unchanged lines hidden (view full) ---

1797out_rx:
1798 kfree_skb(conn->rx_buff);
1799out_conn:
1800 kfree(conn);
1801out:
1802 return NULL;
1803}
1804
1805/**
1805/*
1806 * Release a connection structure and remove it from the
1807 * list of netiucv connections.
1808 */
1809static void netiucv_remove_connection(struct iucv_connection *conn)
1810{
1811
1812 IUCV_DBF_TEXT(trace, 3, __func__);
1813 write_lock_bh(&iucv_connection_rwlock);

--- 7 unchanged lines hidden (view full) ---

1821 conn->path = NULL;
1822 }
1823 netiucv_purge_skb_queue(&conn->commit_queue);
1824 kfree_fsm(conn->fsm);
1825 kfree_skb(conn->rx_buff);
1826 kfree_skb(conn->tx_buff);
1827}
1828
1806 * Release a connection structure and remove it from the
1807 * list of netiucv connections.
1808 */
1809static void netiucv_remove_connection(struct iucv_connection *conn)
1810{
1811
1812 IUCV_DBF_TEXT(trace, 3, __func__);
1813 write_lock_bh(&iucv_connection_rwlock);

--- 7 unchanged lines hidden (view full) ---

1821 conn->path = NULL;
1822 }
1823 netiucv_purge_skb_queue(&conn->commit_queue);
1824 kfree_fsm(conn->fsm);
1825 kfree_skb(conn->rx_buff);
1826 kfree_skb(conn->tx_buff);
1827}
1828
1829/**
1829/*
1830 * Release everything of a net device.
1831 */
1832static void netiucv_free_netdevice(struct net_device *dev)
1833{
1834 struct netiucv_priv *privptr = netdev_priv(dev);
1835
1836 IUCV_DBF_TEXT(trace, 3, __func__);
1837

--- 5 unchanged lines hidden (view full) ---

1843 netiucv_remove_connection(privptr->conn);
1844 if (privptr->fsm)
1845 kfree_fsm(privptr->fsm);
1846 privptr->conn = NULL; privptr->fsm = NULL;
1847 /* privptr gets freed by free_netdev() */
1848 }
1849}
1850
1830 * Release everything of a net device.
1831 */
1832static void netiucv_free_netdevice(struct net_device *dev)
1833{
1834 struct netiucv_priv *privptr = netdev_priv(dev);
1835
1836 IUCV_DBF_TEXT(trace, 3, __func__);
1837

--- 5 unchanged lines hidden (view full) ---

1843 netiucv_remove_connection(privptr->conn);
1844 if (privptr->fsm)
1845 kfree_fsm(privptr->fsm);
1846 privptr->conn = NULL; privptr->fsm = NULL;
1847 /* privptr gets freed by free_netdev() */
1848 }
1849}
1850
1851/**
1851/*
1852 * Initialize a net device. (Called from kernel in alloc_netdev())
1853 */
1854static const struct net_device_ops netiucv_netdev_ops = {
1855 .ndo_open = netiucv_open,
1856 .ndo_stop = netiucv_close,
1857 .ndo_get_stats = netiucv_stats,
1858 .ndo_start_xmit = netiucv_tx,
1859};

--- 8 unchanged lines hidden (view full) ---

1868 dev->hard_header_len = NETIUCV_HDRLEN;
1869 dev->addr_len = 0;
1870 dev->type = ARPHRD_SLIP;
1871 dev->tx_queue_len = NETIUCV_QUEUELEN_DEFAULT;
1872 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
1873 dev->netdev_ops = &netiucv_netdev_ops;
1874}
1875
1852 * Initialize a net device. (Called from kernel in alloc_netdev())
1853 */
1854static const struct net_device_ops netiucv_netdev_ops = {
1855 .ndo_open = netiucv_open,
1856 .ndo_stop = netiucv_close,
1857 .ndo_get_stats = netiucv_stats,
1858 .ndo_start_xmit = netiucv_tx,
1859};

--- 8 unchanged lines hidden (view full) ---

1868 dev->hard_header_len = NETIUCV_HDRLEN;
1869 dev->addr_len = 0;
1870 dev->type = ARPHRD_SLIP;
1871 dev->tx_queue_len = NETIUCV_QUEUELEN_DEFAULT;
1872 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
1873 dev->netdev_ops = &netiucv_netdev_ops;
1874}
1875
1876/**
1876/*
1877 * Allocate and initialize everything of a net device.
1878 */
1879static struct net_device *netiucv_init_netdevice(char *username, char *userdata)
1880{
1881 struct netiucv_priv *privptr;
1882 struct net_device *dev;
1883
1884 dev = alloc_netdev(sizeof(struct netiucv_priv), "iucv%d",

--- 222 unchanged lines hidden ---
1877 * Allocate and initialize everything of a net device.
1878 */
1879static struct net_device *netiucv_init_netdevice(char *username, char *userdata)
1880{
1881 struct netiucv_priv *privptr;
1882 struct net_device *dev;
1883
1884 dev = alloc_netdev(sizeof(struct netiucv_priv), "iucv%d",

--- 222 unchanged lines hidden ---