mkiss.c 24.3 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
R
Ralf Baechle 已提交
2 3 4
 *  This program is free software; you can distribute it and/or modify it
 *  under the terms of the GNU General Public License (Version 2) as
 *  published by the Free Software Foundation.
L
Linus Torvalds 已提交
5
 *
R
Ralf Baechle 已提交
6 7 8 9
 *  This program is distributed in the hope it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 *  for more details.
L
Linus Torvalds 已提交
10
 *
R
Ralf Baechle 已提交
11 12 13
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
L
Linus Torvalds 已提交
14
 *
R
Ralf Baechle 已提交
15 16
 * Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl>
 * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org>
R
Ralf Baechle 已提交
17
 * Copyright (C) 2004, 05 Thomas Osterried DL9SAU <thomas@x-berg.in-berlin.de>
L
Linus Torvalds 已提交
18 19 20 21 22
 */
#include <linux/module.h>
#include <asm/system.h>
#include <linux/bitops.h>
#include <asm/uaccess.h>
R
Ralf Baechle 已提交
23
#include <linux/crc16.h>
L
Linus Torvalds 已提交
24 25 26 27 28 29 30 31 32 33 34 35 36 37
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/tty.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/major.h>
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
38
#include <linux/jiffies.h>
39
#include <linux/compat.h>
L
Linus Torvalds 已提交
40 41 42

#include <net/ax25.h>

R
Ralf Baechle 已提交
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
#define AX_MTU		236

/* SLIP/KISS protocol characters. */
#define END             0300		/* indicates end of frame	*/
#define ESC             0333		/* indicates byte stuffing	*/
#define ESC_END         0334		/* ESC ESC_END means END 'data'	*/
#define ESC_ESC         0335		/* ESC ESC_ESC means ESC 'data'	*/

struct mkiss {
	struct tty_struct	*tty;	/* ptr to TTY structure		*/
	struct net_device	*dev;	/* easy for intr handling	*/

	/* These are pointers to the malloc()ed frame buffers. */
	spinlock_t		buflock;/* lock for rbuf and xbuf */
	unsigned char		*rbuff;	/* receiver buffer		*/
	int			rcount;	/* received chars counter       */
	unsigned char		*xbuff;	/* transmitter buffer		*/
	unsigned char		*xhead;	/* pointer to next byte to XMIT */
	int			xleft;	/* bytes left in XMIT queue     */

	/* Detailed SLIP statistics. */
	int		mtu;		/* Our mtu (to spot changes!)   */
	int		buffsize;	/* Max buffers sizes            */

	unsigned long	flags;		/* Flag values/ mode etc	*/
					/* long req'd: used by set_bit --RR */
#define AXF_INUSE	0		/* Channel in use               */
#define AXF_ESCAPE	1               /* ESC received                 */
#define AXF_ERROR	2               /* Parity, etc. error           */
#define AXF_KEEPTEST	3		/* Keepalive test flag		*/
#define AXF_OUTWAIT	4		/* is outpacket was flag	*/

	int		mode;
        int		crcmode;	/* MW: for FlexNet, SMACK etc.  */
R
Ralf Baechle 已提交
77 78 79 80 81 82 83
	int		crcauto;	/* CRC auto mode */

#define CRC_MODE_NONE		0
#define CRC_MODE_FLEX		1
#define CRC_MODE_SMACK		2
#define CRC_MODE_FLEX_TEST	3
#define CRC_MODE_SMACK_TEST	4
R
Ralf Baechle 已提交
84 85 86 87

	atomic_t		refcnt;
	struct semaphore	dead_sem;
};
L
Linus Torvalds 已提交
88 89 90

/*---------------------------------------------------------------------------*/

R
Ralf Baechle 已提交
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
static const unsigned short crc_flex_table[] = {
	0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38,
	0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770,
	0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9,
	0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1,
	0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a,
	0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672,
	0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb,
	0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3,
	0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c,
	0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574,
	0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd,
	0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5,
	0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e,
	0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476,
	0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf,
	0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7,
	0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30,
	0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378,
	0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1,
	0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9,
	0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32,
	0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a,
	0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3,
	0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb,
	0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34,
	0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c,
	0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5,
	0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd,
	0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36,
	0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e,
	0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7,
	0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff
L
Linus Torvalds 已提交
124 125 126 127
};

static unsigned short calc_crc_flex(unsigned char *cp, int size)
{
R
Ralf Baechle 已提交
128
	unsigned short crc = 0xffff;
L
Linus Torvalds 已提交
129

R
Ralf Baechle 已提交
130 131
	while (size--)
		crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];
L
Linus Torvalds 已提交
132

R
Ralf Baechle 已提交
133 134
	return crc;
}
L
Linus Torvalds 已提交
135 136 137

static int check_crc_flex(unsigned char *cp, int size)
{
R
Ralf Baechle 已提交
138
	unsigned short crc = 0xffff;
L
Linus Torvalds 已提交
139

R
Ralf Baechle 已提交
140 141
	if (size < 3)
		return -1;
L
Linus Torvalds 已提交
142

R
Ralf Baechle 已提交
143 144
	while (size--)
		crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];
L
Linus Torvalds 已提交
145

