1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl>
5*4882a593Smuzhiyun * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org>
6*4882a593Smuzhiyun * Copyright (C) 2004, 05 Thomas Osterried DL9SAU <thomas@x-berg.in-berlin.de>
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun #include <linux/module.h>
9*4882a593Smuzhiyun #include <linux/bitops.h>
10*4882a593Smuzhiyun #include <linux/uaccess.h>
11*4882a593Smuzhiyun #include <linux/crc16.h>
12*4882a593Smuzhiyun #include <linux/string.h>
13*4882a593Smuzhiyun #include <linux/mm.h>
14*4882a593Smuzhiyun #include <linux/interrupt.h>
15*4882a593Smuzhiyun #include <linux/in.h>
16*4882a593Smuzhiyun #include <linux/inet.h>
17*4882a593Smuzhiyun #include <linux/slab.h>
18*4882a593Smuzhiyun #include <linux/tty.h>
19*4882a593Smuzhiyun #include <linux/errno.h>
20*4882a593Smuzhiyun #include <linux/netdevice.h>
21*4882a593Smuzhiyun #include <linux/major.h>
22*4882a593Smuzhiyun #include <linux/init.h>
23*4882a593Smuzhiyun #include <linux/rtnetlink.h>
24*4882a593Smuzhiyun #include <linux/etherdevice.h>
25*4882a593Smuzhiyun #include <linux/skbuff.h>
26*4882a593Smuzhiyun #include <linux/if_arp.h>
27*4882a593Smuzhiyun #include <linux/jiffies.h>
28*4882a593Smuzhiyun #include <linux/refcount.h>
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #include <net/ax25.h>
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #define AX_MTU 236
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun /* some arch define END as assembly function ending, just undef it */
35*4882a593Smuzhiyun #undef END
36*4882a593Smuzhiyun /* SLIP/KISS protocol characters. */
37*4882a593Smuzhiyun #define END 0300 /* indicates end of frame */
38*4882a593Smuzhiyun #define ESC 0333 /* indicates byte stuffing */
39*4882a593Smuzhiyun #define ESC_END 0334 /* ESC ESC_END means END 'data' */
40*4882a593Smuzhiyun #define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun struct mkiss {
43*4882a593Smuzhiyun struct tty_struct *tty; /* ptr to TTY structure */
44*4882a593Smuzhiyun struct net_device *dev; /* easy for intr handling */
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun /* These are pointers to the malloc()ed frame buffers. */
47*4882a593Smuzhiyun spinlock_t buflock;/* lock for rbuf and xbuf */
48*4882a593Smuzhiyun unsigned char *rbuff; /* receiver buffer */
49*4882a593Smuzhiyun int rcount; /* received chars counter */
50*4882a593Smuzhiyun unsigned char *xbuff; /* transmitter buffer */
51*4882a593Smuzhiyun unsigned char *xhead; /* pointer to next byte to XMIT */
52*4882a593Smuzhiyun int xleft; /* bytes left in XMIT queue */
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun /* Detailed SLIP statistics. */
55*4882a593Smuzhiyun int mtu; /* Our mtu (to spot changes!) */
56*4882a593Smuzhiyun int buffsize; /* Max buffers sizes */
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun unsigned long flags; /* Flag values/ mode etc */
59*4882a593Smuzhiyun /* long req'd: used by set_bit --RR */
60*4882a593Smuzhiyun #define AXF_INUSE 0 /* Channel in use */
61*4882a593Smuzhiyun #define AXF_ESCAPE 1 /* ESC received */
62*4882a593Smuzhiyun #define AXF_ERROR 2 /* Parity, etc. error */
63*4882a593Smuzhiyun #define AXF_KEEPTEST 3 /* Keepalive test flag */
64*4882a593Smuzhiyun #define AXF_OUTWAIT 4 /* is outpacket was flag */
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun int mode;
67*4882a593Smuzhiyun int crcmode; /* MW: for FlexNet, SMACK etc. */
68*4882a593Smuzhiyun int crcauto; /* CRC auto mode */
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun #define CRC_MODE_NONE 0
71*4882a593Smuzhiyun #define CRC_MODE_FLEX 1
72*4882a593Smuzhiyun #define CRC_MODE_SMACK 2
73*4882a593Smuzhiyun #define CRC_MODE_FLEX_TEST 3
74*4882a593Smuzhiyun #define CRC_MODE_SMACK_TEST 4
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun refcount_t refcnt;
77*4882a593Smuzhiyun struct completion dead;
78*4882a593Smuzhiyun };
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun /*---------------------------------------------------------------------------*/
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun static const unsigned short crc_flex_table[] = {
83*4882a593Smuzhiyun 0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38,
84*4882a593Smuzhiyun 0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770,
85*4882a593Smuzhiyun 0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9,
86*4882a593Smuzhiyun 0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1,
87*4882a593Smuzhiyun 0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a,
88*4882a593Smuzhiyun 0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672,
89*4882a593Smuzhiyun 0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb,
90*4882a593Smuzhiyun 0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3,
91*4882a593Smuzhiyun 0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c,
92*4882a593Smuzhiyun 0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574,
93*4882a593Smuzhiyun 0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd,
94*4882a593Smuzhiyun 0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5,
95*4882a593Smuzhiyun 0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e,
96*4882a593Smuzhiyun 0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476,
97*4882a593Smuzhiyun 0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf,
98*4882a593Smuzhiyun 0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7,
99*4882a593Smuzhiyun 0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30,
100*4882a593Smuzhiyun 0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378,
101*4882a593Smuzhiyun 0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1,
102*4882a593Smuzhiyun 0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9,
103*4882a593Smuzhiyun 0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32,
104*4882a593Smuzhiyun 0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a,
105*4882a593Smuzhiyun 0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3,
106*4882a593Smuzhiyun 0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb,
107*4882a593Smuzhiyun 0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34,
108*4882a593Smuzhiyun 0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c,
109*4882a593Smuzhiyun 0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5,
110*4882a593Smuzhiyun 0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd,
111*4882a593Smuzhiyun 0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36,
112*4882a593Smuzhiyun 0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e,
113*4882a593Smuzhiyun 0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7,
114*4882a593Smuzhiyun 0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff
115*4882a593Smuzhiyun };
116*4882a593Smuzhiyun
calc_crc_flex(unsigned char * cp,int size)117*4882a593Smuzhiyun static unsigned short calc_crc_flex(unsigned char *cp, int size)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun unsigned short crc = 0xffff;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun while (size--)
122*4882a593Smuzhiyun crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun return crc;
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
check_crc_flex(unsigned char * cp,int size)127*4882a593Smuzhiyun static int check_crc_flex(unsigned char *cp, int size)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun unsigned short crc = 0xffff;
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun if (size < 3)
132*4882a593Smuzhiyun return -1;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun while (size--)
135*4882a593Smuzhiyun crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun if ((crc & 0xffff) != 0x7070)
138*4882a593Smuzhiyun return -1;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun return 0;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun
check_crc_16(unsigned char * cp,int size)143*4882a593Smuzhiyun static int check_crc_16(unsigned char *cp, int size)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun unsigned short crc = 0x0000;
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun if (size < 3)
148*4882a593Smuzhiyun return -1;
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun crc = crc16(0, cp, size);
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun if (crc != 0x0000)
153*4882a593Smuzhiyun return -1;
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun return 0;
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun /*
159*4882a593Smuzhiyun * Standard encapsulation
160*4882a593Smuzhiyun */
161*4882a593Smuzhiyun
kiss_esc(unsigned char * s,unsigned char * d,int len)162*4882a593Smuzhiyun static int kiss_esc(unsigned char *s, unsigned char *d, int len)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun unsigned char *ptr = d;
165*4882a593Smuzhiyun unsigned char c;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun /*
168*4882a593Smuzhiyun * Send an initial END character to flush out any data that may have
169*4882a593Smuzhiyun * accumulated in the receiver due to line noise.
170*4882a593Smuzhiyun */
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun *ptr++ = END;
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun while (len-- > 0) {
175*4882a593Smuzhiyun switch (c = *s++) {
176*4882a593Smuzhiyun case END:
177*4882a593Smuzhiyun *ptr++ = ESC;
178*4882a593Smuzhiyun *ptr++ = ESC_END;
179*4882a593Smuzhiyun break;
180*4882a593Smuzhiyun case ESC:
181*4882a593Smuzhiyun *ptr++ = ESC;
182*4882a593Smuzhiyun *ptr++ = ESC_ESC;
183*4882a593Smuzhiyun break;
184*4882a593Smuzhiyun default:
185*4882a593Smuzhiyun *ptr++ = c;
186*4882a593Smuzhiyun break;
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun *ptr++ = END;
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun return ptr - d;
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun /*
196*4882a593Smuzhiyun * MW:
197*4882a593Smuzhiyun * OK its ugly, but tell me a better solution without copying the
198*4882a593Smuzhiyun * packet to a temporary buffer :-)
199*4882a593Smuzhiyun */
kiss_esc_crc(unsigned char * s,unsigned char * d,unsigned short crc,int len)200*4882a593Smuzhiyun static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc,
201*4882a593Smuzhiyun int len)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun unsigned char *ptr = d;
204*4882a593Smuzhiyun unsigned char c=0;
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun *ptr++ = END;
207*4882a593Smuzhiyun while (len > 0) {
208*4882a593Smuzhiyun if (len > 2)
209*4882a593Smuzhiyun c = *s++;
210*4882a593Smuzhiyun else if (len > 1)
211*4882a593Smuzhiyun c = crc >> 8;
212*4882a593Smuzhiyun else
213*4882a593Smuzhiyun c = crc & 0xff;
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun len--;
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun switch (c) {
218*4882a593Smuzhiyun case END:
219*4882a593Smuzhiyun *ptr++ = ESC;
220*4882a593Smuzhiyun *ptr++ = ESC_END;
221*4882a593Smuzhiyun break;
222*4882a593Smuzhiyun case ESC:
223*4882a593Smuzhiyun *ptr++ = ESC;
224*4882a593Smuzhiyun *ptr++ = ESC_ESC;
225*4882a593Smuzhiyun break;
226*4882a593Smuzhiyun default:
227*4882a593Smuzhiyun *ptr++ = c;
228*4882a593Smuzhiyun break;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun *ptr++ = END;
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun return ptr - d;
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun /* Send one completely decapsulated AX.25 packet to the AX.25 layer. */
ax_bump(struct mkiss * ax)237*4882a593Smuzhiyun static void ax_bump(struct mkiss *ax)
238*4882a593Smuzhiyun {
239*4882a593Smuzhiyun struct sk_buff *skb;
240*4882a593Smuzhiyun int count;
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun spin_lock_bh(&ax->buflock);
243*4882a593Smuzhiyun if (ax->rbuff[0] > 0x0f) {
244*4882a593Smuzhiyun if (ax->rbuff[0] & 0x80) {
245*4882a593Smuzhiyun if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
246*4882a593Smuzhiyun ax->dev->stats.rx_errors++;
247*4882a593Smuzhiyun spin_unlock_bh(&ax->buflock);
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun return;
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) {
252*4882a593Smuzhiyun printk(KERN_INFO
253*4882a593Smuzhiyun "mkiss: %s: Switching to crc-smack\n",
254*4882a593Smuzhiyun ax->dev->name);
255*4882a593Smuzhiyun ax->crcmode = CRC_MODE_SMACK;
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun ax->rcount -= 2;
258*4882a593Smuzhiyun *ax->rbuff &= ~0x80;
259*4882a593Smuzhiyun } else if (ax->rbuff[0] & 0x20) {
260*4882a593Smuzhiyun if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
261*4882a593Smuzhiyun ax->dev->stats.rx_errors++;
262*4882a593Smuzhiyun spin_unlock_bh(&ax->buflock);
263*4882a593Smuzhiyun return;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
266*4882a593Smuzhiyun printk(KERN_INFO
267*4882a593Smuzhiyun "mkiss: %s: Switching to crc-flexnet\n",
268*4882a593Smuzhiyun ax->dev->name);
269*4882a593Smuzhiyun ax->crcmode = CRC_MODE_FLEX;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun ax->rcount -= 2;
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun /*
274*4882a593Smuzhiyun * dl9sau bugfix: the trailling two bytes flexnet crc
275*4882a593Smuzhiyun * will not be passed to the kernel. thus we have to
276*4882a593Smuzhiyun * correct the kissparm signature, because it indicates
277*4882a593Smuzhiyun * a crc but there's none
278*4882a593Smuzhiyun */
279*4882a593Smuzhiyun *ax->rbuff &= ~0x20;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun count = ax->rcount;
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun if ((skb = dev_alloc_skb(count)) == NULL) {
286*4882a593Smuzhiyun printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n",
287*4882a593Smuzhiyun ax->dev->name);
288*4882a593Smuzhiyun ax->dev->stats.rx_dropped++;
289*4882a593Smuzhiyun spin_unlock_bh(&ax->buflock);
290*4882a593Smuzhiyun return;
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun skb_put_data(skb, ax->rbuff, count);
294*4882a593Smuzhiyun skb->protocol = ax25_type_trans(skb, ax->dev);
295*4882a593Smuzhiyun netif_rx(skb);
296*4882a593Smuzhiyun ax->dev->stats.rx_packets++;
297*4882a593Smuzhiyun ax->dev->stats.rx_bytes += count;
298*4882a593Smuzhiyun spin_unlock_bh(&ax->buflock);
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun
kiss_unesc(struct mkiss * ax,unsigned char s)301*4882a593Smuzhiyun static void kiss_unesc(struct mkiss *ax, unsigned char s)
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun switch (s) {
304*4882a593Smuzhiyun case END:
305*4882a593Smuzhiyun /* drop keeptest bit = VSV */
306*4882a593Smuzhiyun if (test_bit(AXF_KEEPTEST, &ax->flags))
307*4882a593Smuzhiyun clear_bit(AXF_KEEPTEST, &ax->flags);
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2))
310*4882a593Smuzhiyun ax_bump(ax);
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun clear_bit(AXF_ESCAPE, &ax->flags);
313*4882a593Smuzhiyun ax->rcount = 0;
314*4882a593Smuzhiyun return;
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun case ESC:
317*4882a593Smuzhiyun set_bit(AXF_ESCAPE, &ax->flags);
318*4882a593Smuzhiyun return;
319*4882a593Smuzhiyun case ESC_ESC:
320*4882a593Smuzhiyun if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
321*4882a593Smuzhiyun s = ESC;
322*4882a593Smuzhiyun break;
323*4882a593Smuzhiyun case ESC_END:
324*4882a593Smuzhiyun if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
325*4882a593Smuzhiyun s = END;
326*4882a593Smuzhiyun break;
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun spin_lock_bh(&ax->buflock);
330*4882a593Smuzhiyun if (!test_bit(AXF_ERROR, &ax->flags)) {
331*4882a593Smuzhiyun if (ax->rcount < ax->buffsize) {
332*4882a593Smuzhiyun ax->rbuff[ax->rcount++] = s;
333*4882a593Smuzhiyun spin_unlock_bh(&ax->buflock);
334*4882a593Smuzhiyun return;
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun ax->dev->stats.rx_over_errors++;
338*4882a593Smuzhiyun set_bit(AXF_ERROR, &ax->flags);
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun spin_unlock_bh(&ax->buflock);
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
ax_set_mac_address(struct net_device * dev,void * addr)343*4882a593Smuzhiyun static int ax_set_mac_address(struct net_device *dev, void *addr)
344*4882a593Smuzhiyun {
345*4882a593Smuzhiyun struct sockaddr_ax25 *sa = addr;
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun netif_tx_lock_bh(dev);
348*4882a593Smuzhiyun netif_addr_lock(dev);
349*4882a593Smuzhiyun memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
350*4882a593Smuzhiyun netif_addr_unlock(dev);
351*4882a593Smuzhiyun netif_tx_unlock_bh(dev);
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun return 0;
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun /*---------------------------------------------------------------------------*/
357*4882a593Smuzhiyun
ax_changedmtu(struct mkiss * ax)358*4882a593Smuzhiyun static void ax_changedmtu(struct mkiss *ax)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun struct net_device *dev = ax->dev;
361*4882a593Smuzhiyun unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
362*4882a593Smuzhiyun int len;
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun len = dev->mtu * 2;
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun /*
367*4882a593Smuzhiyun * allow for arrival of larger UDP packets, even if we say not to
368*4882a593Smuzhiyun * also fixes a bug in which SunOS sends 512-byte packets even with
369*4882a593Smuzhiyun * an MSS of 128
370*4882a593Smuzhiyun */
371*4882a593Smuzhiyun if (len < 576 * 2)
372*4882a593Smuzhiyun len = 576 * 2;
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun xbuff = kmalloc(len + 4, GFP_ATOMIC);
375*4882a593Smuzhiyun rbuff = kmalloc(len + 4, GFP_ATOMIC);
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun if (xbuff == NULL || rbuff == NULL) {
378*4882a593Smuzhiyun printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, "
379*4882a593Smuzhiyun "MTU change cancelled.\n",
380*4882a593Smuzhiyun ax->dev->name);
381*4882a593Smuzhiyun dev->mtu = ax->mtu;
382*4882a593Smuzhiyun kfree(xbuff);
383*4882a593Smuzhiyun kfree(rbuff);
384*4882a593Smuzhiyun return;
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun spin_lock_bh(&ax->buflock);
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun oxbuff = ax->xbuff;
390*4882a593Smuzhiyun ax->xbuff = xbuff;
391*4882a593Smuzhiyun orbuff = ax->rbuff;
392*4882a593Smuzhiyun ax->rbuff = rbuff;
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun if (ax->xleft) {
395*4882a593Smuzhiyun if (ax->xleft <= len) {
396*4882a593Smuzhiyun memcpy(ax->xbuff, ax->xhead, ax->xleft);
397*4882a593Smuzhiyun } else {
398*4882a593Smuzhiyun ax->xleft = 0;
399*4882a593Smuzhiyun dev->stats.tx_dropped++;
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun ax->xhead = ax->xbuff;
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun if (ax->rcount) {
406*4882a593Smuzhiyun if (ax->rcount <= len) {
407*4882a593Smuzhiyun memcpy(ax->rbuff, orbuff, ax->rcount);
408*4882a593Smuzhiyun } else {
409*4882a593Smuzhiyun ax->rcount = 0;
410*4882a593Smuzhiyun dev->stats.rx_over_errors++;
411*4882a593Smuzhiyun set_bit(AXF_ERROR, &ax->flags);
412*4882a593Smuzhiyun }
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun ax->mtu = dev->mtu + 73;
416*4882a593Smuzhiyun ax->buffsize = len;
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun spin_unlock_bh(&ax->buflock);
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun kfree(oxbuff);
421*4882a593Smuzhiyun kfree(orbuff);
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun /* Encapsulate one AX.25 packet and stuff into a TTY queue. */
ax_encaps(struct net_device * dev,unsigned char * icp,int len)425*4882a593Smuzhiyun static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
426*4882a593Smuzhiyun {
427*4882a593Smuzhiyun struct mkiss *ax = netdev_priv(dev);
428*4882a593Smuzhiyun unsigned char *p;
429*4882a593Smuzhiyun int actual, count;
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun if (ax->mtu != ax->dev->mtu + 73) /* Someone has been ifconfigging */
432*4882a593Smuzhiyun ax_changedmtu(ax);
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun if (len > ax->mtu) { /* Sigh, shouldn't occur BUT ... */
435*4882a593Smuzhiyun printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name);
436*4882a593Smuzhiyun dev->stats.tx_dropped++;
437*4882a593Smuzhiyun netif_start_queue(dev);
438*4882a593Smuzhiyun return;
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun p = icp;
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun spin_lock_bh(&ax->buflock);
444*4882a593Smuzhiyun if ((*p & 0x0f) != 0) {
445*4882a593Smuzhiyun /* Configuration Command (kissparms(1).
446*4882a593Smuzhiyun * Protocol spec says: never append CRC.
447*4882a593Smuzhiyun * This fixes a very old bug in the linux
448*4882a593Smuzhiyun * kiss driver. -- dl9sau */
449*4882a593Smuzhiyun switch (*p & 0xff) {
450*4882a593Smuzhiyun case 0x85:
451*4882a593Smuzhiyun /* command from userspace especially for us,
452*4882a593Smuzhiyun * not for delivery to the tnc */
453*4882a593Smuzhiyun if (len > 1) {
454*4882a593Smuzhiyun int cmd = (p[1] & 0xff);
455*4882a593Smuzhiyun switch(cmd) {
456*4882a593Smuzhiyun case 3:
457*4882a593Smuzhiyun ax->crcmode = CRC_MODE_SMACK;
458*4882a593Smuzhiyun break;
459*4882a593Smuzhiyun case 2:
460*4882a593Smuzhiyun ax->crcmode = CRC_MODE_FLEX;
461*4882a593Smuzhiyun break;
462*4882a593Smuzhiyun case 1:
463*4882a593Smuzhiyun ax->crcmode = CRC_MODE_NONE;
464*4882a593Smuzhiyun break;
465*4882a593Smuzhiyun case 0:
466*4882a593Smuzhiyun default:
467*4882a593Smuzhiyun ax->crcmode = CRC_MODE_SMACK_TEST;
468*4882a593Smuzhiyun cmd = 0;
469*4882a593Smuzhiyun }
470*4882a593Smuzhiyun ax->crcauto = (cmd ? 0 : 1);
471*4882a593Smuzhiyun printk(KERN_INFO "mkiss: %s: crc mode set to %d\n",
472*4882a593Smuzhiyun ax->dev->name, cmd);
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun spin_unlock_bh(&ax->buflock);
475*4882a593Smuzhiyun netif_start_queue(dev);
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun return;
478*4882a593Smuzhiyun default:
479*4882a593Smuzhiyun count = kiss_esc(p, ax->xbuff, len);
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun } else {
482*4882a593Smuzhiyun unsigned short crc;
483*4882a593Smuzhiyun switch (ax->crcmode) {
484*4882a593Smuzhiyun case CRC_MODE_SMACK_TEST:
485*4882a593Smuzhiyun ax->crcmode = CRC_MODE_FLEX_TEST;
486*4882a593Smuzhiyun printk(KERN_INFO "mkiss: %s: Trying crc-smack\n", ax->dev->name);
487*4882a593Smuzhiyun fallthrough;
488*4882a593Smuzhiyun case CRC_MODE_SMACK:
489*4882a593Smuzhiyun *p |= 0x80;
490*4882a593Smuzhiyun crc = swab16(crc16(0, p, len));
491*4882a593Smuzhiyun count = kiss_esc_crc(p, ax->xbuff, crc, len+2);
492*4882a593Smuzhiyun break;
493*4882a593Smuzhiyun case CRC_MODE_FLEX_TEST:
494*4882a593Smuzhiyun ax->crcmode = CRC_MODE_NONE;
495*4882a593Smuzhiyun printk(KERN_INFO "mkiss: %s: Trying crc-flexnet\n", ax->dev->name);
496*4882a593Smuzhiyun fallthrough;
497*4882a593Smuzhiyun case CRC_MODE_FLEX:
498*4882a593Smuzhiyun *p |= 0x20;
499*4882a593Smuzhiyun crc = calc_crc_flex(p, len);
500*4882a593Smuzhiyun count = kiss_esc_crc(p, ax->xbuff, crc, len+2);
501*4882a593Smuzhiyun break;
502*4882a593Smuzhiyun
503*4882a593Smuzhiyun default:
504*4882a593Smuzhiyun count = kiss_esc(p, ax->xbuff, len);
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun spin_unlock_bh(&ax->buflock);
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
510*4882a593Smuzhiyun actual = ax->tty->ops->write(ax->tty, ax->xbuff, count);
511*4882a593Smuzhiyun dev->stats.tx_packets++;
512*4882a593Smuzhiyun dev->stats.tx_bytes += actual;
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun netif_trans_update(ax->dev);
515*4882a593Smuzhiyun ax->xleft = count - actual;
516*4882a593Smuzhiyun ax->xhead = ax->xbuff + actual;
517*4882a593Smuzhiyun }
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun /* Encapsulate an AX.25 packet and kick it into a TTY queue. */
ax_xmit(struct sk_buff * skb,struct net_device * dev)520*4882a593Smuzhiyun static netdev_tx_t ax_xmit(struct sk_buff *skb, struct net_device *dev)
521*4882a593Smuzhiyun {
522*4882a593Smuzhiyun struct mkiss *ax = netdev_priv(dev);
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun if (skb->protocol == htons(ETH_P_IP))
525*4882a593Smuzhiyun return ax25_ip_xmit(skb);
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun if (!netif_running(dev)) {
528*4882a593Smuzhiyun printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name);
529*4882a593Smuzhiyun return NETDEV_TX_BUSY;
530*4882a593Smuzhiyun }
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun if (netif_queue_stopped(dev)) {
533*4882a593Smuzhiyun /*
534*4882a593Smuzhiyun * May be we must check transmitter timeout here ?
535*4882a593Smuzhiyun * 14 Oct 1994 Dmitry Gorodchanin.
536*4882a593Smuzhiyun */
537*4882a593Smuzhiyun if (time_before(jiffies, dev_trans_start(dev) + 20 * HZ)) {
538*4882a593Smuzhiyun /* 20 sec timeout not reached */
539*4882a593Smuzhiyun return NETDEV_TX_BUSY;
540*4882a593Smuzhiyun }
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name,
543*4882a593Smuzhiyun (tty_chars_in_buffer(ax->tty) || ax->xleft) ?
544*4882a593Smuzhiyun "bad line quality" : "driver error");
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun ax->xleft = 0;
547*4882a593Smuzhiyun clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
548*4882a593Smuzhiyun netif_start_queue(dev);
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun /* We were not busy, so we are now... :-) */
552*4882a593Smuzhiyun netif_stop_queue(dev);
553*4882a593Smuzhiyun ax_encaps(dev, skb->data, skb->len);
554*4882a593Smuzhiyun kfree_skb(skb);
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun return NETDEV_TX_OK;
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun
ax_open_dev(struct net_device * dev)559*4882a593Smuzhiyun static int ax_open_dev(struct net_device *dev)
560*4882a593Smuzhiyun {
561*4882a593Smuzhiyun struct mkiss *ax = netdev_priv(dev);
562*4882a593Smuzhiyun
563*4882a593Smuzhiyun if (ax->tty == NULL)
564*4882a593Smuzhiyun return -ENODEV;
565*4882a593Smuzhiyun
566*4882a593Smuzhiyun return 0;
567*4882a593Smuzhiyun }
568*4882a593Smuzhiyun
569*4882a593Smuzhiyun /* Open the low-level part of the AX25 channel. Easy! */
ax_open(struct net_device * dev)570*4882a593Smuzhiyun static int ax_open(struct net_device *dev)
571*4882a593Smuzhiyun {
572*4882a593Smuzhiyun struct mkiss *ax = netdev_priv(dev);
573*4882a593Smuzhiyun unsigned long len;
574*4882a593Smuzhiyun
575*4882a593Smuzhiyun if (ax->tty == NULL)
576*4882a593Smuzhiyun return -ENODEV;
577*4882a593Smuzhiyun
578*4882a593Smuzhiyun /*
579*4882a593Smuzhiyun * Allocate the frame buffers:
580*4882a593Smuzhiyun *
581*4882a593Smuzhiyun * rbuff Receive buffer.
582*4882a593Smuzhiyun * xbuff Transmit buffer.
583*4882a593Smuzhiyun */
584*4882a593Smuzhiyun len = dev->mtu * 2;
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun /*
587*4882a593Smuzhiyun * allow for arrival of larger UDP packets, even if we say not to
588*4882a593Smuzhiyun * also fixes a bug in which SunOS sends 512-byte packets even with
589*4882a593Smuzhiyun * an MSS of 128
590*4882a593Smuzhiyun */
591*4882a593Smuzhiyun if (len < 576 * 2)
592*4882a593Smuzhiyun len = 576 * 2;
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun if ((ax->rbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
595*4882a593Smuzhiyun goto norbuff;
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun if ((ax->xbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
598*4882a593Smuzhiyun goto noxbuff;
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun ax->mtu = dev->mtu + 73;
601*4882a593Smuzhiyun ax->buffsize = len;
602*4882a593Smuzhiyun ax->rcount = 0;
603*4882a593Smuzhiyun ax->xleft = 0;
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun ax->flags &= (1 << AXF_INUSE); /* Clear ESCAPE & ERROR flags */
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun spin_lock_init(&ax->buflock);
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun return 0;
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun noxbuff:
612*4882a593Smuzhiyun kfree(ax->rbuff);
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun norbuff:
615*4882a593Smuzhiyun return -ENOMEM;
616*4882a593Smuzhiyun }
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun /* Close the low-level part of the AX25 channel. Easy! */
ax_close(struct net_device * dev)620*4882a593Smuzhiyun static int ax_close(struct net_device *dev)
621*4882a593Smuzhiyun {
622*4882a593Smuzhiyun struct mkiss *ax = netdev_priv(dev);
623*4882a593Smuzhiyun
624*4882a593Smuzhiyun if (ax->tty)
625*4882a593Smuzhiyun clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun netif_stop_queue(dev);
628*4882a593Smuzhiyun
629*4882a593Smuzhiyun return 0;
630*4882a593Smuzhiyun }
631*4882a593Smuzhiyun
632*4882a593Smuzhiyun static const struct net_device_ops ax_netdev_ops = {
633*4882a593Smuzhiyun .ndo_open = ax_open_dev,
634*4882a593Smuzhiyun .ndo_stop = ax_close,
635*4882a593Smuzhiyun .ndo_start_xmit = ax_xmit,
636*4882a593Smuzhiyun .ndo_set_mac_address = ax_set_mac_address,
637*4882a593Smuzhiyun };
638*4882a593Smuzhiyun
ax_setup(struct net_device * dev)639*4882a593Smuzhiyun static void ax_setup(struct net_device *dev)
640*4882a593Smuzhiyun {
641*4882a593Smuzhiyun /* Finish setting up the DEVICE info. */
642*4882a593Smuzhiyun dev->mtu = AX_MTU;
643*4882a593Smuzhiyun dev->hard_header_len = AX25_MAX_HEADER_LEN;
644*4882a593Smuzhiyun dev->addr_len = AX25_ADDR_LEN;
645*4882a593Smuzhiyun dev->type = ARPHRD_AX25;
646*4882a593Smuzhiyun dev->tx_queue_len = 10;
647*4882a593Smuzhiyun dev->header_ops = &ax25_header_ops;
648*4882a593Smuzhiyun dev->netdev_ops = &ax_netdev_ops;
649*4882a593Smuzhiyun
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
652*4882a593Smuzhiyun memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN);
653*4882a593Smuzhiyun
654*4882a593Smuzhiyun dev->flags = IFF_BROADCAST | IFF_MULTICAST;
655*4882a593Smuzhiyun }
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun /*
658*4882a593Smuzhiyun * We have a potential race on dereferencing tty->disc_data, because the tty
659*4882a593Smuzhiyun * layer provides no locking at all - thus one cpu could be running
660*4882a593Smuzhiyun * sixpack_receive_buf while another calls sixpack_close, which zeroes
661*4882a593Smuzhiyun * tty->disc_data and frees the memory that sixpack_receive_buf is using. The
662*4882a593Smuzhiyun * best way to fix this is to use a rwlock in the tty struct, but for now we
663*4882a593Smuzhiyun * use a single global rwlock for all ttys in ppp line discipline.
664*4882a593Smuzhiyun */
665*4882a593Smuzhiyun static DEFINE_RWLOCK(disc_data_lock);
666*4882a593Smuzhiyun
mkiss_get(struct tty_struct * tty)667*4882a593Smuzhiyun static struct mkiss *mkiss_get(struct tty_struct *tty)
668*4882a593Smuzhiyun {
669*4882a593Smuzhiyun struct mkiss *ax;
670*4882a593Smuzhiyun
671*4882a593Smuzhiyun read_lock(&disc_data_lock);
672*4882a593Smuzhiyun ax = tty->disc_data;
673*4882a593Smuzhiyun if (ax)
674*4882a593Smuzhiyun refcount_inc(&ax->refcnt);
675*4882a593Smuzhiyun read_unlock(&disc_data_lock);
676*4882a593Smuzhiyun
677*4882a593Smuzhiyun return ax;
678*4882a593Smuzhiyun }
679*4882a593Smuzhiyun
mkiss_put(struct mkiss * ax)680*4882a593Smuzhiyun static void mkiss_put(struct mkiss *ax)
681*4882a593Smuzhiyun {
682*4882a593Smuzhiyun if (refcount_dec_and_test(&ax->refcnt))
683*4882a593Smuzhiyun complete(&ax->dead);
684*4882a593Smuzhiyun }
685*4882a593Smuzhiyun
686*4882a593Smuzhiyun static int crc_force = 0; /* Can be overridden with insmod */
687*4882a593Smuzhiyun
mkiss_open(struct tty_struct * tty)688*4882a593Smuzhiyun static int mkiss_open(struct tty_struct *tty)
689*4882a593Smuzhiyun {
690*4882a593Smuzhiyun struct net_device *dev;
691*4882a593Smuzhiyun struct mkiss *ax;
692*4882a593Smuzhiyun int err;
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun if (!capable(CAP_NET_ADMIN))
695*4882a593Smuzhiyun return -EPERM;
696*4882a593Smuzhiyun if (tty->ops->write == NULL)
697*4882a593Smuzhiyun return -EOPNOTSUPP;
698*4882a593Smuzhiyun
699*4882a593Smuzhiyun dev = alloc_netdev(sizeof(struct mkiss), "ax%d", NET_NAME_UNKNOWN,
700*4882a593Smuzhiyun ax_setup);
701*4882a593Smuzhiyun if (!dev) {
702*4882a593Smuzhiyun err = -ENOMEM;
703*4882a593Smuzhiyun goto out;
704*4882a593Smuzhiyun }
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun ax = netdev_priv(dev);
707*4882a593Smuzhiyun ax->dev = dev;
708*4882a593Smuzhiyun
709*4882a593Smuzhiyun spin_lock_init(&ax->buflock);
710*4882a593Smuzhiyun refcount_set(&ax->refcnt, 1);
711*4882a593Smuzhiyun init_completion(&ax->dead);
712*4882a593Smuzhiyun
713*4882a593Smuzhiyun ax->tty = tty;
714*4882a593Smuzhiyun tty->disc_data = ax;
715*4882a593Smuzhiyun tty->receive_room = 65535;
716*4882a593Smuzhiyun
717*4882a593Smuzhiyun tty_driver_flush_buffer(tty);
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun /* Restore default settings */
720*4882a593Smuzhiyun dev->type = ARPHRD_AX25;
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun /* Perform the low-level AX25 initialization. */
723*4882a593Smuzhiyun err = ax_open(ax->dev);
724*4882a593Smuzhiyun if (err)
725*4882a593Smuzhiyun goto out_free_netdev;
726*4882a593Smuzhiyun
727*4882a593Smuzhiyun err = register_netdev(dev);
728*4882a593Smuzhiyun if (err)
729*4882a593Smuzhiyun goto out_free_buffers;
730*4882a593Smuzhiyun
731*4882a593Smuzhiyun /* after register_netdev() - because else printk smashes the kernel */
732*4882a593Smuzhiyun switch (crc_force) {
733*4882a593Smuzhiyun case 3:
734*4882a593Smuzhiyun ax->crcmode = CRC_MODE_SMACK;
735*4882a593Smuzhiyun printk(KERN_INFO "mkiss: %s: crc mode smack forced.\n",
736*4882a593Smuzhiyun ax->dev->name);
737*4882a593Smuzhiyun break;
738*4882a593Smuzhiyun case 2:
739*4882a593Smuzhiyun ax->crcmode = CRC_MODE_FLEX;
740*4882a593Smuzhiyun printk(KERN_INFO "mkiss: %s: crc mode flexnet forced.\n",
741*4882a593Smuzhiyun ax->dev->name);
742*4882a593Smuzhiyun break;
743*4882a593Smuzhiyun case 1:
744*4882a593Smuzhiyun ax->crcmode = CRC_MODE_NONE;
745*4882a593Smuzhiyun printk(KERN_INFO "mkiss: %s: crc mode disabled.\n",
746*4882a593Smuzhiyun ax->dev->name);
747*4882a593Smuzhiyun break;
748*4882a593Smuzhiyun case 0:
749*4882a593Smuzhiyun default:
750*4882a593Smuzhiyun crc_force = 0;
751*4882a593Smuzhiyun printk(KERN_INFO "mkiss: %s: crc mode is auto.\n",
752*4882a593Smuzhiyun ax->dev->name);
753*4882a593Smuzhiyun ax->crcmode = CRC_MODE_SMACK_TEST;
754*4882a593Smuzhiyun }
755*4882a593Smuzhiyun ax->crcauto = (crc_force ? 0 : 1);
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun netif_start_queue(dev);
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun /* Done. We have linked the TTY line to a channel. */
760*4882a593Smuzhiyun return 0;
761*4882a593Smuzhiyun
762*4882a593Smuzhiyun out_free_buffers:
763*4882a593Smuzhiyun kfree(ax->rbuff);
764*4882a593Smuzhiyun kfree(ax->xbuff);
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun out_free_netdev:
767*4882a593Smuzhiyun free_netdev(dev);
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun out:
770*4882a593Smuzhiyun return err;
771*4882a593Smuzhiyun }
772*4882a593Smuzhiyun
mkiss_close(struct tty_struct * tty)773*4882a593Smuzhiyun static void mkiss_close(struct tty_struct *tty)
774*4882a593Smuzhiyun {
775*4882a593Smuzhiyun struct mkiss *ax;
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun write_lock_irq(&disc_data_lock);
778*4882a593Smuzhiyun ax = tty->disc_data;
779*4882a593Smuzhiyun tty->disc_data = NULL;
780*4882a593Smuzhiyun write_unlock_irq(&disc_data_lock);
781*4882a593Smuzhiyun
782*4882a593Smuzhiyun if (!ax)
783*4882a593Smuzhiyun return;
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun /*
786*4882a593Smuzhiyun * We have now ensured that nobody can start using ap from now on, but
787*4882a593Smuzhiyun * we have to wait for all existing users to finish.
788*4882a593Smuzhiyun */
789*4882a593Smuzhiyun if (!refcount_dec_and_test(&ax->refcnt))
790*4882a593Smuzhiyun wait_for_completion(&ax->dead);
791*4882a593Smuzhiyun /*
792*4882a593Smuzhiyun * Halt the transmit queue so that a new transmit cannot scribble
793*4882a593Smuzhiyun * on our buffers
794*4882a593Smuzhiyun */
795*4882a593Smuzhiyun netif_stop_queue(ax->dev);
796*4882a593Smuzhiyun
797*4882a593Smuzhiyun unregister_netdev(ax->dev);
798*4882a593Smuzhiyun
799*4882a593Smuzhiyun /* Free all AX25 frame buffers after unreg. */
800*4882a593Smuzhiyun kfree(ax->rbuff);
801*4882a593Smuzhiyun kfree(ax->xbuff);
802*4882a593Smuzhiyun
803*4882a593Smuzhiyun ax->tty = NULL;
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun free_netdev(ax->dev);
806*4882a593Smuzhiyun }
807*4882a593Smuzhiyun
808*4882a593Smuzhiyun /* Perform I/O control on an active ax25 channel. */
mkiss_ioctl(struct tty_struct * tty,struct file * file,unsigned int cmd,unsigned long arg)809*4882a593Smuzhiyun static int mkiss_ioctl(struct tty_struct *tty, struct file *file,
810*4882a593Smuzhiyun unsigned int cmd, unsigned long arg)
811*4882a593Smuzhiyun {
812*4882a593Smuzhiyun struct mkiss *ax = mkiss_get(tty);
813*4882a593Smuzhiyun struct net_device *dev;
814*4882a593Smuzhiyun unsigned int tmp, err;
815*4882a593Smuzhiyun
816*4882a593Smuzhiyun /* First make sure we're connected. */
817*4882a593Smuzhiyun if (ax == NULL)
818*4882a593Smuzhiyun return -ENXIO;
819*4882a593Smuzhiyun dev = ax->dev;
820*4882a593Smuzhiyun
821*4882a593Smuzhiyun switch (cmd) {
822*4882a593Smuzhiyun case SIOCGIFNAME:
823*4882a593Smuzhiyun err = copy_to_user((void __user *) arg, ax->dev->name,
824*4882a593Smuzhiyun strlen(ax->dev->name) + 1) ? -EFAULT : 0;
825*4882a593Smuzhiyun break;
826*4882a593Smuzhiyun
827*4882a593Smuzhiyun case SIOCGIFENCAP:
828*4882a593Smuzhiyun err = put_user(4, (int __user *) arg);
829*4882a593Smuzhiyun break;
830*4882a593Smuzhiyun
831*4882a593Smuzhiyun case SIOCSIFENCAP:
832*4882a593Smuzhiyun if (get_user(tmp, (int __user *) arg)) {
833*4882a593Smuzhiyun err = -EFAULT;
834*4882a593Smuzhiyun break;
835*4882a593Smuzhiyun }
836*4882a593Smuzhiyun
837*4882a593Smuzhiyun ax->mode = tmp;
838*4882a593Smuzhiyun dev->addr_len = AX25_ADDR_LEN;
839*4882a593Smuzhiyun dev->hard_header_len = AX25_KISS_HEADER_LEN +
840*4882a593Smuzhiyun AX25_MAX_HEADER_LEN + 3;
841*4882a593Smuzhiyun dev->type = ARPHRD_AX25;
842*4882a593Smuzhiyun
843*4882a593Smuzhiyun err = 0;
844*4882a593Smuzhiyun break;
845*4882a593Smuzhiyun
846*4882a593Smuzhiyun case SIOCSIFHWADDR: {
847*4882a593Smuzhiyun char addr[AX25_ADDR_LEN];
848*4882a593Smuzhiyun
849*4882a593Smuzhiyun if (copy_from_user(&addr,
850*4882a593Smuzhiyun (void __user *) arg, AX25_ADDR_LEN)) {
851*4882a593Smuzhiyun err = -EFAULT;
852*4882a593Smuzhiyun break;
853*4882a593Smuzhiyun }
854*4882a593Smuzhiyun
855*4882a593Smuzhiyun netif_tx_lock_bh(dev);
856*4882a593Smuzhiyun memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
857*4882a593Smuzhiyun netif_tx_unlock_bh(dev);
858*4882a593Smuzhiyun
859*4882a593Smuzhiyun err = 0;
860*4882a593Smuzhiyun break;
861*4882a593Smuzhiyun }
862*4882a593Smuzhiyun default:
863*4882a593Smuzhiyun err = -ENOIOCTLCMD;
864*4882a593Smuzhiyun }
865*4882a593Smuzhiyun
866*4882a593Smuzhiyun mkiss_put(ax);
867*4882a593Smuzhiyun
868*4882a593Smuzhiyun return err;
869*4882a593Smuzhiyun }
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun /*
872*4882a593Smuzhiyun * Handle the 'receiver data ready' interrupt.
873*4882a593Smuzhiyun * This function is called by the 'tty_io' module in the kernel when
874*4882a593Smuzhiyun * a block of data has been received, which can now be decapsulated
875*4882a593Smuzhiyun * and sent on to the AX.25 layer for further processing.
876*4882a593Smuzhiyun */
mkiss_receive_buf(struct tty_struct * tty,const unsigned char * cp,char * fp,int count)877*4882a593Smuzhiyun static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
878*4882a593Smuzhiyun char *fp, int count)
879*4882a593Smuzhiyun {
880*4882a593Smuzhiyun struct mkiss *ax = mkiss_get(tty);
881*4882a593Smuzhiyun
882*4882a593Smuzhiyun if (!ax)
883*4882a593Smuzhiyun return;
884*4882a593Smuzhiyun
885*4882a593Smuzhiyun /*
886*4882a593Smuzhiyun * Argh! mtu change time! - costs us the packet part received
887*4882a593Smuzhiyun * at the change
888*4882a593Smuzhiyun */
889*4882a593Smuzhiyun if (ax->mtu != ax->dev->mtu + 73)
890*4882a593Smuzhiyun ax_changedmtu(ax);
891*4882a593Smuzhiyun
892*4882a593Smuzhiyun /* Read the characters out of the buffer */
893*4882a593Smuzhiyun while (count--) {
894*4882a593Smuzhiyun if (fp != NULL && *fp++) {
895*4882a593Smuzhiyun if (!test_and_set_bit(AXF_ERROR, &ax->flags))
896*4882a593Smuzhiyun ax->dev->stats.rx_errors++;
897*4882a593Smuzhiyun cp++;
898*4882a593Smuzhiyun continue;
899*4882a593Smuzhiyun }
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun kiss_unesc(ax, *cp++);
902*4882a593Smuzhiyun }
903*4882a593Smuzhiyun
904*4882a593Smuzhiyun mkiss_put(ax);
905*4882a593Smuzhiyun tty_unthrottle(tty);
906*4882a593Smuzhiyun }
907*4882a593Smuzhiyun
908*4882a593Smuzhiyun /*
909*4882a593Smuzhiyun * Called by the driver when there's room for more data. If we have
910*4882a593Smuzhiyun * more packets to send, we send them here.
911*4882a593Smuzhiyun */
mkiss_write_wakeup(struct tty_struct * tty)912*4882a593Smuzhiyun static void mkiss_write_wakeup(struct tty_struct *tty)
913*4882a593Smuzhiyun {
914*4882a593Smuzhiyun struct mkiss *ax = mkiss_get(tty);
915*4882a593Smuzhiyun int actual;
916*4882a593Smuzhiyun
917*4882a593Smuzhiyun if (!ax)
918*4882a593Smuzhiyun return;
919*4882a593Smuzhiyun
920*4882a593Smuzhiyun if (ax->xleft <= 0) {
921*4882a593Smuzhiyun /* Now serial buffer is almost free & we can start
922*4882a593Smuzhiyun * transmission of another packet
923*4882a593Smuzhiyun */
924*4882a593Smuzhiyun clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
925*4882a593Smuzhiyun
926*4882a593Smuzhiyun netif_wake_queue(ax->dev);
927*4882a593Smuzhiyun goto out;
928*4882a593Smuzhiyun }
929*4882a593Smuzhiyun
930*4882a593Smuzhiyun actual = tty->ops->write(tty, ax->xhead, ax->xleft);
931*4882a593Smuzhiyun ax->xleft -= actual;
932*4882a593Smuzhiyun ax->xhead += actual;
933*4882a593Smuzhiyun
934*4882a593Smuzhiyun out:
935*4882a593Smuzhiyun mkiss_put(ax);
936*4882a593Smuzhiyun }
937*4882a593Smuzhiyun
938*4882a593Smuzhiyun static struct tty_ldisc_ops ax_ldisc = {
939*4882a593Smuzhiyun .owner = THIS_MODULE,
940*4882a593Smuzhiyun .magic = TTY_LDISC_MAGIC,
941*4882a593Smuzhiyun .name = "mkiss",
942*4882a593Smuzhiyun .open = mkiss_open,
943*4882a593Smuzhiyun .close = mkiss_close,
944*4882a593Smuzhiyun .ioctl = mkiss_ioctl,
945*4882a593Smuzhiyun .receive_buf = mkiss_receive_buf,
946*4882a593Smuzhiyun .write_wakeup = mkiss_write_wakeup
947*4882a593Smuzhiyun };
948*4882a593Smuzhiyun
949*4882a593Smuzhiyun static const char banner[] __initconst = KERN_INFO \
950*4882a593Smuzhiyun "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
951*4882a593Smuzhiyun static const char msg_regfail[] __initconst = KERN_ERR \
952*4882a593Smuzhiyun "mkiss: can't register line discipline (err = %d)\n";
953*4882a593Smuzhiyun
mkiss_init_driver(void)954*4882a593Smuzhiyun static int __init mkiss_init_driver(void)
955*4882a593Smuzhiyun {
956*4882a593Smuzhiyun int status;
957*4882a593Smuzhiyun
958*4882a593Smuzhiyun printk(banner);
959*4882a593Smuzhiyun
960*4882a593Smuzhiyun status = tty_register_ldisc(N_AX25, &ax_ldisc);
961*4882a593Smuzhiyun if (status != 0)
962*4882a593Smuzhiyun printk(msg_regfail, status);
963*4882a593Smuzhiyun
964*4882a593Smuzhiyun return status;
965*4882a593Smuzhiyun }
966*4882a593Smuzhiyun
967*4882a593Smuzhiyun static const char msg_unregfail[] = KERN_ERR \
968*4882a593Smuzhiyun "mkiss: can't unregister line discipline (err = %d)\n";
969*4882a593Smuzhiyun
mkiss_exit_driver(void)970*4882a593Smuzhiyun static void __exit mkiss_exit_driver(void)
971*4882a593Smuzhiyun {
972*4882a593Smuzhiyun int ret;
973*4882a593Smuzhiyun
974*4882a593Smuzhiyun if ((ret = tty_unregister_ldisc(N_AX25)))
975*4882a593Smuzhiyun printk(msg_unregfail, ret);
976*4882a593Smuzhiyun }
977*4882a593Smuzhiyun
978*4882a593Smuzhiyun MODULE_AUTHOR("Ralf Baechle DL5RB <ralf@linux-mips.org>");
979*4882a593Smuzhiyun MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
980*4882a593Smuzhiyun module_param(crc_force, int, 0);
981*4882a593Smuzhiyun MODULE_PARM_DESC(crc_force, "crc [0 = auto | 1 = none | 2 = flexnet | 3 = smack]");
982*4882a593Smuzhiyun MODULE_LICENSE("GPL");
983*4882a593Smuzhiyun MODULE_ALIAS_LDISC(N_AX25);
984*4882a593Smuzhiyun
985*4882a593Smuzhiyun module_init(mkiss_init_driver);
986*4882a593Smuzhiyun module_exit(mkiss_exit_driver);
987