aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/net/ctcm_mpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/net/ctcm_mpc.c')
-rw-r--r--drivers/s390/net/ctcm_mpc.c2472
1 files changed, 2472 insertions, 0 deletions
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c
new file mode 100644
index 000000000000..044addee64a2
--- /dev/null
+++ b/drivers/s390/net/ctcm_mpc.c
@@ -0,0 +1,2472 @@
1/*
2 * drivers/s390/net/ctcm_mpc.c
3 *
4 * Copyright IBM Corp. 2004, 2007
5 * Authors: Belinda Thompson (belindat@us.ibm.com)
6 * Andy Richter (richtera@us.ibm.com)
7 * Peter Tiedemann (ptiedem@de.ibm.com)
8 */
9
10/*
11 This module exports functions to be used by CCS:
12 EXPORT_SYMBOL(ctc_mpc_alloc_channel);
13 EXPORT_SYMBOL(ctc_mpc_establish_connectivity);
14 EXPORT_SYMBOL(ctc_mpc_dealloc_ch);
15 EXPORT_SYMBOL(ctc_mpc_flow_control);
16*/
17
18#undef DEBUG
19#undef DEBUGDATA
20#undef DEBUGCCW
21
22#include <linux/version.h>
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/kernel.h>
26#include <linux/slab.h>
27#include <linux/errno.h>
28#include <linux/types.h>
29#include <linux/interrupt.h>
30#include <linux/timer.h>
31#include <linux/sched.h>
32
33#include <linux/signal.h>
34#include <linux/string.h>
35#include <linux/proc_fs.h>
36
37#include <linux/ip.h>
38#include <linux/if_arp.h>
39#include <linux/tcp.h>
40#include <linux/skbuff.h>
41#include <linux/ctype.h>
42#include <linux/netdevice.h>
43#include <net/dst.h>
44
45#include <linux/io.h> /* instead of <asm/io.h> ok ? */
46#include <asm/ccwdev.h>
47#include <asm/ccwgroup.h>
48#include <linux/bitops.h> /* instead of <asm/bitops.h> ok ? */
49#include <linux/uaccess.h> /* instead of <asm/uaccess.h> ok ? */
50#include <linux/wait.h>
51#include <linux/moduleparam.h>
52#include <asm/idals.h>
53
54#include "cu3088.h"
55#include "ctcm_mpc.h"
56#include "ctcm_main.h"
57#include "ctcm_fsms.h"
58
59static const struct xid2 init_xid = {
60 .xid2_type_id = XID_FM2,
61 .xid2_len = 0x45,
62 .xid2_adj_id = 0,
63 .xid2_rlen = 0x31,
64 .xid2_resv1 = 0,
65 .xid2_flag1 = 0,
66 .xid2_fmtt = 0,
67 .xid2_flag4 = 0x80,
68 .xid2_resv2 = 0,
69 .xid2_tgnum = 0,
70 .xid2_sender_id = 0,
71 .xid2_flag2 = 0,
72 .xid2_option = XID2_0,
73 .xid2_resv3 = "\x00",
74 .xid2_resv4 = 0,
75 .xid2_dlc_type = XID2_READ_SIDE,
76 .xid2_resv5 = 0,
77 .xid2_mpc_flag = 0,
78 .xid2_resv6 = 0,
79 .xid2_buf_len = (MPC_BUFSIZE_DEFAULT - 35),
80};
81
82static const struct th_header thnorm = {
83 .th_seg = 0x00,
84 .th_ch_flag = TH_IS_XID,
85 .th_blk_flag = TH_DATA_IS_XID,
86 .th_is_xid = 0x01,
87 .th_seq_num = 0x00000000,
88};
89
90static const struct th_header thdummy = {
91 .th_seg = 0x00,
92 .th_ch_flag = 0x00,
93 .th_blk_flag = TH_DATA_IS_XID,
94 .th_is_xid = 0x01,
95 .th_seq_num = 0x00000000,
96};
97
98/*
99 * Definition of one MPC group
100 */
101
102/*
103 * Compatibility macros for busy handling
104 * of network devices.
105 */
106
107static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb);
108
109/*
110 * MPC Group state machine actions (static prototypes)
111 */
112static void mpc_action_nop(fsm_instance *fsm, int event, void *arg);
113static void mpc_action_go_ready(fsm_instance *fsm, int event, void *arg);
114static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg);
115static void mpc_action_timeout(fsm_instance *fi, int event, void *arg);
116static int mpc_validate_xid(struct mpcg_info *mpcginfo);
117static void mpc_action_yside_xid(fsm_instance *fsm, int event, void *arg);
118static void mpc_action_doxid0(fsm_instance *fsm, int event, void *arg);
119static void mpc_action_doxid7(fsm_instance *fsm, int event, void *arg);
120static void mpc_action_xside_xid(fsm_instance *fsm, int event, void *arg);
121static void mpc_action_rcvd_xid0(fsm_instance *fsm, int event, void *arg);
122static void mpc_action_rcvd_xid7(fsm_instance *fsm, int event, void *arg);
123
124#ifdef DEBUGDATA
125/*-------------------------------------------------------------------*
126* Dump buffer format *
127* *
128*--------------------------------------------------------------------*/
129void ctcmpc_dumpit(char *buf, int len)
130{
131 __u32 ct, sw, rm, dup;
132 char *ptr, *rptr;
133 char tbuf[82], tdup[82];
134 #if (UTS_MACHINE == s390x)
135 char addr[22];
136 #else
137 char addr[12];
138 #endif
139 char boff[12];
140 char bhex[82], duphex[82];
141 char basc[40];
142
143 sw = 0;
144 rptr = ptr = buf;
145 rm = 16;
146 duphex[0] = 0x00;
147 dup = 0;
148
149 for (ct = 0; ct < len; ct++, ptr++, rptr++) {
150 if (sw == 0) {
151 #if (UTS_MACHINE == s390x)
152 sprintf(addr, "%16.16lx", (unsigned long)rptr);
153 #else
154 sprintf(addr, "%8.8X", (__u32)rptr);
155 #endif
156
157 sprintf(boff, "%4.4X", (__u32)ct);
158 bhex[0] = '\0';
159 basc[0] = '\0';
160 }
161 if ((sw == 4) || (sw == 12))
162 strcat(bhex, " ");
163 if (sw == 8)
164 strcat(bhex, " ");
165
166 #if (UTS_MACHINE == s390x)
167 sprintf(tbuf, "%2.2lX", (unsigned long)*ptr);
168 #else
169 sprintf(tbuf, "%2.2X", (__u32)*ptr);
170 #endif
171
172 tbuf[2] = '\0';
173 strcat(bhex, tbuf);
174 if ((0 != isprint(*ptr)) && (*ptr >= 0x20))
175 basc[sw] = *ptr;
176 else
177 basc[sw] = '.';
178
179 basc[sw+1] = '\0';
180 sw++;
181 rm--;
182 if (sw == 16) {
183 if ((strcmp(duphex, bhex)) != 0) {
184 if (dup != 0) {
185 sprintf(tdup, "Duplicate as above "
186 "to %s", addr);
187 printk(KERN_INFO " "
188 " --- %s ---\n", tdup);
189 }
190 printk(KERN_INFO " %s (+%s) : %s [%s]\n",
191 addr, boff, bhex, basc);
192 dup = 0;
193 strcpy(duphex, bhex);
194 } else
195 dup++;
196
197 sw = 0;
198 rm = 16;
199 }
200 } /* endfor */
201
202 if (sw != 0) {
203 for ( ; rm > 0; rm--, sw++) {
204 if ((sw == 4) || (sw == 12))
205 strcat(bhex, " ");
206 if (sw == 8)
207 strcat(bhex, " ");
208 strcat(bhex, " ");
209 strcat(basc, " ");
210 }
211 if (dup != 0) {
212 sprintf(tdup, "Duplicate as above to %s", addr);
213 printk(KERN_INFO " "
214 " --- %s ---\n", tdup);
215 }
216 printk(KERN_INFO " %s (+%s) : %s [%s]\n",
217 addr, boff, bhex, basc);
218 } else {
219 if (dup >= 1) {
220 sprintf(tdup, "Duplicate as above to %s", addr);
221 printk(KERN_INFO " "
222 " --- %s ---\n", tdup);
223 }
224 if (dup != 0) {
225 printk(KERN_INFO " %s (+%s) : %s [%s]\n",
226 addr, boff, bhex, basc);
227 }
228 }
229
230 return;
231
232} /* end of ctcmpc_dumpit */
233#endif
234
235#ifdef DEBUGDATA
236/*
237 * Dump header and first 16 bytes of an sk_buff for debugging purposes.
238 *
239 * skb The sk_buff to dump.
240 * offset Offset relative to skb-data, where to start the dump.
241 */
242void ctcmpc_dump_skb(struct sk_buff *skb, int offset)
243{
244 unsigned char *p = skb->data;
245 struct th_header *header;
246 struct pdu *pheader;
247 int bl = skb->len;
248 int i;
249
250 if (p == NULL)
251 return;
252
253 p += offset;
254 header = (struct th_header *)p;
255
256 printk(KERN_INFO "dump:\n");
257 printk(KERN_INFO "skb len=%d \n", skb->len);
258 if (skb->len > 2) {
259 switch (header->th_ch_flag) {
260 case TH_HAS_PDU:
261 break;
262 case 0x00:
263 case TH_IS_XID:
264 if ((header->th_blk_flag == TH_DATA_IS_XID) &&
265 (header->th_is_xid == 0x01))
266 goto dumpth;
267 case TH_SWEEP_REQ:
268 goto dumpth;
269 case TH_SWEEP_RESP:
270 goto dumpth;
271 default:
272 break;
273 }
274
275 pheader = (struct pdu *)p;
276 printk(KERN_INFO "pdu->offset: %d hex: %04x\n",
277 pheader->pdu_offset, pheader->pdu_offset);
278 printk(KERN_INFO "pdu->flag : %02x\n", pheader->pdu_flag);
279 printk(KERN_INFO "pdu->proto : %02x\n", pheader->pdu_proto);
280 printk(KERN_INFO "pdu->seq : %02x\n", pheader->pdu_seq);
281 goto dumpdata;
282
283dumpth:
284 printk(KERN_INFO "th->seg : %02x\n", header->th_seg);
285 printk(KERN_INFO "th->ch : %02x\n", header->th_ch_flag);
286 printk(KERN_INFO "th->blk_flag: %02x\n", header->th_blk_flag);
287 printk(KERN_INFO "th->type : %s\n",
288 (header->th_is_xid) ? "DATA" : "XID");
289 printk(KERN_INFO "th->seqnum : %04x\n", header->th_seq_num);
290
291 }
292dumpdata:
293 if (bl > 32)
294 bl = 32;
295 printk(KERN_INFO "data: ");
296 for (i = 0; i < bl; i++)
297 printk(KERN_INFO "%02x%s", *p++, (i % 16) ? " " : "\n<7>");
298 printk(KERN_INFO "\n");
299}
300#endif
301
302/*
303 * ctc_mpc_alloc_channel
304 * (exported interface)
305 *
306 * Device Initialization :
307 * ACTPATH driven IO operations
308 */
309int ctc_mpc_alloc_channel(int port_num, void (*callback)(int, int))
310{
311 char device[20];
312 struct net_device *dev;
313 struct mpc_group *grp;
314 struct ctcm_priv *priv;
315
316 ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__);
317
318 sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num);
319 dev = __dev_get_by_name(&init_net, device);
320
321 if (dev == NULL) {
322 printk(KERN_INFO "ctc_mpc_alloc_channel %s dev=NULL\n", device);
323 return 1;
324 }
325
326 priv = dev->priv;
327 grp = priv->mpcg;
328 if (!grp)
329 return 1;
330
331 grp->allochanfunc = callback;
332 grp->port_num = port_num;
333 grp->port_persist = 1;
334
335 ctcm_pr_debug("ctcmpc: %s called for device %s state=%s\n",
336 __FUNCTION__,
337 dev->name,
338 fsm_getstate_str(grp->fsm));
339
340 switch (fsm_getstate(grp->fsm)) {
341 case MPCG_STATE_INOP:
342 /* Group is in the process of terminating */
343 grp->alloc_called = 1;
344 break;
345 case MPCG_STATE_RESET:
346 /* MPC Group will transition to state */
347 /* MPCG_STATE_XID2INITW iff the minimum number */
348 /* of 1 read and 1 write channel have successfully*/
349 /* activated */
350 /*fsm_newstate(grp->fsm, MPCG_STATE_XID2INITW);*/
351 if (callback)
352 grp->send_qllc_disc = 1;
353 case MPCG_STATE_XID0IOWAIT:
354 fsm_deltimer(&grp->timer);
355 grp->outstanding_xid2 = 0;
356 grp->outstanding_xid7 = 0;
357 grp->outstanding_xid7_p2 = 0;
358 grp->saved_xid2 = NULL;
359 if (callback)
360 ctcm_open(dev);
361 fsm_event(priv->fsm, DEV_EVENT_START, dev);
362 break;
363 case MPCG_STATE_READY:
364 /* XID exchanges completed after PORT was activated */
365 /* Link station already active */
366 /* Maybe timing issue...retry callback */
367 grp->allocchan_callback_retries++;
368 if (grp->allocchan_callback_retries < 4) {
369 if (grp->allochanfunc)
370 grp->allochanfunc(grp->port_num,
371 grp->group_max_buflen);
372 } else {
373 /* there are problems...bail out */
374 /* there may be a state mismatch so restart */
375 grp->port_persist = 1;
376 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
377 grp->allocchan_callback_retries = 0;
378 }
379 break;
380 default:
381 return 0;
382
383 }
384
385 ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__);
386 return 0;
387}
388EXPORT_SYMBOL(ctc_mpc_alloc_channel);
389
390/*
391 * ctc_mpc_establish_connectivity
392 * (exported interface)
393 */
394void ctc_mpc_establish_connectivity(int port_num,
395 void (*callback)(int, int, int))
396{
397 char device[20];
398 struct net_device *dev;
399 struct mpc_group *grp;
400 struct ctcm_priv *priv;
401 struct channel *rch, *wch;
402
403 ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__);
404
405 sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num);
406 dev = __dev_get_by_name(&init_net, device);
407
408 if (dev == NULL) {
409 printk(KERN_INFO "ctc_mpc_establish_connectivity "
410 "%s dev=NULL\n", device);
411 return;
412 }
413 priv = dev->priv;
414 rch = priv->channel[READ];
415 wch = priv->channel[WRITE];
416
417 grp = priv->mpcg;
418
419 ctcm_pr_debug("ctcmpc: %s() called for device %s state=%s\n",
420 __FUNCTION__, dev->name,
421 fsm_getstate_str(grp->fsm));
422
423 grp->estconnfunc = callback;
424 grp->port_num = port_num;
425
426 switch (fsm_getstate(grp->fsm)) {
427 case MPCG_STATE_READY:
428 /* XID exchanges completed after PORT was activated */
429 /* Link station already active */
430 /* Maybe timing issue...retry callback */
431 fsm_deltimer(&grp->timer);
432 grp->estconn_callback_retries++;
433 if (grp->estconn_callback_retries < 4) {
434 if (grp->estconnfunc) {
435 grp->estconnfunc(grp->port_num, 0,
436 grp->group_max_buflen);
437 grp->estconnfunc = NULL;
438 }
439 } else {
440 /* there are problems...bail out */
441 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
442 grp->estconn_callback_retries = 0;
443 }
444 break;
445 case MPCG_STATE_INOP:
446 case MPCG_STATE_RESET:
447 /* MPC Group is not ready to start XID - min num of */
448 /* 1 read and 1 write channel have not been acquired*/
449 printk(KERN_WARNING "ctcmpc: %s() REJECTED ACTIVE XID Req"
450 "uest - Channel Pair is not Active\n", __FUNCTION__);
451 if (grp->estconnfunc) {
452 grp->estconnfunc(grp->port_num, -1, 0);
453 grp->estconnfunc = NULL;
454 }
455 break;
456 case MPCG_STATE_XID2INITW:
457 /* alloc channel was called but no XID exchange */
458 /* has occurred. initiate xside XID exchange */
459 /* make sure yside XID0 processing has not started */
460 if ((fsm_getstate(rch->fsm) > CH_XID0_PENDING) ||
461 (fsm_getstate(wch->fsm) > CH_XID0_PENDING)) {
462 printk(KERN_WARNING "mpc: %s() ABORT ACTIVE XID"
463 " Request- PASSIVE XID in process\n"
464 , __FUNCTION__);
465 break;
466 }
467 grp->send_qllc_disc = 1;
468 fsm_newstate(grp->fsm, MPCG_STATE_XID0IOWAIT);
469 fsm_deltimer(&grp->timer);
470 fsm_addtimer(&grp->timer, MPC_XID_TIMEOUT_VALUE,
471 MPCG_EVENT_TIMER, dev);
472 grp->outstanding_xid7 = 0;
473 grp->outstanding_xid7_p2 = 0;
474 grp->saved_xid2 = NULL;
475 if ((rch->in_mpcgroup) &&
476 (fsm_getstate(rch->fsm) == CH_XID0_PENDING))
477 fsm_event(grp->fsm, MPCG_EVENT_XID0DO, rch);
478 else {
479 printk(KERN_WARNING "mpc: %s() Unable to start"
480 " ACTIVE XID0 on read channel\n",
481 __FUNCTION__);
482 if (grp->estconnfunc) {
483 grp->estconnfunc(grp->port_num, -1, 0);
484 grp->estconnfunc = NULL;
485 }
486 fsm_deltimer(&grp->timer);
487 goto done;
488 }
489 if ((wch->in_mpcgroup) &&
490 (fsm_getstate(wch->fsm) == CH_XID0_PENDING))
491 fsm_event(grp->fsm, MPCG_EVENT_XID0DO, wch);
492 else {
493 printk(KERN_WARNING "mpc: %s() Unable to start"
494 " ACTIVE XID0 on write channel\n",
495 __FUNCTION__);
496 if (grp->estconnfunc) {
497 grp->estconnfunc(grp->port_num, -1, 0);
498 grp->estconnfunc = NULL;
499 }
500 fsm_deltimer(&grp->timer);
501 goto done;
502 }
503 break;
504 case MPCG_STATE_XID0IOWAIT:
505 /* already in active XID negotiations */
506 default:
507 break;
508 }
509
510done:
511 ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__);
512 return;
513}
514EXPORT_SYMBOL(ctc_mpc_establish_connectivity);
515
516/*
517 * ctc_mpc_dealloc_ch
518 * (exported interface)
519 */
520void ctc_mpc_dealloc_ch(int port_num)
521{
522 struct net_device *dev;
523 char device[20];
524 struct ctcm_priv *priv;
525 struct mpc_group *grp;
526
527 ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__);
528 sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num);
529 dev = __dev_get_by_name(&init_net, device);
530
531 if (dev == NULL) {
532 printk(KERN_INFO "%s() %s dev=NULL\n", __FUNCTION__, device);
533 goto done;
534 }
535
536 ctcm_pr_debug("ctcmpc:%s %s() called for device %s refcount=%d\n",
537 dev->name, __FUNCTION__,
538 dev->name, atomic_read(&dev->refcnt));
539
540 priv = dev->priv;
541 if (priv == NULL) {
542 printk(KERN_INFO "%s() %s priv=NULL\n",
543 __FUNCTION__, device);
544 goto done;
545 }
546 fsm_deltimer(&priv->restart_timer);
547
548 grp = priv->mpcg;
549 if (grp == NULL) {
550 printk(KERN_INFO "%s() %s dev=NULL\n", __FUNCTION__, device);
551 goto done;
552 }
553 grp->channels_terminating = 0;
554
555 fsm_deltimer(&grp->timer);
556
557 grp->allochanfunc = NULL;
558 grp->estconnfunc = NULL;
559 grp->port_persist = 0;
560 grp->send_qllc_disc = 0;
561 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
562
563 ctcm_close(dev);
564done:
565 ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__);
566 return;
567}
568EXPORT_SYMBOL(ctc_mpc_dealloc_ch);
569
570/*
571 * ctc_mpc_flow_control
572 * (exported interface)
573 */
574void ctc_mpc_flow_control(int port_num, int flowc)
575{
576 char device[20];
577 struct ctcm_priv *priv;
578 struct mpc_group *grp;
579 struct net_device *dev;
580 struct channel *rch;
581 int mpcg_state;
582
583 ctcm_pr_debug("ctcmpc enter: %s() %i\n", __FUNCTION__, flowc);
584
585 sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num);
586 dev = __dev_get_by_name(&init_net, device);
587
588 if (dev == NULL) {
589 printk(KERN_INFO "ctc_mpc_flow_control %s dev=NULL\n", device);
590 return;
591 }
592
593 ctcm_pr_debug("ctcmpc: %s %s called \n", dev->name, __FUNCTION__);
594
595 priv = dev->priv;
596 if (priv == NULL) {
597 printk(KERN_INFO "ctcmpc:%s() %s priv=NULL\n",
598 __FUNCTION__, device);
599 return;
600 }
601 grp = priv->mpcg;
602 rch = priv->channel[READ];
603
604 mpcg_state = fsm_getstate(grp->fsm);
605 switch (flowc) {
606 case 1:
607 if (mpcg_state == MPCG_STATE_FLOWC)
608 break;
609 if (mpcg_state == MPCG_STATE_READY) {
610 if (grp->flow_off_called == 1)
611 grp->flow_off_called = 0;
612 else
613 fsm_newstate(grp->fsm, MPCG_STATE_FLOWC);
614 break;
615 }
616 break;
617 case 0:
618 if (mpcg_state == MPCG_STATE_FLOWC) {
619 fsm_newstate(grp->fsm, MPCG_STATE_READY);
620 /* ensure any data that has accumulated */
621 /* on the io_queue will now be sen t */
622 tasklet_schedule(&rch->ch_tasklet);
623 }
624 /* possible race condition */
625 if (mpcg_state == MPCG_STATE_READY) {
626 grp->flow_off_called = 1;
627 break;
628 }
629 break;
630 }
631
632 ctcm_pr_debug("ctcmpc exit: %s() %i\n", __FUNCTION__, flowc);
633}
634EXPORT_SYMBOL(ctc_mpc_flow_control);
635
636static int mpc_send_qllc_discontact(struct net_device *);
637
638/*
639 * helper function of ctcmpc_unpack_skb
640*/
641static void mpc_rcvd_sweep_resp(struct mpcg_info *mpcginfo)
642{
643 struct channel *rch = mpcginfo->ch;
644 struct net_device *dev = rch->netdev;
645 struct ctcm_priv *priv = dev->priv;
646 struct mpc_group *grp = priv->mpcg;
647 struct channel *ch = priv->channel[WRITE];
648
649 if (do_debug)
650 ctcm_pr_debug("ctcmpc enter: %s(): ch=0x%p id=%s\n",
651 __FUNCTION__, ch, ch->id);
652
653 if (do_debug_data)
654 ctcmpc_dumpit((char *)mpcginfo->sweep, TH_SWEEP_LENGTH);
655
656 grp->sweep_rsp_pend_num--;
657
658 if ((grp->sweep_req_pend_num == 0) &&
659 (grp->sweep_rsp_pend_num == 0)) {
660 fsm_deltimer(&ch->sweep_timer);
661 grp->in_sweep = 0;
662 rch->th_seq_num = 0x00;
663 ch->th_seq_num = 0x00;
664 ctcm_clear_busy_do(dev);
665 }
666
667 kfree(mpcginfo);
668
669 return;
670
671}
672
673/*
674 * helper function of mpc_rcvd_sweep_req
675 * which is a helper of ctcmpc_unpack_skb
676 */
677static void ctcmpc_send_sweep_resp(struct channel *rch)
678{
679 struct net_device *dev = rch->netdev;
680 struct ctcm_priv *priv = dev->priv;
681 struct mpc_group *grp = priv->mpcg;
682 int rc = 0;
683 struct th_sweep *header;
684 struct sk_buff *sweep_skb;
685 struct channel *ch = priv->channel[WRITE];
686
687 if (do_debug)
688 ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
689 __FUNCTION__, rch, rch->id);
690
691 sweep_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT,
692 GFP_ATOMIC|GFP_DMA);
693 if (sweep_skb == NULL) {
694 printk(KERN_INFO "Couldn't alloc sweep_skb\n");
695 rc = -ENOMEM;
696 goto done;
697 }
698
699 header = (struct th_sweep *)
700 kmalloc(sizeof(struct th_sweep), gfp_type());
701
702 if (!header) {
703 dev_kfree_skb_any(sweep_skb);
704 rc = -ENOMEM;
705 goto done;
706 }
707
708 header->th.th_seg = 0x00 ;
709 header->th.th_ch_flag = TH_SWEEP_RESP;
710 header->th.th_blk_flag = 0x00;
711 header->th.th_is_xid = 0x00;
712 header->th.th_seq_num = 0x00;
713 header->sw.th_last_seq = ch->th_seq_num;
714
715 memcpy(skb_put(sweep_skb, TH_SWEEP_LENGTH), header, TH_SWEEP_LENGTH);
716
717 kfree(header);
718
719 dev->trans_start = jiffies;
720 skb_queue_tail(&ch->sweep_queue, sweep_skb);
721
722 fsm_addtimer(&ch->sweep_timer, 100, CTC_EVENT_RSWEEP_TIMER, ch);
723
724 return;
725
726done:
727 if (rc != 0) {
728 grp->in_sweep = 0;
729 ctcm_clear_busy_do(dev);
730 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
731 }
732
733 return;
734}
735
736/*
737 * helper function of ctcmpc_unpack_skb
738 */
739static void mpc_rcvd_sweep_req(struct mpcg_info *mpcginfo)
740{
741 struct channel *rch = mpcginfo->ch;
742 struct net_device *dev = rch->netdev;
743 struct ctcm_priv *priv = dev->priv;
744 struct mpc_group *grp = priv->mpcg;
745 struct channel *ch = priv->channel[WRITE];
746
747 if (do_debug)
748 CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG,
749 " %s(): ch=0x%p id=%s\n", __FUNCTION__, ch, ch->id);
750
751 if (grp->in_sweep == 0) {
752 grp->in_sweep = 1;
753 ctcm_test_and_set_busy(dev);
754 grp->sweep_req_pend_num = grp->active_channels[READ];
755 grp->sweep_rsp_pend_num = grp->active_channels[READ];
756 }
757
758 if (do_debug_data)
759 ctcmpc_dumpit((char *)mpcginfo->sweep, TH_SWEEP_LENGTH);
760
761 grp->sweep_req_pend_num--;
762 ctcmpc_send_sweep_resp(ch);
763 kfree(mpcginfo);
764 return;
765}
766
767/*
768 * MPC Group Station FSM definitions
769 */
770static const char *mpcg_event_names[] = {
771 [MPCG_EVENT_INOP] = "INOP Condition",
772 [MPCG_EVENT_DISCONC] = "Discontact Received",
773 [MPCG_EVENT_XID0DO] = "Channel Active - Start XID",
774 [MPCG_EVENT_XID2] = "XID2 Received",
775 [MPCG_EVENT_XID2DONE] = "XID0 Complete",
776 [MPCG_EVENT_XID7DONE] = "XID7 Complete",
777 [MPCG_EVENT_TIMER] = "XID Setup Timer",
778 [MPCG_EVENT_DOIO] = "XID DoIO",
779};
780
781static const char *mpcg_state_names[] = {
782 [MPCG_STATE_RESET] = "Reset",
783 [MPCG_STATE_INOP] = "INOP",
784 [MPCG_STATE_XID2INITW] = "Passive XID- XID0 Pending Start",
785 [MPCG_STATE_XID2INITX] = "Passive XID- XID0 Pending Complete",
786 [MPCG_STATE_XID7INITW] = "Passive XID- XID7 Pending P1 Start",
787 [MPCG_STATE_XID7INITX] = "Passive XID- XID7 Pending P2 Complete",
788 [MPCG_STATE_XID0IOWAIT] = "Active XID- XID0 Pending Start",
789 [MPCG_STATE_XID0IOWAIX] = "Active XID- XID0 Pending Complete",
790 [MPCG_STATE_XID7INITI] = "Active XID- XID7 Pending Start",
791 [MPCG_STATE_XID7INITZ] = "Active XID- XID7 Pending Complete ",
792 [MPCG_STATE_XID7INITF] = "XID - XID7 Complete ",
793 [MPCG_STATE_FLOWC] = "FLOW CONTROL ON",
794 [MPCG_STATE_READY] = "READY",
795};
796
797/*
798 * The MPC Group Station FSM
799 * 22 events
800 */
801static const fsm_node mpcg_fsm[] = {
802 { MPCG_STATE_RESET, MPCG_EVENT_INOP, mpc_action_go_inop },
803 { MPCG_STATE_INOP, MPCG_EVENT_INOP, mpc_action_nop },
804 { MPCG_STATE_FLOWC, MPCG_EVENT_INOP, mpc_action_go_inop },
805
806 { MPCG_STATE_READY, MPCG_EVENT_DISCONC, mpc_action_discontact },
807 { MPCG_STATE_READY, MPCG_EVENT_INOP, mpc_action_go_inop },
808
809 { MPCG_STATE_XID2INITW, MPCG_EVENT_XID0DO, mpc_action_doxid0 },
810 { MPCG_STATE_XID2INITW, MPCG_EVENT_XID2, mpc_action_rcvd_xid0 },
811 { MPCG_STATE_XID2INITW, MPCG_EVENT_INOP, mpc_action_go_inop },
812 { MPCG_STATE_XID2INITW, MPCG_EVENT_TIMER, mpc_action_timeout },
813 { MPCG_STATE_XID2INITW, MPCG_EVENT_DOIO, mpc_action_yside_xid },
814
815 { MPCG_STATE_XID2INITX, MPCG_EVENT_XID0DO, mpc_action_doxid0 },
816 { MPCG_STATE_XID2INITX, MPCG_EVENT_XID2, mpc_action_rcvd_xid0 },
817 { MPCG_STATE_XID2INITX, MPCG_EVENT_INOP, mpc_action_go_inop },
818 { MPCG_STATE_XID2INITX, MPCG_EVENT_TIMER, mpc_action_timeout },
819 { MPCG_STATE_XID2INITX, MPCG_EVENT_DOIO, mpc_action_yside_xid },
820
821 { MPCG_STATE_XID7INITW, MPCG_EVENT_XID2DONE, mpc_action_doxid7 },
822 { MPCG_STATE_XID7INITW, MPCG_EVENT_DISCONC, mpc_action_discontact },
823 { MPCG_STATE_XID7INITW, MPCG_EVENT_XID2, mpc_action_rcvd_xid7 },
824 { MPCG_STATE_XID7INITW, MPCG_EVENT_INOP, mpc_action_go_inop },
825 { MPCG_STATE_XID7INITW, MPCG_EVENT_TIMER, mpc_action_timeout },
826 { MPCG_STATE_XID7INITW, MPCG_EVENT_XID7DONE, mpc_action_doxid7 },
827 { MPCG_STATE_XID7INITW, MPCG_EVENT_DOIO, mpc_action_yside_xid },
828
829 { MPCG_STATE_XID7INITX, MPCG_EVENT_DISCONC, mpc_action_discontact },
830 { MPCG_STATE_XID7INITX, MPCG_EVENT_XID2, mpc_action_rcvd_xid7 },
831 { MPCG_STATE_XID7INITX, MPCG_EVENT_INOP, mpc_action_go_inop },
832 { MPCG_STATE_XID7INITX, MPCG_EVENT_XID7DONE, mpc_action_doxid7 },
833 { MPCG_STATE_XID7INITX, MPCG_EVENT_TIMER, mpc_action_timeout },
834 { MPCG_STATE_XID7INITX, MPCG_EVENT_DOIO, mpc_action_yside_xid },
835
836 { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_XID0DO, mpc_action_doxid0 },
837 { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_DISCONC, mpc_action_discontact },
838 { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_XID2, mpc_action_rcvd_xid0 },
839 { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_INOP, mpc_action_go_inop },
840 { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_TIMER, mpc_action_timeout },
841 { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_DOIO, mpc_action_xside_xid },
842
843 { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_XID0DO, mpc_action_doxid0 },
844 { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_DISCONC, mpc_action_discontact },
845 { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_XID2, mpc_action_rcvd_xid0 },
846 { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_INOP, mpc_action_go_inop },
847 { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_TIMER, mpc_action_timeout },
848 { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_DOIO, mpc_action_xside_xid },
849
850 { MPCG_STATE_XID7INITI, MPCG_EVENT_XID2DONE, mpc_action_doxid7 },
851 { MPCG_STATE_XID7INITI, MPCG_EVENT_XID2, mpc_action_rcvd_xid7 },
852 { MPCG_STATE_XID7INITI, MPCG_EVENT_DISCONC, mpc_action_discontact },
853 { MPCG_STATE_XID7INITI, MPCG_EVENT_INOP, mpc_action_go_inop },
854 { MPCG_STATE_XID7INITI, MPCG_EVENT_TIMER, mpc_action_timeout },
855 { MPCG_STATE_XID7INITI, MPCG_EVENT_XID7DONE, mpc_action_doxid7 },
856 { MPCG_STATE_XID7INITI, MPCG_EVENT_DOIO, mpc_action_xside_xid },
857
858 { MPCG_STATE_XID7INITZ, MPCG_EVENT_XID2, mpc_action_rcvd_xid7 },
859 { MPCG_STATE_XID7INITZ, MPCG_EVENT_XID7DONE, mpc_action_doxid7 },
860 { MPCG_STATE_XID7INITZ, MPCG_EVENT_DISCONC, mpc_action_discontact },
861 { MPCG_STATE_XID7INITZ, MPCG_EVENT_INOP, mpc_action_go_inop },
862 { MPCG_STATE_XID7INITZ, MPCG_EVENT_TIMER, mpc_action_timeout },
863 { MPCG_STATE_XID7INITZ, MPCG_EVENT_DOIO, mpc_action_xside_xid },
864
865 { MPCG_STATE_XID7INITF, MPCG_EVENT_INOP, mpc_action_go_inop },
866 { MPCG_STATE_XID7INITF, MPCG_EVENT_XID7DONE, mpc_action_go_ready },
867};
868
869static int mpcg_fsm_len = ARRAY_SIZE(mpcg_fsm);
870
871/*
872 * MPC Group Station FSM action
873 * CTCM_PROTO_MPC only
874 */
875static void mpc_action_go_ready(fsm_instance *fsm, int event, void *arg)
876{
877 struct net_device *dev = arg;
878 struct ctcm_priv *priv = NULL;
879 struct mpc_group *grp = NULL;
880
881 if (dev == NULL) {
882 printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
883 return;
884 }
885
886 ctcm_pr_debug("ctcmpc enter: %s %s()\n", dev->name, __FUNCTION__);
887
888 priv = dev->priv;
889 if (priv == NULL) {
890 printk(KERN_INFO "%s() priv=NULL\n", __FUNCTION__);
891 return;
892 }
893
894 grp = priv->mpcg;
895 if (grp == NULL) {
896 printk(KERN_INFO "%s() grp=NULL\n", __FUNCTION__);
897 return;
898 }
899
900 fsm_deltimer(&grp->timer);
901
902 if (grp->saved_xid2->xid2_flag2 == 0x40) {
903 priv->xid->xid2_flag2 = 0x00;
904 if (grp->estconnfunc) {
905 grp->estconnfunc(grp->port_num, 1,
906 grp->group_max_buflen);
907 grp->estconnfunc = NULL;
908 } else if (grp->allochanfunc)
909 grp->send_qllc_disc = 1;
910 goto done;
911 }
912
913 grp->port_persist = 1;
914 grp->out_of_sequence = 0;
915 grp->estconn_called = 0;
916
917 tasklet_hi_schedule(&grp->mpc_tasklet2);
918
919 ctcm_pr_debug("ctcmpc exit: %s %s()\n", dev->name, __FUNCTION__);
920 return;
921
922done:
923 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
924
925
926 ctcm_pr_info("ctcmpc: %s()failure occurred\n", __FUNCTION__);
927}
928
929/*
930 * helper of ctcm_init_netdevice
931 * CTCM_PROTO_MPC only
932 */
933void mpc_group_ready(unsigned long adev)
934{
935 struct net_device *dev = (struct net_device *)adev;
936 struct ctcm_priv *priv = NULL;
937 struct mpc_group *grp = NULL;
938 struct channel *ch = NULL;
939
940
941 ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__);
942
943 if (dev == NULL) {
944 printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
945 return;
946 }
947
948 priv = dev->priv;
949 if (priv == NULL) {
950 printk(KERN_INFO "%s() priv=NULL\n", __FUNCTION__);
951 return;
952 }
953
954 grp = priv->mpcg;
955 if (grp == NULL) {
956 printk(KERN_INFO "ctcmpc:%s() grp=NULL\n", __FUNCTION__);
957 return;
958 }
959
960 printk(KERN_NOTICE "ctcmpc: %s GROUP TRANSITIONED TO READY"
961 " maxbuf:%d\n",
962 dev->name, grp->group_max_buflen);
963
964 fsm_newstate(grp->fsm, MPCG_STATE_READY);
965
966 /* Put up a read on the channel */
967 ch = priv->channel[READ];
968 ch->pdu_seq = 0;
969 if (do_debug_data)
970 ctcm_pr_debug("ctcmpc: %s() ToDCM_pdu_seq= %08x\n" ,
971 __FUNCTION__, ch->pdu_seq);
972
973 ctcmpc_chx_rxidle(ch->fsm, CTC_EVENT_START, ch);
974 /* Put the write channel in idle state */
975 ch = priv->channel[WRITE];
976 if (ch->collect_len > 0) {
977 spin_lock(&ch->collect_lock);
978 ctcm_purge_skb_queue(&ch->collect_queue);
979 ch->collect_len = 0;
980 spin_unlock(&ch->collect_lock);
981 }
982 ctcm_chx_txidle(ch->fsm, CTC_EVENT_START, ch);
983
984 ctcm_clear_busy(dev);
985
986 if (grp->estconnfunc) {
987 grp->estconnfunc(grp->port_num, 0,
988 grp->group_max_buflen);
989 grp->estconnfunc = NULL;
990 } else
991 if (grp->allochanfunc)
992 grp->allochanfunc(grp->port_num,
993 grp->group_max_buflen);
994
995 grp->send_qllc_disc = 1;
996 grp->changed_side = 0;
997
998 ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__);
999 return;
1000
1001}
1002
1003/*
1004 * Increment the MPC Group Active Channel Counts
1005 * helper of dev_action (called from channel fsm)
1006 */
1007int mpc_channel_action(struct channel *ch, int direction, int action)
1008{
1009 struct net_device *dev = ch->netdev;
1010 struct ctcm_priv *priv;
1011 struct mpc_group *grp = NULL;
1012 int rc = 0;
1013
1014 if (do_debug)
1015 ctcm_pr_debug("ctcmpc enter: %s(): ch=0x%p id=%s\n",
1016 __FUNCTION__, ch, ch->id);
1017
1018 if (dev == NULL) {
1019 printk(KERN_INFO "ctcmpc_channel_action %i dev=NULL\n",
1020 action);
1021 rc = 1;
1022 goto done;
1023 }
1024
1025 priv = dev->priv;
1026 if (priv == NULL) {
1027 printk(KERN_INFO
1028 "ctcmpc_channel_action%i priv=NULL, dev=%s\n",
1029 action, dev->name);
1030 rc = 2;
1031 goto done;
1032 }
1033
1034 grp = priv->mpcg;
1035
1036 if (grp == NULL) {
1037 printk(KERN_INFO "ctcmpc: %s()%i mpcgroup=NULL, dev=%s\n",
1038 __FUNCTION__, action, dev->name);
1039 rc = 3;
1040 goto done;
1041 }
1042
1043 ctcm_pr_info(
1044 "ctcmpc: %s() %i(): Grp:%s total_channel_paths=%i "
1045 "active_channels read=%i, write=%i\n",
1046 __FUNCTION__,
1047 action,
1048 fsm_getstate_str(grp->fsm),
1049 grp->num_channel_paths,
1050 grp->active_channels[READ],
1051 grp->active_channels[WRITE]);
1052
1053 if ((action == MPC_CHANNEL_ADD) && (ch->in_mpcgroup == 0)) {
1054 grp->num_channel_paths++;
1055 grp->active_channels[direction]++;
1056 grp->outstanding_xid2++;
1057 ch->in_mpcgroup = 1;
1058
1059 if (ch->xid_skb != NULL)
1060 dev_kfree_skb_any(ch->xid_skb);
1061
1062 ch->xid_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT,
1063 GFP_ATOMIC | GFP_DMA);
1064 if (ch->xid_skb == NULL) {
1065 printk(KERN_INFO "ctcmpc: %s()"
1066 "Couldn't alloc ch xid_skb\n", __FUNCTION__);
1067 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1068 return 1;
1069 }
1070 ch->xid_skb_data = ch->xid_skb->data;
1071 ch->xid_th = (struct th_header *)ch->xid_skb->data;
1072 skb_put(ch->xid_skb, TH_HEADER_LENGTH);
1073 ch->xid = (struct xid2 *)skb_tail_pointer(ch->xid_skb);
1074 skb_put(ch->xid_skb, XID2_LENGTH);
1075 ch->xid_id = skb_tail_pointer(ch->xid_skb);
1076 ch->xid_skb->data = ch->xid_skb_data;
1077 skb_reset_tail_pointer(ch->xid_skb);
1078 ch->xid_skb->len = 0;
1079
1080 memcpy(skb_put(ch->xid_skb, grp->xid_skb->len),
1081 grp->xid_skb->data,
1082 grp->xid_skb->len);
1083
1084 ch->xid->xid2_dlc_type = ((CHANNEL_DIRECTION(ch->flags) == READ)
1085 ? XID2_READ_SIDE : XID2_WRITE_SIDE);
1086
1087 if (CHANNEL_DIRECTION(ch->flags) == WRITE)
1088 ch->xid->xid2_buf_len = 0x00;
1089
1090 ch->xid_skb->data = ch->xid_skb_data;
1091 skb_reset_tail_pointer(ch->xid_skb);
1092 ch->xid_skb->len = 0;
1093
1094 fsm_newstate(ch->fsm, CH_XID0_PENDING);
1095
1096 if ((grp->active_channels[READ] > 0) &&
1097 (grp->active_channels[WRITE] > 0) &&
1098 (fsm_getstate(grp->fsm) < MPCG_STATE_XID2INITW)) {
1099 fsm_newstate(grp->fsm, MPCG_STATE_XID2INITW);
1100 printk(KERN_NOTICE "ctcmpc: %s MPC GROUP "
1101 "CHANNELS ACTIVE\n", dev->name);
1102 }
1103 } else if ((action == MPC_CHANNEL_REMOVE) &&
1104 (ch->in_mpcgroup == 1)) {
1105 ch->in_mpcgroup = 0;
1106 grp->num_channel_paths--;
1107 grp->active_channels[direction]--;
1108
1109 if (ch->xid_skb != NULL)
1110 dev_kfree_skb_any(ch->xid_skb);
1111 ch->xid_skb = NULL;
1112
1113 if (grp->channels_terminating)
1114 goto done;
1115
1116 if (((grp->active_channels[READ] == 0) &&
1117 (grp->active_channels[WRITE] > 0))
1118 || ((grp->active_channels[WRITE] == 0) &&
1119 (grp->active_channels[READ] > 0)))
1120 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1121 }
1122
1123done:
1124
1125 if (do_debug) {
1126 ctcm_pr_debug(
1127 "ctcmpc: %s() %i Grp:%s ttl_chan_paths=%i "
1128 "active_chans read=%i, write=%i\n",
1129 __FUNCTION__,
1130 action,
1131 fsm_getstate_str(grp->fsm),
1132 grp->num_channel_paths,
1133 grp->active_channels[READ],
1134 grp->active_channels[WRITE]);
1135
1136 ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
1137 __FUNCTION__, ch, ch->id);
1138 }
1139 return rc;
1140
1141}
1142
1143/**
1144 * Unpack a just received skb and hand it over to
1145 * upper layers.
1146 * special MPC version of unpack_skb.
1147 *
1148 * ch The channel where this skb has been received.
1149 * pskb The received skb.
1150 */
1151static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
1152{
1153 struct net_device *dev = ch->netdev;
1154 struct ctcm_priv *priv = dev->priv;
1155 struct mpc_group *grp = priv->mpcg;
1156 struct pdu *curr_pdu;
1157 struct mpcg_info *mpcginfo;
1158 struct th_header *header = NULL;
1159 struct th_sweep *sweep = NULL;
1160 int pdu_last_seen = 0;
1161 __u32 new_len;
1162 struct sk_buff *skb;
1163 int skblen;
1164 int sendrc = 0;
1165
1166 if (do_debug)
1167 ctcm_pr_debug("ctcmpc enter: %s() %s cp:%i ch:%s\n",
1168 __FUNCTION__, dev->name, smp_processor_id(), ch->id);
1169
1170 header = (struct th_header *)pskb->data;
1171 if ((header->th_seg == 0) &&
1172 (header->th_ch_flag == 0) &&
1173 (header->th_blk_flag == 0) &&
1174 (header->th_seq_num == 0))
1175 /* nothing for us */ goto done;
1176
1177 if (do_debug_data) {
1178 ctcm_pr_debug("ctcmpc: %s() th_header\n", __FUNCTION__);
1179 ctcmpc_dumpit((char *)header, TH_HEADER_LENGTH);
1180 ctcm_pr_debug("ctcmpc: %s() pskb len: %04x \n",
1181 __FUNCTION__, pskb->len);
1182 }
1183
1184 pskb->dev = dev;
1185 pskb->ip_summed = CHECKSUM_UNNECESSARY;
1186 skb_pull(pskb, TH_HEADER_LENGTH);
1187
1188 if (likely(header->th_ch_flag == TH_HAS_PDU)) {
1189 if (do_debug_data)
1190 ctcm_pr_debug("ctcmpc: %s() came into th_has_pdu\n",
1191 __FUNCTION__);
1192 if ((fsm_getstate(grp->fsm) == MPCG_STATE_FLOWC) ||
1193 ((fsm_getstate(grp->fsm) == MPCG_STATE_READY) &&
1194 (header->th_seq_num != ch->th_seq_num + 1) &&
1195 (ch->th_seq_num != 0))) {
1196 /* This is NOT the next segment *
1197 * we are not the correct race winner *
1198 * go away and let someone else win *
1199 * BUT..this only applies if xid negot *
1200 * is done *
1201 */
1202 grp->out_of_sequence += 1;
1203 __skb_push(pskb, TH_HEADER_LENGTH);
1204 skb_queue_tail(&ch->io_queue, pskb);
1205 if (do_debug_data)
1206 ctcm_pr_debug("ctcmpc: %s() th_seq_num "
1207 "expect:%08x got:%08x\n", __FUNCTION__,
1208 ch->th_seq_num + 1, header->th_seq_num);
1209
1210 return;
1211 }
1212 grp->out_of_sequence = 0;
1213 ch->th_seq_num = header->th_seq_num;
1214
1215 if (do_debug_data)
1216 ctcm_pr_debug("ctcmpc: %s() FromVTAM_th_seq=%08x\n",
1217 __FUNCTION__, ch->th_seq_num);
1218
1219 if (unlikely(fsm_getstate(grp->fsm) != MPCG_STATE_READY))
1220 goto done;
1221 pdu_last_seen = 0;
1222 while ((pskb->len > 0) && !pdu_last_seen) {
1223 curr_pdu = (struct pdu *)pskb->data;
1224 if (do_debug_data) {
1225 ctcm_pr_debug("ctcm: %s() pdu_header\n",
1226 __FUNCTION__);
1227 ctcmpc_dumpit((char *)pskb->data,
1228 PDU_HEADER_LENGTH);
1229 ctcm_pr_debug("ctcm: %s() pskb len: %04x \n",
1230 __FUNCTION__, pskb->len);
1231 }
1232 skb_pull(pskb, PDU_HEADER_LENGTH);
1233
1234 if (curr_pdu->pdu_flag & PDU_LAST)
1235 pdu_last_seen = 1;
1236 if (curr_pdu->pdu_flag & PDU_CNTL)
1237 pskb->protocol = htons(ETH_P_SNAP);
1238 else
1239 pskb->protocol = htons(ETH_P_SNA_DIX);
1240
1241 if ((pskb->len <= 0) || (pskb->len > ch->max_bufsize)) {
1242 printk(KERN_INFO
1243 "%s Illegal packet size %d "
1244 "received "
1245 "dropping\n", dev->name,
1246 pskb->len);
1247 priv->stats.rx_dropped++;
1248 priv->stats.rx_length_errors++;
1249 goto done;
1250 }
1251 skb_reset_mac_header(pskb);
1252 new_len = curr_pdu->pdu_offset;
1253 if (do_debug_data)
1254 ctcm_pr_debug("ctcmpc: %s() new_len: %04x \n",
1255 __FUNCTION__, new_len);
1256 if ((new_len == 0) || (new_len > pskb->len)) {
1257 /* should never happen */
1258 /* pskb len must be hosed...bail out */
1259 printk(KERN_INFO
1260 "ctcmpc: %s(): invalid pdu"
1261 " offset of %04x - data may be"
1262 "lost\n", __FUNCTION__, new_len);
1263 goto done;
1264 }
1265 skb = __dev_alloc_skb(new_len+4, GFP_ATOMIC);
1266
1267 if (!skb) {
1268 printk(KERN_INFO
1269 "ctcm: %s Out of memory in "
1270 "%s()- request-len:%04x \n",
1271 dev->name,
1272 __FUNCTION__,
1273 new_len+4);
1274 priv->stats.rx_dropped++;
1275 fsm_event(grp->fsm,
1276 MPCG_EVENT_INOP, dev);
1277 goto done;
1278 }
1279
1280 memcpy(skb_put(skb, new_len),
1281 pskb->data, new_len);
1282
1283 skb_reset_mac_header(skb);
1284 skb->dev = pskb->dev;
1285 skb->protocol = pskb->protocol;
1286 skb->ip_summed = CHECKSUM_UNNECESSARY;
1287 *((__u32 *) skb_push(skb, 4)) = ch->pdu_seq;
1288 ch->pdu_seq++;
1289
1290 if (do_debug_data)
1291 ctcm_pr_debug("%s: ToDCM_pdu_seq= %08x\n",
1292 __FUNCTION__, ch->pdu_seq);
1293
1294 ctcm_pr_debug("ctcm: %s() skb:%0lx "
1295 "skb len: %d \n", __FUNCTION__,
1296 (unsigned long)skb, skb->len);
1297 if (do_debug_data) {
1298 ctcm_pr_debug("ctcmpc: %s() up to 32 bytes"
1299 " of pdu_data sent\n",
1300 __FUNCTION__);
1301 ctcmpc_dump32((char *)skb->data, skb->len);
1302 }
1303
1304 skblen = skb->len;
1305 sendrc = netif_rx(skb);
1306 priv->stats.rx_packets++;
1307 priv->stats.rx_bytes += skblen;
1308 skb_pull(pskb, new_len); /* point to next PDU */
1309 }
1310 } else {
1311 mpcginfo = (struct mpcg_info *)
1312 kmalloc(sizeof(struct mpcg_info), gfp_type());
1313 if (mpcginfo == NULL)
1314 goto done;
1315
1316 mpcginfo->ch = ch;
1317 mpcginfo->th = header;
1318 mpcginfo->skb = pskb;
1319 ctcm_pr_debug("ctcmpc: %s() Not PDU - may be control pkt\n",
1320 __FUNCTION__);
1321 /* it's a sweep? */
1322 sweep = (struct th_sweep *)pskb->data;
1323 mpcginfo->sweep = sweep;
1324 if (header->th_ch_flag == TH_SWEEP_REQ)
1325 mpc_rcvd_sweep_req(mpcginfo);
1326 else if (header->th_ch_flag == TH_SWEEP_RESP)
1327 mpc_rcvd_sweep_resp(mpcginfo);
1328 else if (header->th_blk_flag == TH_DATA_IS_XID) {
1329 struct xid2 *thisxid = (struct xid2 *)pskb->data;
1330 skb_pull(pskb, XID2_LENGTH);
1331 mpcginfo->xid = thisxid;
1332 fsm_event(grp->fsm, MPCG_EVENT_XID2, mpcginfo);
1333 } else if (header->th_blk_flag == TH_DISCONTACT)
1334 fsm_event(grp->fsm, MPCG_EVENT_DISCONC, mpcginfo);
1335 else if (header->th_seq_num != 0) {
1336 printk(KERN_INFO "%s unexpected packet"
1337 " expected control pkt\n", dev->name);
1338 priv->stats.rx_dropped++;
1339 /* mpcginfo only used for non-data transfers */
1340 kfree(mpcginfo);
1341 if (do_debug_data)
1342 ctcmpc_dump_skb(pskb, -8);
1343 }
1344 }
1345done:
1346
1347 dev_kfree_skb_any(pskb);
1348 if (sendrc == NET_RX_DROP) {
1349 printk(KERN_WARNING "%s %s() NETWORK BACKLOG EXCEEDED"
1350 " - PACKET DROPPED\n", dev->name, __FUNCTION__);
1351 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1352 }
1353
1354 if (do_debug)
1355 ctcm_pr_debug("ctcmpc exit : %s %s(): ch=0x%p id=%s\n",
1356 dev->name, __FUNCTION__, ch, ch->id);
1357}
1358
1359/**
1360 * tasklet helper for mpc's skb unpacking.
1361 *
1362 * ch The channel to work on.
1363 * Allow flow control back pressure to occur here.
1364 * Throttling back channel can result in excessive
1365 * channel inactivity and system deact of channel
1366 */
1367void ctcmpc_bh(unsigned long thischan)
1368{
1369 struct channel *ch = (struct channel *)thischan;
1370 struct sk_buff *skb;
1371 struct net_device *dev = ch->netdev;
1372 struct ctcm_priv *priv = dev->priv;
1373 struct mpc_group *grp = priv->mpcg;
1374
1375 if (do_debug)
1376 ctcm_pr_debug("%s cp:%i enter: %s() %s\n",
1377 dev->name, smp_processor_id(), __FUNCTION__, ch->id);
1378 /* caller has requested driver to throttle back */
1379 while ((fsm_getstate(grp->fsm) != MPCG_STATE_FLOWC) &&
1380 (skb = skb_dequeue(&ch->io_queue))) {
1381 ctcmpc_unpack_skb(ch, skb);
1382 if (grp->out_of_sequence > 20) {
1383 /* assume data loss has occurred if */
1384 /* missing seq_num for extended */
1385 /* period of time */
1386 grp->out_of_sequence = 0;
1387 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1388 break;
1389 }
1390 if (skb == skb_peek(&ch->io_queue))
1391 break;
1392 }
1393 if (do_debug)
1394 ctcm_pr_debug("ctcmpc exit : %s %s(): ch=0x%p id=%s\n",
1395 dev->name, __FUNCTION__, ch, ch->id);
1396 return;
1397}
1398
1399/*
1400 * MPC Group Initializations
1401 */
1402struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv)
1403{
1404 struct mpc_group *grp;
1405
1406 CTCM_DBF_TEXT(MPC_SETUP, 3, __FUNCTION__);
1407
1408 grp = kzalloc(sizeof(struct mpc_group), GFP_KERNEL);
1409 if (grp == NULL)
1410 return NULL;
1411
1412 grp->fsm =
1413 init_fsm("mpcg", mpcg_state_names, mpcg_event_names,
1414 MPCG_NR_STATES, MPCG_NR_EVENTS, mpcg_fsm,
1415 mpcg_fsm_len, GFP_KERNEL);
1416 if (grp->fsm == NULL) {
1417 kfree(grp);
1418 return NULL;
1419 }
1420
1421 fsm_newstate(grp->fsm, MPCG_STATE_RESET);
1422 fsm_settimer(grp->fsm, &grp->timer);
1423
1424 grp->xid_skb =
1425 __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC | GFP_DMA);
1426 if (grp->xid_skb == NULL) {
1427 printk(KERN_INFO "Couldn't alloc MPCgroup xid_skb\n");
1428 kfree_fsm(grp->fsm);
1429 kfree(grp);
1430 return NULL;
1431 }
1432 /* base xid for all channels in group */
1433 grp->xid_skb_data = grp->xid_skb->data;
1434 grp->xid_th = (struct th_header *)grp->xid_skb->data;
1435 memcpy(skb_put(grp->xid_skb, TH_HEADER_LENGTH),
1436 &thnorm, TH_HEADER_LENGTH);
1437
1438 grp->xid = (struct xid2 *) skb_tail_pointer(grp->xid_skb);
1439 memcpy(skb_put(grp->xid_skb, XID2_LENGTH), &init_xid, XID2_LENGTH);
1440 grp->xid->xid2_adj_id = jiffies | 0xfff00000;
1441 grp->xid->xid2_sender_id = jiffies;
1442
1443 grp->xid_id = skb_tail_pointer(grp->xid_skb);
1444 memcpy(skb_put(grp->xid_skb, 4), "VTAM", 4);
1445
1446 grp->rcvd_xid_skb =
1447 __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC|GFP_DMA);
1448 if (grp->rcvd_xid_skb == NULL) {
1449 printk(KERN_INFO "Couldn't alloc MPCgroup rcvd_xid_skb\n");
1450 kfree_fsm(grp->fsm);
1451 dev_kfree_skb(grp->xid_skb);
1452 kfree(grp);
1453 return NULL;
1454 }
1455 grp->rcvd_xid_data = grp->rcvd_xid_skb->data;
1456 grp->rcvd_xid_th = (struct th_header *)grp->rcvd_xid_skb->data;
1457 memcpy(skb_put(grp->rcvd_xid_skb, TH_HEADER_LENGTH),
1458 &thnorm, TH_HEADER_LENGTH);
1459 grp->saved_xid2 = NULL;
1460 priv->xid = grp->xid;
1461 priv->mpcg = grp;
1462 return grp;
1463}
1464
1465/*
1466 * The MPC Group Station FSM
1467 */
1468
1469/*
1470 * MPC Group Station FSM actions
1471 * CTCM_PROTO_MPC only
1472 */
1473
1474/**
1475 * NOP action for statemachines
1476 */
1477static void mpc_action_nop(fsm_instance *fi, int event, void *arg)
1478{
1479}
1480
1481/*
1482 * invoked when the device transitions to dev_stopped
1483 * MPC will stop each individual channel if a single XID failure
1484 * occurs, or will intitiate all channels be stopped if a GROUP
1485 * level failure occurs.
1486 */
1487static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
1488{
1489 struct net_device *dev = arg;
1490 struct ctcm_priv *priv;
1491 struct mpc_group *grp;
1492 int rc = 0;
1493 struct channel *wch, *rch;
1494
1495 if (dev == NULL) {
1496 printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
1497 return;
1498 }
1499
1500 ctcm_pr_debug("ctcmpc enter: %s %s()\n", dev->name, __FUNCTION__);
1501
1502 priv = dev->priv;
1503 grp = priv->mpcg;
1504 grp->flow_off_called = 0;
1505
1506 fsm_deltimer(&grp->timer);
1507
1508 if (grp->channels_terminating)
1509 goto done;
1510
1511 grp->channels_terminating = 1;
1512
1513 grp->saved_state = fsm_getstate(grp->fsm);
1514 fsm_newstate(grp->fsm, MPCG_STATE_INOP);
1515 if (grp->saved_state > MPCG_STATE_XID7INITF)
1516 printk(KERN_NOTICE "%s:MPC GROUP INOPERATIVE\n", dev->name);
1517 if ((grp->saved_state != MPCG_STATE_RESET) ||
1518 /* dealloc_channel has been called */
1519 ((grp->saved_state == MPCG_STATE_RESET) &&
1520 (grp->port_persist == 0)))
1521 fsm_deltimer(&priv->restart_timer);
1522
1523 wch = priv->channel[WRITE];
1524 rch = priv->channel[READ];
1525
1526 switch (grp->saved_state) {
1527 case MPCG_STATE_RESET:
1528 case MPCG_STATE_INOP:
1529 case MPCG_STATE_XID2INITW:
1530 case MPCG_STATE_XID0IOWAIT:
1531 case MPCG_STATE_XID2INITX:
1532 case MPCG_STATE_XID7INITW:
1533 case MPCG_STATE_XID7INITX:
1534 case MPCG_STATE_XID0IOWAIX:
1535 case MPCG_STATE_XID7INITI:
1536 case MPCG_STATE_XID7INITZ:
1537 case MPCG_STATE_XID7INITF:
1538 break;
1539 case MPCG_STATE_FLOWC:
1540 case MPCG_STATE_READY:
1541 default:
1542 tasklet_hi_schedule(&wch->ch_disc_tasklet);
1543 }
1544
1545 grp->xid2_tgnum = 0;
1546 grp->group_max_buflen = 0; /*min of all received */
1547 grp->outstanding_xid2 = 0;
1548 grp->outstanding_xid7 = 0;
1549 grp->outstanding_xid7_p2 = 0;
1550 grp->saved_xid2 = NULL;
1551 grp->xidnogood = 0;
1552 grp->changed_side = 0;
1553
1554 grp->rcvd_xid_skb->data = grp->rcvd_xid_data;
1555 skb_reset_tail_pointer(grp->rcvd_xid_skb);
1556 grp->rcvd_xid_skb->len = 0;
1557 grp->rcvd_xid_th = (struct th_header *)grp->rcvd_xid_skb->data;
1558 memcpy(skb_put(grp->rcvd_xid_skb, TH_HEADER_LENGTH), &thnorm,
1559 TH_HEADER_LENGTH);
1560
1561 if (grp->send_qllc_disc == 1) {
1562 grp->send_qllc_disc = 0;
1563 rc = mpc_send_qllc_discontact(dev);
1564 }
1565
1566 /* DO NOT issue DEV_EVENT_STOP directly out of this code */
1567 /* This can result in INOP of VTAM PU due to halting of */
1568 /* outstanding IO which causes a sense to be returned */
1569 /* Only about 3 senses are allowed and then IOS/VTAM will*/
1570 /* ebcome unreachable without manual intervention */
1571 if ((grp->port_persist == 1) || (grp->alloc_called)) {
1572 grp->alloc_called = 0;
1573 fsm_deltimer(&priv->restart_timer);
1574 fsm_addtimer(&priv->restart_timer,
1575 500,
1576 DEV_EVENT_RESTART,
1577 dev);
1578 fsm_newstate(grp->fsm, MPCG_STATE_RESET);
1579 if (grp->saved_state > MPCG_STATE_XID7INITF)
1580 printk(KERN_NOTICE "%s:MPC GROUP RECOVERY SCHEDULED\n",
1581 dev->name);
1582 } else {
1583 fsm_deltimer(&priv->restart_timer);
1584 fsm_addtimer(&priv->restart_timer, 500, DEV_EVENT_STOP, dev);
1585 fsm_newstate(grp->fsm, MPCG_STATE_RESET);
1586 printk(KERN_NOTICE "%s:MPC GROUP RECOVERY NOT ATTEMPTED\n",
1587 dev->name);
1588 }
1589
1590done:
1591 ctcm_pr_debug("ctcmpc exit:%s %s()\n", dev->name, __FUNCTION__);
1592 return;
1593}
1594
1595/**
1596 * Handle mpc group action timeout.
1597 * MPC Group Station FSM action
1598 * CTCM_PROTO_MPC only
1599 *
1600 * fi An instance of an mpc_group fsm.
1601 * event The event, just happened.
1602 * arg Generic pointer, casted from net_device * upon call.
1603 */
1604static void mpc_action_timeout(fsm_instance *fi, int event, void *arg)
1605{
1606 struct net_device *dev = arg;
1607 struct ctcm_priv *priv;
1608 struct mpc_group *grp;
1609 struct channel *wch;
1610 struct channel *rch;
1611
1612 CTCM_DBF_TEXT(MPC_TRACE, 6, __FUNCTION__);
1613
1614 if (dev == NULL) {
1615 CTCM_DBF_TEXT_(MPC_ERROR, 4, "%s: dev=NULL\n", __FUNCTION__);
1616 return;
1617 }
1618
1619 priv = dev->priv;
1620 grp = priv->mpcg;
1621 wch = priv->channel[WRITE];
1622 rch = priv->channel[READ];
1623
1624 switch (fsm_getstate(grp->fsm)) {
1625 case MPCG_STATE_XID2INITW:
1626 /* Unless there is outstanding IO on the */
1627 /* channel just return and wait for ATTN */
1628 /* interrupt to begin XID negotiations */
1629 if ((fsm_getstate(rch->fsm) == CH_XID0_PENDING) &&
1630 (fsm_getstate(wch->fsm) == CH_XID0_PENDING))
1631 break;
1632 default:
1633 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1634 }
1635
1636 CTCM_DBF_TEXT_(MPC_TRACE, 6, "%s: dev=%s exit",
1637 __FUNCTION__, dev->name);
1638 return;
1639}
1640
1641/*
1642 * MPC Group Station FSM action
1643 * CTCM_PROTO_MPC only
1644 */
1645void mpc_action_discontact(fsm_instance *fi, int event, void *arg)
1646{
1647 struct mpcg_info *mpcginfo = arg;
1648 struct channel *ch = mpcginfo->ch;
1649 struct net_device *dev = ch->netdev;
1650 struct ctcm_priv *priv = dev->priv;
1651 struct mpc_group *grp = priv->mpcg;
1652
1653 if (ch == NULL) {
1654 printk(KERN_INFO "%s() ch=NULL\n", __FUNCTION__);
1655 return;
1656 }
1657 if (ch->netdev == NULL) {
1658 printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
1659 return;
1660 }
1661
1662 ctcm_pr_debug("ctcmpc enter: %s %s()\n", dev->name, __FUNCTION__);
1663
1664 grp->send_qllc_disc = 1;
1665 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1666
1667 ctcm_pr_debug("ctcmpc exit: %s %s()\n", dev->name, __FUNCTION__);
1668 return;
1669}
1670
1671/*
1672 * MPC Group Station - not part of FSM
1673 * CTCM_PROTO_MPC only
1674 * called from add_channel in ctcm_main.c
1675 */
1676void mpc_action_send_discontact(unsigned long thischan)
1677{
1678 struct channel *ch;
1679 struct net_device *dev;
1680 struct ctcm_priv *priv;
1681 struct mpc_group *grp;
1682 int rc = 0;
1683 unsigned long saveflags;
1684
1685 ch = (struct channel *)thischan;
1686 dev = ch->netdev;
1687 priv = dev->priv;
1688 grp = priv->mpcg;
1689
1690 ctcm_pr_info("ctcmpc: %s cp:%i enter: %s() GrpState:%s ChState:%s\n",
1691 dev->name,
1692 smp_processor_id(),
1693 __FUNCTION__,
1694 fsm_getstate_str(grp->fsm),
1695 fsm_getstate_str(ch->fsm));
1696 saveflags = 0; /* avoids compiler warning with
1697 spin_unlock_irqrestore */
1698
1699 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
1700 rc = ccw_device_start(ch->cdev, &ch->ccw[15],
1701 (unsigned long)ch, 0xff, 0);
1702 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
1703
1704 if (rc != 0) {
1705 ctcm_pr_info("ctcmpc: %s() ch:%s IO failed \n",
1706 __FUNCTION__,
1707 ch->id);
1708 ctcm_ccw_check_rc(ch, rc, "send discontact");
1709 /* Not checking return code value here */
1710 /* Making best effort to notify partner*/
1711 /* that MPC Group is going down */
1712 }
1713
1714 ctcm_pr_debug("ctcmpc exit: %s %s()\n", dev->name, __FUNCTION__);
1715 return;
1716}
1717
1718
1719/*
1720 * helper function of mpc FSM
1721 * CTCM_PROTO_MPC only
1722 * mpc_action_rcvd_xid7
1723*/
1724static int mpc_validate_xid(struct mpcg_info *mpcginfo)
1725{
1726 struct channel *ch = mpcginfo->ch;
1727 struct net_device *dev = ch->netdev;
1728 struct ctcm_priv *priv = dev->priv;
1729 struct mpc_group *grp = priv->mpcg;
1730 struct xid2 *xid = mpcginfo->xid;
1731 int failed = 0;
1732 int rc = 0;
1733 __u64 our_id, their_id = 0;
1734 int len;
1735
1736 len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
1737
1738 ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__);
1739
1740 if (mpcginfo->xid == NULL) {
1741 printk(KERN_INFO "%s() xid=NULL\n", __FUNCTION__);
1742 rc = 1;
1743 goto done;
1744 }
1745
1746 ctcm_pr_debug("ctcmpc : %s xid received()\n", __FUNCTION__);
1747 ctcmpc_dumpit((char *)mpcginfo->xid, XID2_LENGTH);
1748
1749 /*the received direction should be the opposite of ours */
1750 if (((CHANNEL_DIRECTION(ch->flags) == READ) ? XID2_WRITE_SIDE :
1751 XID2_READ_SIDE) != xid->xid2_dlc_type) {
1752 failed = 1;
1753 printk(KERN_INFO "ctcmpc:%s() XID REJECTED - READ-WRITE CH "
1754 "Pairing Invalid \n", __FUNCTION__);
1755 }
1756
1757 if (xid->xid2_dlc_type == XID2_READ_SIDE) {
1758 ctcm_pr_debug("ctcmpc: %s(): grpmaxbuf:%d xid2buflen:%d\n",
1759 __FUNCTION__, grp->group_max_buflen,
1760 xid->xid2_buf_len);
1761
1762 if (grp->group_max_buflen == 0 ||
1763 grp->group_max_buflen > xid->xid2_buf_len - len)
1764 grp->group_max_buflen = xid->xid2_buf_len - len;
1765 }
1766
1767
1768 if (grp->saved_xid2 == NULL) {
1769 grp->saved_xid2 =
1770 (struct xid2 *)skb_tail_pointer(grp->rcvd_xid_skb);
1771
1772 memcpy(skb_put(grp->rcvd_xid_skb,
1773 XID2_LENGTH), xid, XID2_LENGTH);
1774 grp->rcvd_xid_skb->data = grp->rcvd_xid_data;
1775
1776 skb_reset_tail_pointer(grp->rcvd_xid_skb);
1777 grp->rcvd_xid_skb->len = 0;
1778
1779 /* convert two 32 bit numbers into 1 64 bit for id compare */
1780 our_id = (__u64)priv->xid->xid2_adj_id;
1781 our_id = our_id << 32;
1782 our_id = our_id + priv->xid->xid2_sender_id;
1783 their_id = (__u64)xid->xid2_adj_id;
1784 their_id = their_id << 32;
1785 their_id = their_id + xid->xid2_sender_id;
1786 /* lower id assume the xside role */
1787 if (our_id < their_id) {
1788 grp->roll = XSIDE;
1789 ctcm_pr_debug("ctcmpc :%s() WE HAVE LOW ID-"
1790 "TAKE XSIDE\n", __FUNCTION__);
1791 } else {
1792 grp->roll = YSIDE;
1793 ctcm_pr_debug("ctcmpc :%s() WE HAVE HIGH ID-"
1794 "TAKE YSIDE\n", __FUNCTION__);
1795 }
1796
1797 } else {
1798 if (xid->xid2_flag4 != grp->saved_xid2->xid2_flag4) {
1799 failed = 1;
1800 printk(KERN_INFO "%s XID REJECTED - XID Flag Byte4\n",
1801 __FUNCTION__);
1802 }
1803 if (xid->xid2_flag2 == 0x40) {
1804 failed = 1;
1805 printk(KERN_INFO "%s XID REJECTED - XID NOGOOD\n",
1806 __FUNCTION__);
1807 }
1808 if (xid->xid2_adj_id != grp->saved_xid2->xid2_adj_id) {
1809 failed = 1;
1810 printk(KERN_INFO "%s XID REJECTED - "
1811 "Adjacent Station ID Mismatch\n",
1812 __FUNCTION__);
1813 }
1814 if (xid->xid2_sender_id != grp->saved_xid2->xid2_sender_id) {
1815 failed = 1;
1816 printk(KERN_INFO "%s XID REJECTED - "
1817 "Sender Address Mismatch\n", __FUNCTION__);
1818
1819 }
1820 }
1821
1822 if (failed) {
1823 ctcm_pr_info("ctcmpc : %s() failed\n", __FUNCTION__);
1824 priv->xid->xid2_flag2 = 0x40;
1825 grp->saved_xid2->xid2_flag2 = 0x40;
1826 rc = 1;
1827 }
1828
1829done:
1830
1831 ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__);
1832 return rc;
1833}
1834
1835/*
1836 * MPC Group Station FSM action
1837 * CTCM_PROTO_MPC only
1838 */
1839static void mpc_action_side_xid(fsm_instance *fsm, void *arg, int side)
1840{
1841 struct channel *ch = arg;
1842 struct ctcm_priv *priv;
1843 struct mpc_group *grp = NULL;
1844 struct net_device *dev = NULL;
1845 int rc = 0;
1846 int gotlock = 0;
1847 unsigned long saveflags = 0; /* avoids compiler warning with
1848 spin_unlock_irqrestore */
1849
1850 if (ch == NULL) {
1851 printk(KERN_INFO "%s ch=NULL\n", __FUNCTION__);
1852 goto done;
1853 }
1854
1855 if (do_debug)
1856 ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
1857 __FUNCTION__, smp_processor_id(), ch, ch->id);
1858
1859 dev = ch->netdev;
1860 if (dev == NULL) {
1861 printk(KERN_INFO "%s dev=NULL\n", __FUNCTION__);
1862 goto done;
1863 }
1864
1865 priv = dev->priv;
1866 if (priv == NULL) {
1867 printk(KERN_INFO "%s priv=NULL\n", __FUNCTION__);
1868 goto done;
1869 }
1870
1871 grp = priv->mpcg;
1872 if (grp == NULL) {
1873 printk(KERN_INFO "%s grp=NULL\n", __FUNCTION__);
1874 goto done;
1875 }
1876
1877 if (ctcm_checkalloc_buffer(ch))
1878 goto done;
1879
1880 /* skb data-buffer referencing: */
1881
1882 ch->trans_skb->data = ch->trans_skb_data;
1883 skb_reset_tail_pointer(ch->trans_skb);
1884 ch->trans_skb->len = 0;
1885 /* result of the previous 3 statements is NOT always
1886 * already set after ctcm_checkalloc_buffer
1887 * because of possible reuse of the trans_skb
1888 */
1889 memset(ch->trans_skb->data, 0, 16);
1890 ch->rcvd_xid_th = (struct th_header *)ch->trans_skb_data;
1891 /* check is main purpose here: */
1892 skb_put(ch->trans_skb, TH_HEADER_LENGTH);
1893 ch->rcvd_xid = (struct xid2 *)skb_tail_pointer(ch->trans_skb);
1894 /* check is main purpose here: */
1895 skb_put(ch->trans_skb, XID2_LENGTH);
1896 ch->rcvd_xid_id = skb_tail_pointer(ch->trans_skb);
1897 /* cleanup back to startpoint */
1898 ch->trans_skb->data = ch->trans_skb_data;
1899 skb_reset_tail_pointer(ch->trans_skb);
1900 ch->trans_skb->len = 0;
1901
1902 /* non-checking rewrite of above skb data-buffer referencing: */
1903 /*
1904 memset(ch->trans_skb->data, 0, 16);
1905 ch->rcvd_xid_th = (struct th_header *)ch->trans_skb_data;
1906 ch->rcvd_xid = (struct xid2 *)(ch->trans_skb_data + TH_HEADER_LENGTH);
1907 ch->rcvd_xid_id = ch->trans_skb_data + TH_HEADER_LENGTH + XID2_LENGTH;
1908 */
1909
1910 ch->ccw[8].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1911 ch->ccw[8].count = 0;
1912 ch->ccw[8].cda = 0x00;
1913
1914 if (side == XSIDE) {
1915 /* mpc_action_xside_xid */
1916 if (ch->xid_th == NULL) {
1917 printk(KERN_INFO "%s ch->xid_th=NULL\n", __FUNCTION__);
1918 goto done;
1919 }
1920 ch->ccw[9].cmd_code = CCW_CMD_WRITE;
1921 ch->ccw[9].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1922 ch->ccw[9].count = TH_HEADER_LENGTH;
1923 ch->ccw[9].cda = virt_to_phys(ch->xid_th);
1924
1925 if (ch->xid == NULL) {
1926 printk(KERN_INFO "%s ch->xid=NULL\n", __FUNCTION__);
1927 goto done;
1928 }
1929
1930 ch->ccw[10].cmd_code = CCW_CMD_WRITE;
1931 ch->ccw[10].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1932 ch->ccw[10].count = XID2_LENGTH;
1933 ch->ccw[10].cda = virt_to_phys(ch->xid);
1934
1935 ch->ccw[11].cmd_code = CCW_CMD_READ;
1936 ch->ccw[11].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1937 ch->ccw[11].count = TH_HEADER_LENGTH;
1938 ch->ccw[11].cda = virt_to_phys(ch->rcvd_xid_th);
1939
1940 ch->ccw[12].cmd_code = CCW_CMD_READ;
1941 ch->ccw[12].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1942 ch->ccw[12].count = XID2_LENGTH;
1943 ch->ccw[12].cda = virt_to_phys(ch->rcvd_xid);
1944
1945 ch->ccw[13].cmd_code = CCW_CMD_READ;
1946 ch->ccw[13].cda = virt_to_phys(ch->rcvd_xid_id);
1947
1948 } else { /* side == YSIDE : mpc_action_yside_xid */
1949 ch->ccw[9].cmd_code = CCW_CMD_READ;
1950 ch->ccw[9].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1951 ch->ccw[9].count = TH_HEADER_LENGTH;
1952 ch->ccw[9].cda = virt_to_phys(ch->rcvd_xid_th);
1953
1954 ch->ccw[10].cmd_code = CCW_CMD_READ;
1955 ch->ccw[10].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1956 ch->ccw[10].count = XID2_LENGTH;
1957 ch->ccw[10].cda = virt_to_phys(ch->rcvd_xid);
1958
1959 if (ch->xid_th == NULL) {
1960 printk(KERN_INFO "%s ch->xid_th=NULL\n", __FUNCTION__);
1961 goto done;
1962 }
1963 ch->ccw[11].cmd_code = CCW_CMD_WRITE;
1964 ch->ccw[11].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1965 ch->ccw[11].count = TH_HEADER_LENGTH;
1966 ch->ccw[11].cda = virt_to_phys(ch->xid_th);
1967
1968 if (ch->xid == NULL) {
1969 printk(KERN_INFO "%s ch->xid=NULL\n", __FUNCTION__);
1970 goto done;
1971 }
1972 ch->ccw[12].cmd_code = CCW_CMD_WRITE;
1973 ch->ccw[12].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1974 ch->ccw[12].count = XID2_LENGTH;
1975 ch->ccw[12].cda = virt_to_phys(ch->xid);
1976
1977 if (ch->xid_id == NULL) {
1978 printk(KERN_INFO "%s ch->xid_id=NULL\n", __FUNCTION__);
1979 goto done;
1980 }
1981 ch->ccw[13].cmd_code = CCW_CMD_WRITE;
1982 ch->ccw[13].cda = virt_to_phys(ch->xid_id);
1983
1984 }
1985 ch->ccw[13].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1986 ch->ccw[13].count = 4;
1987
1988 ch->ccw[14].cmd_code = CCW_CMD_NOOP;
1989 ch->ccw[14].flags = CCW_FLAG_SLI;
1990 ch->ccw[14].count = 0;
1991 ch->ccw[14].cda = 0;
1992
1993 if (do_debug_ccw)
1994 ctcmpc_dumpit((char *)&ch->ccw[8], sizeof(struct ccw1) * 7);
1995
1996 ctcmpc_dumpit((char *)ch->xid_th, TH_HEADER_LENGTH);
1997 ctcmpc_dumpit((char *)ch->xid, XID2_LENGTH);
1998 ctcmpc_dumpit((char *)ch->xid_id, 4);
1999 if (!in_irq()) {
2000 /* Such conditional locking is a known problem for
2001 * sparse because its static undeterministic.
2002 * Warnings should be ignored here. */
2003 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
2004 gotlock = 1;
2005 }
2006
2007 fsm_addtimer(&ch->timer, 5000 , CTC_EVENT_TIMER, ch);
2008 rc = ccw_device_start(ch->cdev, &ch->ccw[8],
2009 (unsigned long)ch, 0xff, 0);
2010
2011 if (gotlock) /* see remark above about conditional locking */
2012 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
2013
2014 if (rc != 0) {
2015 ctcm_pr_info("ctcmpc: %s() ch:%s IO failed \n",
2016 __FUNCTION__, ch->id);
2017 ctcm_ccw_check_rc(ch, rc,
2018 (side == XSIDE) ? "x-side XID" : "y-side XID");
2019 }
2020
2021done:
2022 if (do_debug)
2023 ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
2024 __FUNCTION__, ch, ch->id);
2025 return;
2026
2027}
2028
2029/*
2030 * MPC Group Station FSM action
2031 * CTCM_PROTO_MPC only
2032 */
2033static void mpc_action_xside_xid(fsm_instance *fsm, int event, void *arg)
2034{
2035 mpc_action_side_xid(fsm, arg, XSIDE);
2036}
2037
2038/*
2039 * MPC Group Station FSM action
2040 * CTCM_PROTO_MPC only
2041 */
2042static void mpc_action_yside_xid(fsm_instance *fsm, int event, void *arg)
2043{
2044 mpc_action_side_xid(fsm, arg, YSIDE);
2045}
2046
2047/*
2048 * MPC Group Station FSM action
2049 * CTCM_PROTO_MPC only
2050 */
2051static void mpc_action_doxid0(fsm_instance *fsm, int event, void *arg)
2052{
2053 struct channel *ch = arg;
2054 struct ctcm_priv *priv;
2055 struct mpc_group *grp = NULL;
2056 struct net_device *dev = NULL;
2057
2058 if (do_debug)
2059 ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
2060 __FUNCTION__, smp_processor_id(), ch, ch->id);
2061
2062 if (ch == NULL) {
2063 printk(KERN_WARNING "%s ch=NULL\n", __FUNCTION__);
2064 goto done;
2065 }
2066
2067 dev = ch->netdev;
2068 if (dev == NULL) {
2069 printk(KERN_WARNING "%s dev=NULL\n", __FUNCTION__);
2070 goto done;
2071 }
2072
2073 priv = dev->priv;
2074 if (priv == NULL) {
2075 printk(KERN_WARNING "%s priv=NULL\n", __FUNCTION__);
2076 goto done;
2077 }
2078
2079 grp = priv->mpcg;
2080 if (grp == NULL) {
2081 printk(KERN_WARNING "%s grp=NULL\n", __FUNCTION__);
2082 goto done;
2083 }
2084
2085 if (ch->xid == NULL) {
2086 printk(KERN_WARNING "%s ch-xid=NULL\n", __FUNCTION__);
2087 goto done;
2088 }
2089
2090 fsm_newstate(ch->fsm, CH_XID0_INPROGRESS);
2091
2092 ch->xid->xid2_option = XID2_0;
2093
2094 switch (fsm_getstate(grp->fsm)) {
2095 case MPCG_STATE_XID2INITW:
2096 case MPCG_STATE_XID2INITX:
2097 ch->ccw[8].cmd_code = CCW_CMD_SENSE_CMD;
2098 break;
2099 case MPCG_STATE_XID0IOWAIT:
2100 case MPCG_STATE_XID0IOWAIX:
2101 ch->ccw[8].cmd_code = CCW_CMD_WRITE_CTL;
2102 break;
2103 }
2104
2105 fsm_event(grp->fsm, MPCG_EVENT_DOIO, ch);
2106
2107done:
2108 if (do_debug)
2109 ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
2110 __FUNCTION__, ch, ch->id);
2111 return;
2112
2113}
2114
2115/*
2116 * MPC Group Station FSM action
2117 * CTCM_PROTO_MPC only
2118*/
2119static void mpc_action_doxid7(fsm_instance *fsm, int event, void *arg)
2120{
2121 struct net_device *dev = arg;
2122 struct ctcm_priv *priv = NULL;
2123 struct mpc_group *grp = NULL;
2124 int direction;
2125 int rc = 0;
2126 int send = 0;
2127
2128 ctcm_pr_debug("ctcmpc enter: %s() \n", __FUNCTION__);
2129
2130 if (dev == NULL) {
2131 printk(KERN_INFO "%s dev=NULL \n", __FUNCTION__);
2132 rc = 1;
2133 goto done;
2134 }
2135
2136 priv = dev->priv;
2137 if (priv == NULL) {
2138 printk(KERN_INFO "%s priv=NULL \n", __FUNCTION__);
2139 rc = 1;
2140 goto done;
2141 }
2142
2143 grp = priv->mpcg;
2144 if (grp == NULL) {
2145 printk(KERN_INFO "%s grp=NULL \n", __FUNCTION__);
2146 rc = 1;
2147 goto done;
2148 }
2149
2150 for (direction = READ; direction <= WRITE; direction++) {
2151 struct channel *ch = priv->channel[direction];
2152 struct xid2 *thisxid = ch->xid;
2153 ch->xid_skb->data = ch->xid_skb_data;
2154 skb_reset_tail_pointer(ch->xid_skb);
2155 ch->xid_skb->len = 0;
2156 thisxid->xid2_option = XID2_7;
2157 send = 0;
2158
2159 /* xid7 phase 1 */
2160 if (grp->outstanding_xid7_p2 > 0) {
2161 if (grp->roll == YSIDE) {
2162 if (fsm_getstate(ch->fsm) == CH_XID7_PENDING1) {
2163 fsm_newstate(ch->fsm, CH_XID7_PENDING2);
2164 ch->ccw[8].cmd_code = CCW_CMD_SENSE_CMD;
2165 memcpy(skb_put(ch->xid_skb,
2166 TH_HEADER_LENGTH),
2167 &thdummy, TH_HEADER_LENGTH);
2168 send = 1;
2169 }
2170 } else if (fsm_getstate(ch->fsm) < CH_XID7_PENDING2) {
2171 fsm_newstate(ch->fsm, CH_XID7_PENDING2);
2172 ch->ccw[8].cmd_code = CCW_CMD_WRITE_CTL;
2173 memcpy(skb_put(ch->xid_skb,
2174 TH_HEADER_LENGTH),
2175 &thnorm, TH_HEADER_LENGTH);
2176 send = 1;
2177 }
2178 } else {
2179 /* xid7 phase 2 */
2180 if (grp->roll == YSIDE) {
2181 if (fsm_getstate(ch->fsm) < CH_XID7_PENDING4) {
2182 fsm_newstate(ch->fsm, CH_XID7_PENDING4);
2183 memcpy(skb_put(ch->xid_skb,
2184 TH_HEADER_LENGTH),
2185 &thnorm, TH_HEADER_LENGTH);
2186 ch->ccw[8].cmd_code = CCW_CMD_WRITE_CTL;
2187 send = 1;
2188 }
2189 } else if (fsm_getstate(ch->fsm) == CH_XID7_PENDING3) {
2190 fsm_newstate(ch->fsm, CH_XID7_PENDING4);
2191 ch->ccw[8].cmd_code = CCW_CMD_SENSE_CMD;
2192 memcpy(skb_put(ch->xid_skb, TH_HEADER_LENGTH),
2193 &thdummy, TH_HEADER_LENGTH);
2194 send = 1;
2195 }
2196 }
2197
2198 if (send)
2199 fsm_event(grp->fsm, MPCG_EVENT_DOIO, ch);
2200 }
2201
2202done:
2203
2204 if (rc != 0)
2205 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
2206
2207 return;
2208}
2209
2210/*
2211 * MPC Group Station FSM action
2212 * CTCM_PROTO_MPC only
2213 */
2214static void mpc_action_rcvd_xid0(fsm_instance *fsm, int event, void *arg)
2215{
2216
2217 struct mpcg_info *mpcginfo = arg;
2218 struct channel *ch = mpcginfo->ch;
2219 struct net_device *dev = ch->netdev;
2220 struct ctcm_priv *priv;
2221 struct mpc_group *grp;
2222
2223 if (do_debug)
2224 ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
2225 __FUNCTION__, smp_processor_id(), ch, ch->id);
2226
2227 priv = dev->priv;
2228 grp = priv->mpcg;
2229
2230 ctcm_pr_debug("ctcmpc in:%s() %s xid2:%i xid7:%i xidt_p2:%i \n",
2231 __FUNCTION__, ch->id,
2232 grp->outstanding_xid2,
2233 grp->outstanding_xid7,
2234 grp->outstanding_xid7_p2);
2235
2236 if (fsm_getstate(ch->fsm) < CH_XID7_PENDING)
2237 fsm_newstate(ch->fsm, CH_XID7_PENDING);
2238
2239 grp->outstanding_xid2--;
2240 grp->outstanding_xid7++;
2241 grp->outstanding_xid7_p2++;
2242
2243 /* must change state before validating xid to */
2244 /* properly handle interim interrupts received*/
2245 switch (fsm_getstate(grp->fsm)) {
2246 case MPCG_STATE_XID2INITW:
2247 fsm_newstate(grp->fsm, MPCG_STATE_XID2INITX);
2248 mpc_validate_xid(mpcginfo);
2249 break;
2250 case MPCG_STATE_XID0IOWAIT:
2251 fsm_newstate(grp->fsm, MPCG_STATE_XID0IOWAIX);
2252 mpc_validate_xid(mpcginfo);
2253 break;
2254 case MPCG_STATE_XID2INITX:
2255 if (grp->outstanding_xid2 == 0) {
2256 fsm_newstate(grp->fsm, MPCG_STATE_XID7INITW);
2257 mpc_validate_xid(mpcginfo);
2258 fsm_event(grp->fsm, MPCG_EVENT_XID2DONE, dev);
2259 }
2260 break;
2261 case MPCG_STATE_XID0IOWAIX:
2262 if (grp->outstanding_xid2 == 0) {
2263 fsm_newstate(grp->fsm, MPCG_STATE_XID7INITI);
2264 mpc_validate_xid(mpcginfo);
2265 fsm_event(grp->fsm, MPCG_EVENT_XID2DONE, dev);
2266 }
2267 break;
2268 }
2269 kfree(mpcginfo);
2270
2271 if (do_debug) {
2272 ctcm_pr_debug("ctcmpc:%s() %s xid2:%i xid7:%i xidt_p2:%i \n",
2273 __FUNCTION__, ch->id,
2274 grp->outstanding_xid2,
2275 grp->outstanding_xid7,
2276 grp->outstanding_xid7_p2);
2277 ctcm_pr_debug("ctcmpc:%s() %s grpstate: %s chanstate: %s \n",
2278 __FUNCTION__, ch->id,
2279 fsm_getstate_str(grp->fsm),
2280 fsm_getstate_str(ch->fsm));
2281 }
2282 return;
2283
2284}
2285
2286
2287/*
2288 * MPC Group Station FSM action
2289 * CTCM_PROTO_MPC only
2290 */
2291static void mpc_action_rcvd_xid7(fsm_instance *fsm, int event, void *arg)
2292{
2293 struct mpcg_info *mpcginfo = arg;
2294 struct channel *ch = mpcginfo->ch;
2295 struct net_device *dev = ch->netdev;
2296 struct ctcm_priv *priv = dev->priv;
2297 struct mpc_group *grp = priv->mpcg;
2298
2299 if (do_debug) {
2300 ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
2301 __FUNCTION__, smp_processor_id(), ch, ch->id);
2302
2303 ctcm_pr_debug("ctcmpc: outstanding_xid7: %i, "
2304 " outstanding_xid7_p2: %i\n",
2305 grp->outstanding_xid7,
2306 grp->outstanding_xid7_p2);
2307 }
2308
2309 grp->outstanding_xid7--;
2310 ch->xid_skb->data = ch->xid_skb_data;
2311 skb_reset_tail_pointer(ch->xid_skb);
2312 ch->xid_skb->len = 0;
2313
2314 switch (fsm_getstate(grp->fsm)) {
2315 case MPCG_STATE_XID7INITI:
2316 fsm_newstate(grp->fsm, MPCG_STATE_XID7INITZ);
2317 mpc_validate_xid(mpcginfo);
2318 break;
2319 case MPCG_STATE_XID7INITW:
2320 fsm_newstate(grp->fsm, MPCG_STATE_XID7INITX);
2321 mpc_validate_xid(mpcginfo);
2322 break;
2323 case MPCG_STATE_XID7INITZ:
2324 case MPCG_STATE_XID7INITX:
2325 if (grp->outstanding_xid7 == 0) {
2326 if (grp->outstanding_xid7_p2 > 0) {
2327 grp->outstanding_xid7 =
2328 grp->outstanding_xid7_p2;
2329 grp->outstanding_xid7_p2 = 0;
2330 } else
2331 fsm_newstate(grp->fsm, MPCG_STATE_XID7INITF);
2332
2333 mpc_validate_xid(mpcginfo);
2334 fsm_event(grp->fsm, MPCG_EVENT_XID7DONE, dev);
2335 break;
2336 }
2337 mpc_validate_xid(mpcginfo);
2338 break;
2339 }
2340
2341 kfree(mpcginfo);
2342
2343 if (do_debug)
2344 ctcm_pr_debug("ctcmpc exit: %s(): cp=%i ch=0x%p id=%s\n",
2345 __FUNCTION__, smp_processor_id(), ch, ch->id);
2346 return;
2347
2348}
2349
2350/*
2351 * mpc_action helper of an MPC Group Station FSM action
2352 * CTCM_PROTO_MPC only
2353 */
2354static int mpc_send_qllc_discontact(struct net_device *dev)
2355{
2356 int rc = 0;
2357 __u32 new_len = 0;
2358 struct sk_buff *skb;
2359 struct qllc *qllcptr;
2360 struct ctcm_priv *priv;
2361 struct mpc_group *grp;
2362
2363 ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__);
2364
2365 if (dev == NULL) {
2366 printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
2367 rc = 1;
2368 goto done;
2369 }
2370
2371 priv = dev->priv;
2372 if (priv == NULL) {
2373 printk(KERN_INFO "%s() priv=NULL\n", __FUNCTION__);
2374 rc = 1;
2375 goto done;
2376 }
2377
2378 grp = priv->mpcg;
2379 if (grp == NULL) {
2380 printk(KERN_INFO "%s() grp=NULL\n", __FUNCTION__);
2381 rc = 1;
2382 goto done;
2383 }
2384 ctcm_pr_info("ctcmpc: %s() GROUP STATE: %s\n", __FUNCTION__,
2385 mpcg_state_names[grp->saved_state]);
2386
2387 switch (grp->saved_state) {
2388 /*
2389 * establish conn callback function is
2390 * preferred method to report failure
2391 */
2392 case MPCG_STATE_XID0IOWAIT:
2393 case MPCG_STATE_XID0IOWAIX:
2394 case MPCG_STATE_XID7INITI:
2395 case MPCG_STATE_XID7INITZ:
2396 case MPCG_STATE_XID2INITW:
2397 case MPCG_STATE_XID2INITX:
2398 case MPCG_STATE_XID7INITW:
2399 case MPCG_STATE_XID7INITX:
2400 if (grp->estconnfunc) {
2401 grp->estconnfunc(grp->port_num, -1, 0);
2402 grp->estconnfunc = NULL;
2403 break;
2404 }
2405 case MPCG_STATE_FLOWC:
2406 case MPCG_STATE_READY:
2407 grp->send_qllc_disc = 2;
2408 new_len = sizeof(struct qllc);
2409 qllcptr = kzalloc(new_len, gfp_type() | GFP_DMA);
2410 if (qllcptr == NULL) {
2411 printk(KERN_INFO
2412 "ctcmpc: Out of memory in %s()\n",
2413 dev->name);
2414 rc = 1;
2415 goto done;
2416 }
2417
2418 qllcptr->qllc_address = 0xcc;
2419 qllcptr->qllc_commands = 0x03;
2420
2421 skb = __dev_alloc_skb(new_len, GFP_ATOMIC);
2422
2423 if (skb == NULL) {
2424 printk(KERN_INFO "%s Out of memory in mpc_send_qllc\n",
2425 dev->name);
2426 priv->stats.rx_dropped++;
2427 rc = 1;
2428 kfree(qllcptr);
2429 goto done;
2430 }
2431
2432 memcpy(skb_put(skb, new_len), qllcptr, new_len);
2433 kfree(qllcptr);
2434
2435 if (skb_headroom(skb) < 4) {
2436 printk(KERN_INFO "ctcmpc: %s() Unable to"
2437 " build discontact for %s\n",
2438 __FUNCTION__, dev->name);
2439 rc = 1;
2440 dev_kfree_skb_any(skb);
2441 goto done;
2442 }
2443
2444 *((__u32 *)skb_push(skb, 4)) = priv->channel[READ]->pdu_seq;
2445 priv->channel[READ]->pdu_seq++;
2446 if (do_debug_data)
2447 ctcm_pr_debug("ctcmpc: %s ToDCM_pdu_seq= %08x\n",
2448 __FUNCTION__, priv->channel[READ]->pdu_seq);
2449
2450 /* receipt of CC03 resets anticipated sequence number on
2451 receiving side */
2452 priv->channel[READ]->pdu_seq = 0x00;
2453 skb_reset_mac_header(skb);
2454 skb->dev = dev;
2455 skb->protocol = htons(ETH_P_SNAP);
2456 skb->ip_summed = CHECKSUM_UNNECESSARY;
2457
2458 ctcmpc_dumpit((char *)skb->data, (sizeof(struct qllc) + 4));
2459
2460 netif_rx(skb);
2461 break;
2462 default:
2463 break;
2464
2465 }
2466
2467done:
2468 ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__);
2469 return rc;
2470}
2471/* --- This is the END my friend --- */
2472