R
Ralf Baechle 已提交
146 147
	if ((crc & 0xffff) != 0x7070)
		return -1;
L
Linus Torvalds 已提交
148

R
Ralf Baechle 已提交
149
	return 0;
L
Linus Torvalds 已提交
150 151
}

R
Ralf Baechle 已提交
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
static int check_crc_16(unsigned char *cp, int size)
{
	unsigned short crc = 0x0000;

	if (size < 3)
		return -1;

	crc = crc16(0, cp, size);

	if (crc != 0x0000)
		return -1;

	return 0;
}

R
Ralf Baechle 已提交
167 168 169
/*
 * Standard encapsulation
 */
L
Linus Torvalds 已提交
170

R
Ralf Baechle 已提交
171
static int kiss_esc(unsigned char *s, unsigned char *d, int len)
L
Linus Torvalds 已提交
172
{
R
Ralf Baechle 已提交
173 174
	unsigned char *ptr = d;
	unsigned char c;
L
Linus Torvalds 已提交
175

R
Ralf Baechle 已提交
176 177 178 179
	/*
	 * Send an initial END character to flush out any data that may have
	 * accumulated in the receiver due to line noise.
	 */
L
Linus Torvalds 已提交
180

R
Ralf Baechle 已提交
181
	*ptr++ = END;
L
Linus Torvalds 已提交
182

R
Ralf Baechle 已提交
183 184 185 186 187
	while (len-- > 0) {
		switch (c = *s++) {
		case END:
			*ptr++ = ESC;
			*ptr++ = ESC_END;
L
Linus Torvalds 已提交
188
			break;
R
Ralf Baechle 已提交
189 190 191 192 193 194 195 196
		case ESC:
			*ptr++ = ESC;
			*ptr++ = ESC_ESC;
			break;
		default:
			*ptr++ = c;
			break;
		}
L
Linus Torvalds 已提交
197 198
	}

R
Ralf Baechle 已提交
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
	*ptr++ = END;

	return ptr - d;
}

/*
 * MW:
 * OK its ugly, but tell me a better solution without copying the
 * packet to a temporary buffer :-)
 */
static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc,
	int len)
{
	unsigned char *ptr = d;
	unsigned char c=0;

	*ptr++ = END;
	while (len > 0) {
		if (len > 2)
			c = *s++;
		else if (len > 1)
			c = crc >> 8;
		else if (len > 0)
			c = crc & 0xff;

		len--;
L
Linus Torvalds 已提交
225

R
Ralf Baechle 已提交
226 227 228 229 230 231 232 233 234 235 236 237 238
		switch (c) {
		case END:
			*ptr++ = ESC;
			*ptr++ = ESC_END;
			break;
		case ESC:
			*ptr++ = ESC;
			*ptr++ = ESC_ESC;
			break;
		default:
			*ptr++ = c;
			break;
		}
L
Linus Torvalds 已提交
239
	}
R
Ralf Baechle 已提交
240 241 242 243 244 245 246 247 248 249 250 251 252
	*ptr++ = END;

	return ptr - d;
}

/* Send one completely decapsulated AX.25 packet to the AX.25 layer. */
static void ax_bump(struct mkiss *ax)
{
	struct sk_buff *skb;
	int count;

	spin_lock_bh(&ax->buflock);
	if (ax->rbuff[0] > 0x0f) {
R
Ralf Baechle 已提交
253 254
		if (ax->rbuff[0] & 0x80) {
			if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
255
				ax->dev->stats.rx_errors++;
R
Ralf Baechle 已提交
256 257 258 259 260 261
				spin_unlock_bh(&ax->buflock);

				return;
			}
			if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) {
				printk(KERN_INFO
R
Ralf Baechle 已提交
262
				       "mkiss: %s: Switching to crc-smack\n",
R
Ralf Baechle 已提交
263 264 265 266 267 268
				       ax->dev->name);
				ax->crcmode = CRC_MODE_SMACK;
			}
			ax->rcount -= 2;
			*ax->rbuff &= ~0x80;
		} else if (ax->rbuff[0] & 0x20)  {
R
Ralf Baechle 已提交
269
			if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
270
				ax->dev->stats.rx_errors++;
R
Ralf Baechle 已提交
271
				spin_unlock_bh(&ax->buflock);
R
Ralf Baechle 已提交
272 273
				return;
			}
R
Ralf Baechle 已提交
274 275
			if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
				printk(KERN_INFO
R
Ralf Baechle 已提交
276
				       "mkiss: %s: Switching to crc-flexnet\n",
R
Ralf Baechle 已提交
277 278 279
				       ax->dev->name);
				ax->crcmode = CRC_MODE_FLEX;
			}
R
Ralf Baechle 已提交
280
			ax->rcount -= 2;
R
Ralf Baechle 已提交
281 282 283 284 285 286

			/*
			 * dl9sau bugfix: the trailling two bytes flexnet crc
			 * will not be passed to the kernel. thus we have to
			 * correct the kissparm signature, because it indicates
			 * a crc but there's none
R
Ralf Baechle 已提交
287
			 */
R
Ralf Baechle 已提交
288
			*ax->rbuff &= ~0x20;
