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