ctcm_main.h 7.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*
 *	drivers/s390/net/ctcm_main.h
 *
 *	Copyright IBM Corp. 2001, 2007
 *	Authors:	Fritz Elfert (felfert@millenux.com)
 *			Peter Tiedemann (ptiedem@de.ibm.com)
 */

#ifndef _CTCM_MAIN_H_
#define _CTCM_MAIN_H_

#include <asm/ccwdev.h>
#include <asm/ccwgroup.h>

#include <linux/skbuff.h>
#include <linux/netdevice.h>

#include "fsm.h"
#include "cu3088.h"
#include "ctcm_dbug.h"
#include "ctcm_mpc.h"

#define CTC_DRIVER_NAME	"ctcm"
#define CTC_DEVICE_NAME	"ctc"
#define MPC_DEVICE_NAME	"mpc"
P
Peter Tiedemann 已提交
26 27
#define CTC_DEVICE_GENE CTC_DEVICE_NAME "%d"
#define MPC_DEVICE_GENE	MPC_DEVICE_NAME "%d"
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

#define CHANNEL_FLAGS_READ	0
#define CHANNEL_FLAGS_WRITE	1
#define CHANNEL_FLAGS_INUSE	2
#define CHANNEL_FLAGS_BUFSIZE_CHANGED	4
#define CHANNEL_FLAGS_FAILED	8
#define CHANNEL_FLAGS_WAITIRQ	16
#define CHANNEL_FLAGS_RWMASK	1
#define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK)

#define LOG_FLAG_ILLEGALPKT	1
#define LOG_FLAG_ILLEGALSIZE	2
#define LOG_FLAG_OVERRUN	4
#define LOG_FLAG_NOMEM		8

#define ctcm_pr_debug(fmt, arg...) printk(KERN_DEBUG fmt, ##arg)
#define ctcm_pr_info(fmt, arg...) printk(KERN_INFO fmt, ##arg)
#define ctcm_pr_notice(fmt, arg...) printk(KERN_NOTICE fmt, ##arg)
#define ctcm_pr_warn(fmt, arg...) printk(KERN_WARNING fmt, ##arg)
#define ctcm_pr_emerg(fmt, arg...) printk(KERN_EMERG fmt, ##arg)
#define ctcm_pr_err(fmt, arg...) printk(KERN_ERR fmt, ##arg)
#define ctcm_pr_crit(fmt, arg...) printk(KERN_CRIT fmt, ##arg)