L
Linus Torvalds 已提交
289
		}
R
Ralf Baechle 已提交
290 291 292 293 294 295 296
 	}

	count = ax->rcount;

	if ((skb = dev_alloc_skb(count)) == NULL) {
		printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n",
		       ax->dev->name);
297
		ax->dev->stats.rx_dropped++;
J
Jarek Poplawski 已提交
298
		spin_unlock_bh(&ax->buflock);
R
Ralf Baechle 已提交
299
		return;
L
Linus Torvalds 已提交
300 301
	}

R
Ralf Baechle 已提交
302 303 304
	memcpy(skb_put(skb,count), ax->rbuff, count);
	skb->protocol = ax25_type_trans(skb, ax->dev);
	netif_rx(skb);
305 306
	ax->dev->stats.rx_packets++;
	ax->dev->stats.rx_bytes += count;
J
Jarek Poplawski 已提交
307
	spin_unlock_bh(&ax->buflock);
L
Linus Torvalds 已提交
308 309
}

R
Ralf Baechle 已提交
310
static void kiss_unesc(struct mkiss *ax, unsigned char s)
L
Linus Torvalds 已提交
311
{
R
Ralf Baechle 已提交
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
	switch (s) {
	case END:
		/* drop keeptest bit = VSV */
		if (test_bit(AXF_KEEPTEST, &ax->flags))
			clear_bit(AXF_KEEPTEST, &ax->flags);

		if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2))
			ax_bump(ax);

		clear_bit(AXF_ESCAPE, &ax->flags);
		ax->rcount = 0;
		return;

	case ESC:
		set_bit(AXF_ESCAPE, &ax->flags);
		return;
	case ESC_ESC:
		if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
			s = ESC;
		break;
	case ESC_END:
		if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
			s = END;
		break;
	}

	spin_lock_bh(&ax->buflock);
	if (!test_bit(AXF_ERROR, &ax->flags)) {
		if (ax->rcount < ax->buffsize) {
			ax->rbuff[ax->rcount++] = s;
			spin_unlock_bh(&ax->buflock);
			return;
		}

346
		ax->dev->stats.rx_over_errors++;
R
Ralf Baechle 已提交
347 348 349 350 351 352 353 354 355
		set_bit(AXF_ERROR, &ax->flags);
	}
	spin_unlock_bh(&ax->buflock);
}

static int ax_set_mac_address(struct net_device *dev, void *addr)
{
	struct sockaddr_ax25 *sa = addr;

H
Herbert Xu 已提交
356
	netif_tx_lock_bh(dev);
357
	netif_addr_lock(dev);
R
Ralf Baechle 已提交
358
	memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
359
	netif_addr_unlock(dev);
H
Herbert Xu 已提交
360
	netif_tx_unlock_bh(dev);
R
Ralf Baechle 已提交
361 362

	return 0;
L
Linus Torvalds 已提交
363 364
}

R
Ralf Baechle 已提交
365 366 367
/*---------------------------------------------------------------------------*/

static void ax_changedmtu(struct mkiss *ax)
L
Linus Torvalds 已提交
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
{
	struct net_device *dev = ax->dev;
	unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
	int len;

	len = dev->mtu * 2;

	/*
	 * allow for arrival of larger UDP packets, even if we say not to
	 * also fixes a bug in which SunOS sends 512-byte packets even with
	 * an MSS of 128
	 */
	if (len < 576 * 2)
		len = 576 * 2;

	xbuff = kmalloc(len + 4, GFP_ATOMIC);
	rbuff = kmalloc(len + 4, GFP_ATOMIC);

	if (xbuff == NULL || rbuff == NULL)  {
R
Ralf Baechle 已提交
387 388
		printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, "
		       "MTU change cancelled.\n",
L
Linus Torvalds 已提交
389 390
		       ax->dev->name);
		dev->mtu = ax->mtu;
391 392
		kfree(xbuff);
		kfree(rbuff);
L
Linus Torvalds 已提交
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
		return;
	}

	spin_lock_bh(&ax->buflock);

	oxbuff    = ax->xbuff;
	ax->xbuff = xbuff;
	orbuff    = ax->rbuff;
	ax->rbuff = rbuff;

	if (ax->xleft) {
		if (ax->xleft <= len) {
			memcpy(ax->xbuff, ax->xhead, ax->xleft);
		} else  {
			ax->xleft = 0;
408
			dev->stats.tx_dropped++;
L
Linus Torvalds 已提交
409 410 411 412 413 414 415 416 417 418
		}
	}

	ax->xhead = ax->xbuff;

	if (ax->rcount) {
		if (ax->rcount <= len) {
			memcpy(ax->rbuff, orbuff, ax->rcount);
		} else  {
			ax->rcount = 0;
419
			dev->stats.rx_over_errors++;
L
Linus Torvalds 已提交
420 421 422 423 424 425 426 427 428
			set_bit(AXF_ERROR, &ax->flags);
		}
	}

	ax->mtu      = dev->mtu + 73;
	ax->buffsize = len;

	spin_unlock_bh(&ax->buflock);

R
Ralf Baechle 已提交
429 430
	kfree(oxbuff);
	kfree(orbuff);
L
Linus Torvalds 已提交
431 432 433
}

/* Encapsulate one AX.25 packet and stuff into a TTY queue. */
R
Ralf Baechle 已提交
434
static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
L
Linus Torvalds 已提交
435
{
R
Ralf Baechle 已提交
436
	struct mkiss *ax = netdev_priv(dev);
L
Linus Torvalds 已提交
437 438 439 440 441 442 443 444 445
	unsigned char *p;
	int actual, count;

	if (ax->mtu != ax->dev->mtu + 73)	/* Someone has been ifconfigging */
		ax_changedmtu(ax);

	if (len > ax->mtu) {		/* Sigh, shouldn't occur BUT ... */
		len = ax->mtu;
		printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name);
446
		dev->stats.tx_dropped++;
R
Ralf Baechle 已提交
447
		netif_start_queue(dev);
L
Linus Torvalds 已提交
448 449 450 451 452 453
		return;
	}

	p = icp;

	spin_lock_bh(&ax->buflock);
R
Ralf Baechle 已提交
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
	if ((*p & 0x0f) != 0) {
		/* Configuration Command (kissparms(1).
		 * Protocol spec says: never append CRC.
		 * This fixes a very old bug in the linux
		 * kiss driver. -- dl9sau */
		switch (*p & 0xff) {
		case 0x85:
			/* command from userspace especially for us,
			 * not for delivery to the tnc */
			if (len > 1) {
				int cmd = (p[1] & 0xff);
				switch(cmd) {
				case 3:
				  ax->crcmode = CRC_MODE_SMACK;
				  break;
				case 2:
				  ax->crcmode = CRC_MODE_FLEX;
				  break;
				case 1:
				  ax->crcmode = CRC_MODE_NONE;
				  break;
				case 0:
				default:
				  ax->crcmode = CRC_MODE_SMACK_TEST;
				  cmd = 0;
				}
				ax->crcauto = (cmd ? 0 : 1);
				printk(KERN_INFO "mkiss: %s: crc mode %s %d\n", ax->dev->name, (len) ? "set to" : "is", cmd);
			}
			spin_unlock_bh(&ax->buflock);
			netif_start_queue(dev);
L
Linus Torvalds 已提交
485

R
Ralf Baechle 已提交
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
			return;
		default:
			count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
		}
	} else {
		unsigned short crc;
		switch (ax->crcmode) {
		case CRC_MODE_SMACK_TEST:
			ax->crcmode  = CRC_MODE_FLEX_TEST;
			printk(KERN_INFO "mkiss: %s: Trying crc-smack\n", ax->dev->name);
			// fall through
		case CRC_MODE_SMACK:
			*p |= 0x80;
			crc = swab16(crc16(0, p, len));
			count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
			break;
		case CRC_MODE_FLEX_TEST:
			ax->crcmode = CRC_MODE_NONE;
			printk(KERN_INFO "mkiss: %s: Trying crc-flexnet\n", ax->dev->name);
			// fall through
		case CRC_MODE_FLEX:
			*p |= 0x20;
			crc = calc_crc_flex(p, len);
			count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
			break;

		default:
			count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
		}
  	}
516
	spin_unlock_bh(&ax->buflock);
L
Linus Torvalds 已提交
517

R
Ralf Baechle 已提交
518
	set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
A
Alan Cox 已提交
519
	actual = ax->tty->ops->write(ax->tty, ax->xbuff, count);
520 521
	dev->stats.tx_packets++;
	dev->stats.tx_bytes += actual;
R
Ralf Baechle 已提交
522

L
Linus Torvalds 已提交
523 524 525 526 527 528
	ax->dev->trans_start = jiffies;
	ax->xleft = count - actual;
	ax->xhead = ax->xbuff + actual;
}

/* Encapsulate an AX.25 packet and kick it into a TTY queue. */
529
static netdev_tx_t ax_xmit(struct sk_buff *skb, struct net_device *dev)
L
Linus Torvalds 已提交
530
{
R
Ralf Baechle 已提交
531
	struct mkiss *ax = netdev_priv(dev);
L
Linus Torvalds 已提交
532 533 534

	if (!netif_running(dev))  {
		printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name);
535
		return NETDEV_TX_BUSY;
L
Linus Torvalds 已提交
536 537 538 539 540 541 542
	}

	if (netif_queue_stopped(dev)) {
		/*
		 * May be we must check transmitter timeout here ?
		 *      14 Oct 1994 Dmitry Gorodchanin.
		 */
543
		if (time_before(jiffies, dev->trans_start + 20 * HZ)) {
L
Linus Torvalds 已提交
544
			/* 20 sec timeout not reached */
545
			return NETDEV_TX_BUSY;
L
Linus Torvalds 已提交
546 547 548
		}

		printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name,
549
		       (tty_chars_in_buffer(ax->tty) || ax->xleft) ?
L
Linus Torvalds 已提交
550 551 552
		       "bad line quality" : "driver error");

		ax->xleft = 0;
R
Ralf Baechle 已提交
553 554
		clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
		netif_start_queue(dev);