P
Peter Tiedemann 已提交
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
#define CTCM_PR_DEBUG(fmt, arg...) \
	do { \
		if (do_debug) \
			printk(KERN_DEBUG fmt, ##arg); \
	} while (0)

#define	CTCM_PR_DBGDATA(fmt, arg...) \
	do { \
		if (do_debug_data) \
			printk(KERN_DEBUG fmt, ##arg); \
	} while (0)

#define	CTCM_D3_DUMP(buf, len) \
	do { \
		if (do_debug_data) \
			ctcmpc_dumpit(buf, len); \
	} while (0)

#define	CTCM_CCW_DUMP(buf, len) \
	do { \
		if (do_debug_ccw) \
			ctcmpc_dumpit(buf, len); \
	} while (0)

75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
/*
 * CCW commands, used in this driver.
 */
#define CCW_CMD_WRITE		0x01
#define CCW_CMD_READ		0x02
#define CCW_CMD_NOOP		0x03
#define CCW_CMD_TIC             0x08
#define CCW_CMD_SENSE_CMD	0x14
#define CCW_CMD_WRITE_CTL	0x17
#define CCW_CMD_SET_EXTENDED	0xc3
#define CCW_CMD_PREPARE		0xe3

#define CTCM_PROTO_S390		0
#define CTCM_PROTO_LINUX	1
#define CTCM_PROTO_LINUX_TTY	2
#define CTCM_PROTO_OS390	3
#define CTCM_PROTO_MPC		4
#define CTCM_PROTO_MAX		4

#define CTCM_BUFSIZE_LIMIT	65535
#define CTCM_BUFSIZE_DEFAULT	32768
#define MPC_BUFSIZE_DEFAULT	CTCM_BUFSIZE_LIMIT

#define CTCM_TIME_1_SEC		1000
#define CTCM_TIME_5_SEC		5000
#define CTCM_TIME_10_SEC	10000

#define CTCM_INITIAL_BLOCKLEN	2

#define READ			0
#define WRITE			1

#define CTCM_ID_SIZE		BUS_ID_SIZE+3

struct ctcm_profile {
	unsigned long maxmulti;
	unsigned long maxcqueue;
	unsigned long doios_single;
	unsigned long doios_multi;
	unsigned long txlen;
	unsigned long tx_time;
	struct timespec send_stamp;
};

/*
 * Definition of one channel
 */
struct channel {
	struct channel *next;
	char id[CTCM_ID_SIZE];
	struct ccw_device *cdev;
	/*
	 * Type of this channel.
	 * CTC/A or Escon for valid channels.
	 */
	enum channel_types type;
	/*
	 * Misc. flags. See CHANNEL_FLAGS_... below
	 */
	__u32 flags;
	__u16 protocol;		/* protocol of this channel (4 = MPC) */
	/*
	 * I/O and irq related stuff
	 */
	struct ccw1 *ccw;
	struct irb *irb;
	/*
	 * RX/TX buffer size
	 */
	int max_bufsize;
	struct sk_buff *trans_skb;	/* transmit/receive buffer */
	struct sk_buff_head io_queue;	/* universal I/O queue */
	struct tasklet_struct ch_tasklet;	/* MPC ONLY */
	/*
	 * TX queue for collecting skb's during busy.
	 */
	struct sk_buff_head collect_queue;
	/*
	 * Amount of data in collect_queue.
	 */
	int collect_len;
	/*
	 * spinlock for collect_queue and collect_len
	 */
	spinlock_t collect_lock;
	/*
	 * Timer for detecting unresposive
	 * I/O operations.
	 */
	fsm_timer timer;
	/* MPC ONLY section begin */
	__u32	th_seq_num;	/* SNA TH seq number */
	__u8	th_seg;
	__u32	pdu_seq;
	struct sk_buff		*xid_skb;
	char			*xid_skb_data;
	struct th_header	*xid_th;
	struct xid2		*xid;
	char			*xid_id;
	struct th_header	*rcvd_xid_th;
	struct xid2		*rcvd_xid;
	char			*rcvd_xid_id;
	__u8			in_mpcgroup;
	fsm_timer		sweep_timer;
	struct sk_buff_head	sweep_queue;
	struct th_header	*discontact_th;
	struct tasklet_struct	ch_disc_tasklet;
	/* MPC ONLY section end */

	int retry;		/* retry counter for misc. operations */
	fsm_instance *fsm;	/* finite state machine of this channel */
	struct net_device *netdev;	/* corresponding net_device */
	struct ctcm_profile prof;
P
Peter Tiedemann 已提交
188
	__u8 *trans_skb_data;
189
	__u16 logflags;
P
Peter Tiedemann 已提交
190
	__u8  sense_rc; /* last unit check sense code report control */
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
};

struct ctcm_priv {
	struct net_device_stats	stats;
	unsigned long	tbusy;

	/* The MPC group struct of this interface */
	struct	mpc_group	*mpcg;	/* MPC only */
	struct	xid2		*xid;	/* MPC only */

	/* The finite state machine of this interface */
	fsm_instance *fsm;

	/* The protocol of this device */
	__u16 protocol;

	/* Timer for restarting after I/O Errors */
	fsm_timer	restart_timer;

	int buffer_size;	/* ctc only */

	struct channel *channel[2];
};

int ctcm_open(struct net_device *dev);
int ctcm_close(struct net_device *dev);

/*
 * prototypes for non-static sysfs functions
 */
int ctcm_add_attributes(struct device *dev);
void ctcm_remove_attributes(struct device *dev);
int ctcm_add_files(struct device *dev);
void ctcm_remove_files(struct device *dev);

/*
 * Compatibility macros for busy handling
 * of network devices.
 */
static inline void ctcm_clear_busy_do(struct net_device *dev)
{
232
	clear_bit(0, &(((struct ctcm_priv *)dev->ml_priv)->tbusy));
233 234 235 236 237 238
	netif_wake_queue(dev);
}

static inline void ctcm_clear_busy(struct net_device *dev)
{
	struct mpc_group *grp;
239
	grp = ((struct ctcm_priv *)dev->ml_priv)->mpcg;
240 241 242 243 244 245 246 247 248

	if (!(grp && grp->in_sweep))
		ctcm_clear_busy_do(dev);
}


static inline int ctcm_test_and_set_busy(struct net_device *dev)
{
	netif_stop_queue(dev);
249 250
	return test_and_set_bit(0,
			&(((struct ctcm_priv *)dev->ml_priv)->tbusy));
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
}

extern int loglevel;
extern struct channel *channels;

void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb);

/*
 * Functions related to setup and device detection.
 */

static inline int ctcm_less_than(char *id1, char *id2)
{
	unsigned long dev1, dev2;

	id1 = id1 + 5;
	id2 = id2 + 5;

	dev1 = simple_strtoul(id1, &id1, 16);
	dev2 = simple_strtoul(id2, &id2, 16);

	return (dev1 < dev2);
}

int ctcm_ch_alloc_buffer(struct channel *ch);

static inline int ctcm_checkalloc_buffer(struct channel *ch)
{
	if (ch->trans_skb == NULL)
		return ctcm_ch_alloc_buffer(ch);
	if (ch->flags & CHANNEL_FLAGS_BUFSIZE_CHANGED) {
		dev_kfree_skb(ch->trans_skb);
		return ctcm_ch_alloc_buffer(ch);
	}
	return 0;
}

struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv);

/* test if protocol attribute (of struct ctcm_priv or struct channel)
 * has MPC protocol setting. Type is not checked
 */
#define IS_MPC(p) ((p)->protocol == CTCM_PROTO_MPC)

/* test if struct ctcm_priv of struct net_device has MPC protocol setting */
296
#define IS_MPCDEV(dev) IS_MPC((struct ctcm_priv *)dev->ml_priv)
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313

static inline gfp_t gfp_type(void)
{
	return in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
}

/*
 * Definition of our link level header.
 */
struct ll_header {
	__u16 length;
	__u16 type;
	__u16 unused;
};
#define LL_HEADER_LENGTH (sizeof(struct ll_header))

#endif