L
Linus Torvalds 已提交
555 556 557 558
	}

	/* We were not busy, so we are now... :-) */
	if (skb != NULL) {
R
Ralf Baechle 已提交
559 560
		netif_stop_queue(dev);
		ax_encaps(dev, skb->data, skb->len);
L
Linus Torvalds 已提交
561 562 563
		kfree_skb(skb);
	}

564
	return NETDEV_TX_OK;
L
Linus Torvalds 已提交
565 566
}

R
Ralf Baechle 已提交
567 568 569 570 571 572 573 574 575 576
static int ax_open_dev(struct net_device *dev)
{
	struct mkiss *ax = netdev_priv(dev);

	if (ax->tty == NULL)
		return -ENODEV;

	return 0;
}

L
Linus Torvalds 已提交
577 578 579
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)

/* Return the frame type ID */
580 581 582
static int ax_header(struct sk_buff *skb, struct net_device *dev,
		     unsigned short type, const void *daddr,
		     const void *saddr, unsigned len)
L
Linus Torvalds 已提交
583 584
{
#ifdef CONFIG_INET
585
	if (type != ETH_P_AX25)
586
		return ax25_hard_header(skb, dev, type, daddr, saddr, len);
L
Linus Torvalds 已提交
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
#endif
	return 0;
}


static int ax_rebuild_header(struct sk_buff *skb)
{
#ifdef CONFIG_INET
	return ax25_rebuild_header(skb);
#else
	return 0;
#endif
}

#endif	/* CONFIG_{AX25,AX25_MODULE} */

/* Open the low-level part of the AX25 channel. Easy! */
static int ax_open(struct net_device *dev)
{
R
Ralf Baechle 已提交
606
	struct mkiss *ax = netdev_priv(dev);
L
Linus Torvalds 已提交
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655
	unsigned long len;

	if (ax->tty == NULL)
		return -ENODEV;

	/*
	 * Allocate the frame buffers:
	 *
	 * rbuff	Receive buffer.
	 * xbuff	Transmit buffer.
	 */
	len = dev->mtu * 2;

	/*
	 * allow for arrival of larger UDP packets, even if we say not to
	 * also fixes a bug in which SunOS sends 512-byte packets even with
	 * an MSS of 128
	 */
	if (len < 576 * 2)
		len = 576 * 2;

	if ((ax->rbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
		goto norbuff;

	if ((ax->xbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
		goto noxbuff;

	ax->mtu	     = dev->mtu + 73;
	ax->buffsize = len;
	ax->rcount   = 0;
	ax->xleft    = 0;

	ax->flags   &= (1 << AXF_INUSE);      /* Clear ESCAPE & ERROR flags */

	spin_lock_init(&ax->buflock);

	return 0;

noxbuff:
	kfree(ax->rbuff);

norbuff:
	return -ENOMEM;
}


/* Close the low-level part of the AX25 channel. Easy! */
static int ax_close(struct net_device *dev)
{
R
Ralf Baechle 已提交
656
	struct mkiss *ax = netdev_priv(dev);
L
Linus Torvalds 已提交
657

R
Ralf Baechle 已提交
658 659
	if (ax->tty)
		clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
L
Linus Torvalds 已提交
660 661 662 663 664 665

	netif_stop_queue(dev);

	return 0;
}

666 667 668 669 670
static const struct header_ops ax_header_ops = {
	.create    = ax_header,
	.rebuild   = ax_rebuild_header,
};

671 672 673 674 675 676 677
static const struct net_device_ops ax_netdev_ops = {
	.ndo_open            = ax_open_dev,
	.ndo_stop            = ax_close,
	.ndo_start_xmit	     = ax_xmit,
	.ndo_set_mac_address = ax_set_mac_address,
};

R
Ralf Baechle 已提交
678 679 680 681 682 683 684 685
static void ax_setup(struct net_device *dev)
{
	/* Finish setting up the DEVICE info. */
	dev->mtu             = AX_MTU;
	dev->hard_header_len = 0;
	dev->addr_len        = 0;
	dev->type            = ARPHRD_AX25;
	dev->tx_queue_len    = 10;
686
	dev->header_ops      = &ax_header_ops;
687
	dev->netdev_ops	     = &ax_netdev_ops;
688

R
Ralf Baechle 已提交
689

690 691
	memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
	memcpy(dev->dev_addr,  &ax25_defaddr,  AX25_ADDR_LEN);
R
Ralf Baechle 已提交
692 693

	dev->flags      = IFF_BROADCAST | IFF_MULTICAST;
L
Linus Torvalds 已提交
694 695 696
}

/*
R
Ralf Baechle 已提交
697 698 699 700 701 702
 * We have a potential race on dereferencing tty->disc_data, because the tty
 * layer provides no locking at all - thus one cpu could be running
 * sixpack_receive_buf while another calls sixpack_close, which zeroes
 * tty->disc_data and frees the memory that sixpack_receive_buf is using.  The
 * best way to fix this is to use a rwlock in the tty struct, but for now we
 * use a single global rwlock for all ttys in ppp line discipline.
L
Linus Torvalds 已提交
703
 */
704
static DEFINE_RWLOCK(disc_data_lock);
R
Ralf Baechle 已提交
705 706

static struct mkiss *mkiss_get(struct tty_struct *tty)
L
Linus Torvalds 已提交
707
{
R
Ralf Baechle 已提交
708
	struct mkiss *ax;
L
Linus Torvalds 已提交
709

R
Ralf Baechle 已提交
710 711 712 713 714
	read_lock(&disc_data_lock);
	ax = tty->disc_data;
	if (ax)
		atomic_inc(&ax->refcnt);
	read_unlock(&disc_data_lock);
L
Linus Torvalds 已提交
715

R
Ralf Baechle 已提交
716 717
	return ax;
}
L
Linus Torvalds 已提交
718

R
Ralf Baechle 已提交
719 720 721 722
static void mkiss_put(struct mkiss *ax)
{
	if (atomic_dec_and_test(&ax->refcnt))
		up(&ax->dead_sem);
L
Linus Torvalds 已提交
723 724
}

R
Ralf Baechle 已提交
725 726
static int crc_force = 0;	/* Can be overridden with insmod */

R
Ralf Baechle 已提交
727
static int mkiss_open(struct tty_struct *tty)
L
Linus Torvalds 已提交
728
{
R
Ralf Baechle 已提交
729 730
	struct net_device *dev;
	struct mkiss *ax;
L
Linus Torvalds 已提交
731 732
	int err;

R
Ralf Baechle 已提交
733 734
	if (!capable(CAP_NET_ADMIN))
		return -EPERM;
A
Alan Cox 已提交
735 736
	if (tty->ops->write == NULL)
		return -EOPNOTSUPP;
L
Linus Torvalds 已提交
737

R
Ralf Baechle 已提交
738 739 740 741 742 743 744 745 746 747 748 749
	dev = alloc_netdev(sizeof(struct mkiss), "ax%d", ax_setup);
	if (!dev) {
		err = -ENOMEM;
		goto out;
	}

	ax = netdev_priv(dev);
	ax->dev = dev;

	spin_lock_init(&ax->buflock);
	atomic_set(&ax->refcnt, 1);
	init_MUTEX_LOCKED(&ax->dead_sem);
L
Linus Torvalds 已提交
750 751 752

	ax->tty = tty;
	tty->disc_data = ax;
A
Alan Cox 已提交
753
	tty->receive_room = 65535;
L
Linus Torvalds 已提交
754

A
Alan Cox 已提交
755
	tty_driver_flush_buffer(tty);
L
Linus Torvalds 已提交
756 757

	/* Restore default settings */
R
Ralf Baechle 已提交
758
	dev->type = ARPHRD_AX25;
L
Linus Torvalds 已提交
759 760

	/* Perform the low-level AX25 initialization. */
R
Ralf Baechle 已提交
761 762 763
	if ((err = ax_open(ax->dev))) {
		goto out_free_netdev;
	}
L
Linus Torvalds 已提交
764

R
Ralf Baechle 已提交
765 766
	if (register_netdev(dev))
		goto out_free_buffers;
L
Linus Torvalds 已提交
767

R
Ralf Baechle 已提交
768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
	/* after register_netdev() - because else printk smashes the kernel */
	switch (crc_force) {
	case 3:
		ax->crcmode  = CRC_MODE_SMACK;
		printk(KERN_INFO "mkiss: %s: crc mode smack forced.\n",
		       ax->dev->name);
		break;
	case 2:
		ax->crcmode  = CRC_MODE_FLEX;
		printk(KERN_INFO "mkiss: %s: crc mode flexnet forced.\n",
		       ax->dev->name);
		break;
	case 1:
		ax->crcmode  = CRC_MODE_NONE;
		printk(KERN_INFO "mkiss: %s: crc mode disabled.\n",
		       ax->dev->name);
		break;
	case 0:
		/* fall through */
	default:
		crc_force = 0;
		printk(KERN_INFO "mkiss: %s: crc mode is auto.\n",
		       ax->dev->name);
		ax->crcmode  = CRC_MODE_SMACK_TEST;
	}
	ax->crcauto = (crc_force ? 0 : 1);

R
Ralf Baechle 已提交
795
	netif_start_queue(dev);
L
Linus Torvalds 已提交
796

R
Ralf Baechle 已提交
797 798
	/* Done.  We have linked the TTY line to a channel. */
	return 0;
L
Linus Torvalds 已提交
799

R
Ralf Baechle 已提交
800 801 802
out_free_buffers:
	kfree(ax->rbuff);
	kfree(ax->xbuff);
L
Linus Torvalds 已提交
803

R
Ralf Baechle 已提交
804 805
out_free_netdev:
	free_netdev(dev);
L
Linus Torvalds 已提交
806

R
Ralf Baechle 已提交
807 808
out:
	return err;
L
Linus Torvalds 已提交
809 810
}

R
Ralf Baechle 已提交
811
static void mkiss_close(struct tty_struct *tty)
L
Linus Torvalds 已提交
812
{
R
Ralf Baechle 已提交
813
	struct mkiss *ax;
L
Linus Torvalds 已提交
814

R
Ralf Baechle 已提交
815 816 817 818
	write_lock(&disc_data_lock);
	ax = tty->disc_data;
	tty->disc_data = NULL;
	write_unlock(&disc_data_lock);
L
Linus Torvalds 已提交
819

A
Al Viro 已提交
820
	if (!ax)
R
Ralf Baechle 已提交
821
		return;
L
Linus Torvalds 已提交
822 823

	/*
R
Ralf Baechle 已提交
824 825
	 * We have now ensured that nobody can start using ap from now on, but
	 * we have to wait for all existing users to finish.
L
Linus Torvalds 已提交
826
	 */
R
Ralf Baechle 已提交
827 828
	if (!atomic_dec_and_test(&ax->refcnt))
		down(&ax->dead_sem);
L
Linus Torvalds 已提交
829

R
Ralf Baechle 已提交
830
	unregister_netdev(ax->dev);
L
Linus Torvalds 已提交
831

R
Ralf Baechle 已提交
832 833 834
	/* Free all AX25 frame buffers. */
	kfree(ax->rbuff);
	kfree(ax->xbuff);
L
Linus Torvalds 已提交
835

R
Ralf Baechle 已提交
836
	ax->tty = NULL;
L
Linus Torvalds 已提交
837 838
}

R
Ralf Baechle 已提交
839 840 841
/* Perform I/O control on an active ax25 channel. */
static int mkiss_ioctl(struct tty_struct *tty, struct file *file,
	unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
842
{
R
Ralf Baechle 已提交
843
	struct mkiss *ax = mkiss_get(tty);
844
	struct net_device *dev;
R
Ralf Baechle 已提交
845
	unsigned int tmp, err;
L
Linus Torvalds 已提交
846

R
Ralf Baechle 已提交
847 848 849
	/* First make sure we're connected. */
	if (ax == NULL)
		return -ENXIO;
850
	dev = ax->dev;
L
Linus Torvalds 已提交
851

R
Ralf Baechle 已提交
852 853 854 855 856 857 858 859 860 861 862 863 864 865
	switch (cmd) {
 	case SIOCGIFNAME:
		err = copy_to_user((void __user *) arg, ax->dev->name,
		                   strlen(ax->dev->name) + 1) ? -EFAULT : 0;
		break;

	case SIOCGIFENCAP:
		err = put_user(4, (int __user *) arg);
		break;

	case SIOCSIFENCAP:
		if (get_user(tmp, (int __user *) arg)) {
			err = -EFAULT;
			break;
L
Linus Torvalds 已提交
866 867
		}

R
Ralf Baechle 已提交
868 869 870 871 872
		ax->mode = tmp;
		dev->addr_len        = AX25_ADDR_LEN;
		dev->hard_header_len = AX25_KISS_HEADER_LEN +
		                       AX25_MAX_HEADER_LEN + 3;
		dev->type            = ARPHRD_AX25;
L
Linus Torvalds 已提交
873

R
Ralf Baechle 已提交
874 875
		err = 0;
		break;
L
Linus Torvalds 已提交
876

R
Ralf Baechle 已提交
877 878
	case SIOCSIFHWADDR: {
		char addr[AX25_ADDR_LEN];
L
Linus Torvalds 已提交
879

R
Ralf Baechle 已提交
880 881 882
		if (copy_from_user(&addr,
		                   (void __user *) arg, AX25_ADDR_LEN)) {
			err = -EFAULT;
L
Linus Torvalds 已提交
883 884 885
			break;
		}

H
Herbert Xu 已提交
886
		netif_tx_lock_bh(dev);
R
Ralf Baechle 已提交
887
		memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
H
Herbert Xu 已提交
888
		netif_tx_unlock_bh(dev);
R
Ralf Baechle 已提交
889 890 891 892 893 894

		err = 0;
		break;
	}
	default:
		err = -ENOIOCTLCMD;
L
Linus Torvalds 已提交
895 896
	}

R
Ralf Baechle 已提交
897
	mkiss_put(ax);
L
Linus Torvalds 已提交
898

R
Ralf Baechle 已提交
899
	return err;
L
Linus Torvalds 已提交
900 901
}

902 903 904 905
#ifdef CONFIG_COMPAT
static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file,
	unsigned int cmd, unsigned long arg)
{
906
	switch (cmd) {
907 908 909 910 911 912 913 914 915 916 917 918
	case SIOCGIFNAME:
	case SIOCGIFENCAP:
	case SIOCSIFENCAP:
	case SIOCSIFHWADDR:
		return mkiss_ioctl(tty, file, cmd,
				   (unsigned long)compat_ptr(arg));
	}

	return -ENOIOCTLCMD;
}
#endif

R
Ralf Baechle 已提交
919 920 921 922 923 924 925 926
/*
 * Handle the 'receiver data ready' interrupt.
 * This function is called by the 'tty_io' module in the kernel when
 * a block of data has been received, which can now be decapsulated
 * and sent on to the AX.25 layer for further processing.
 */
static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
	char *fp, int count)
L
Linus Torvalds 已提交
927
{
R
Ralf Baechle 已提交
928
	struct mkiss *ax = mkiss_get(tty);
L
Linus Torvalds 已提交
929

R
Ralf Baechle 已提交
930 931
	if (!ax)
		return;
L
Linus Torvalds 已提交
932

R
Ralf Baechle 已提交
933 934 935 936 937 938
	/*
	 * Argh! mtu change time! - costs us the packet part received
	 * at the change
	 */
	if (ax->mtu != ax->dev->mtu + 73)
		ax_changedmtu(ax);
L
Linus Torvalds 已提交
939

R
Ralf Baechle 已提交
940 941 942 943
	/* Read the characters out of the buffer */
	while (count--) {
		if (fp != NULL && *fp++) {
			if (!test_and_set_bit(AXF_ERROR, &ax->flags))
944
				ax->dev->stats.rx_errors++;
R
Ralf Baechle 已提交
945 946 947
			cp++;
			continue;
		}
L
Linus Torvalds 已提交
948

R
Ralf Baechle 已提交
949
		kiss_unesc(ax, *cp++);
L
Linus Torvalds 已提交
950
	}
R
Ralf Baechle 已提交
951 952

	mkiss_put(ax);
A
Alan Cox 已提交
953
	tty_unthrottle(tty);
L
Linus Torvalds 已提交
954 955
}

R
Ralf Baechle 已提交
956 957 958 959 960
/*
 * Called by the driver when there's room for more data.  If we have
 * more packets to send, we send them here.
 */
static void mkiss_write_wakeup(struct tty_struct *tty)
L
Linus Torvalds 已提交
961
{
R
Ralf Baechle 已提交
962 963
	struct mkiss *ax = mkiss_get(tty);
	int actual;
L
Linus Torvalds 已提交
964

R
Ralf Baechle 已提交
965 966
	if (!ax)
		return;
L
Linus Torvalds 已提交
967

R
Ralf Baechle 已提交
968 969 970 971 972
	if (ax->xleft <= 0)  {
		/* Now serial buffer is almost free & we can start
		 * transmission of another packet
		 */
		clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
L
Linus Torvalds 已提交
973

R
Ralf Baechle 已提交
974 975 976
		netif_wake_queue(ax->dev);
		goto out;
	}
L
Linus Torvalds 已提交
977

A
Alan Cox 已提交
978
	actual = tty->ops->write(tty, ax->xhead, ax->xleft);
R
Ralf Baechle 已提交
979 980
	ax->xleft -= actual;
	ax->xhead += actual;
L
Linus Torvalds 已提交
981

R
Ralf Baechle 已提交
982 983
out:
	mkiss_put(ax);
L
Linus Torvalds 已提交
984 985
}

A
Alan Cox 已提交
986
static struct tty_ldisc_ops ax_ldisc = {
987
	.owner		= THIS_MODULE,
R
Ralf Baechle 已提交
988 989 990 991 992
	.magic		= TTY_LDISC_MAGIC,
	.name		= "mkiss",
	.open		= mkiss_open,
	.close		= mkiss_close,
	.ioctl		= mkiss_ioctl,
993 994 995
#ifdef CONFIG_COMPAT
	.compat_ioctl	= mkiss_compat_ioctl,
#endif
R
Ralf Baechle 已提交
996 997 998
	.receive_buf	= mkiss_receive_buf,
	.write_wakeup	= mkiss_write_wakeup
};
L
Linus Torvalds 已提交
999

1000
static const char banner[] __initdata = KERN_INFO \
R
Ralf Baechle 已提交
1001
	"mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
1002
static const char msg_regfail[] __initdata = KERN_ERR \
R
Ralf Baechle 已提交
1003
	"mkiss: can't register line discipline (err = %d)\n";
L
Linus Torvalds 已提交
1004 1005 1006 1007 1008 1009 1010

static int __init mkiss_init_driver(void)
{
	int status;

	printk(banner);

1011 1012 1013
	status = tty_register_ldisc(N_AX25, &ax_ldisc);
	if (status != 0)
		printk(msg_regfail, status);
L
Linus Torvalds 已提交
1014 1015 1016 1017

	return status;
}

R
Ralf Baechle 已提交
1018 1019 1020
static const char msg_unregfail[] __exitdata = KERN_ERR \
	"mkiss: can't unregister line discipline (err = %d)\n";

L
Linus Torvalds 已提交
1021 1022
static void __exit mkiss_exit_driver(void)
{
R
Ralf Baechle 已提交
1023
	int ret;
L
Linus Torvalds 已提交
1024

R
Ralf Baechle 已提交
1025 1026
	if ((ret = tty_unregister_ldisc(N_AX25)))
		printk(msg_unregfail, ret);
L
Linus Torvalds 已提交
1027 1028
}

R
Ralf Baechle 已提交
1029
MODULE_AUTHOR("Ralf Baechle DL5RB <ralf@linux-mips.org>");
L
Linus Torvalds 已提交
1030
MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
R
Rusty Russell 已提交
1031
module_param(crc_force, int, 0);
R
Ralf Baechle 已提交
1032
MODULE_PARM_DESC(crc_force, "crc [0 = auto | 1 = none | 2 = flexnet | 3 = smack]");
L
Linus Torvalds 已提交
1033 1034
MODULE_LICENSE("GPL");
MODULE_ALIAS_LDISC(N_AX25);
R
Ralf Baechle 已提交
1035

L
Linus Torvalds 已提交
1036 1037
module_init(mkiss_init_driver);
module_exit(mkiss_exit_driver);