aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2005-08-24 13:06:36 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-08-27 04:35:31 -0400
commit815f62bf742718458ba822a7e1f51f285eb997f2 (patch)
tree01e1dc8b4447bcceca8106182e4cf1327ee9a3ad
parent75a95178dafb5c8d69b4abe45ea746a9cea23142 (diff)
[PATCH] SMP rewrite of mkiss
Rewrite the mkiss driver to make it SMP-proof following the example of 6pack.c. Signed-off-by: Ralf Baechle DL5RB <ralf@linux-mips.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r--drivers/net/hamradio/Kconfig2
-rw-r--r--drivers/net/hamradio/mkiss.c1083
2 files changed, 523 insertions, 562 deletions
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index 0cd54306e636..de087cd609d9 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -1,6 +1,6 @@
1config MKISS 1config MKISS
2 tristate "Serial port KISS driver" 2 tristate "Serial port KISS driver"
3 depends on AX25 && BROKEN_ON_SMP 3 depends on AX25
4 ---help--- 4 ---help---
5 KISS is a protocol used for the exchange of data between a computer 5 KISS is a protocol used for the exchange of data between a computer
6 and a Terminal Node Controller (a small embedded system commonly 6 and a Terminal Node Controller (a small embedded system commonly
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index e94952e799fe..63b1a2b86acb 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -1,30 +1,19 @@
1/* 1/*
2 * MKISS Driver 2 * This program is free software; you can distribute it and/or modify it
3 * under the terms of the GNU General Public License (Version 2) as
4 * published by the Free Software Foundation.
3 * 5 *
4 * This module: 6 * This program is distributed in the hope it will be useful, but WITHOUT
5 * This module is free software; you can redistribute it and/or 7 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6 * modify it under the terms of the GNU General Public License 8 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7 * as published by the Free Software Foundation; either version 9 * for more details.
8 * 2 of the License, or (at your option) any later version.
9 * 10 *
10 * This module implements the AX.25 protocol for kernel-based 11 * You should have received a copy of the GNU General Public License along
11 * devices like TTYs. It interfaces between a raw TTY, and the 12 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * kernel's AX.25 protocol layers, just like slip.c. 13 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
13 * AX.25 needs to be separated from slip.c while slip.c is no
14 * longer a static kernel device since it is a module.
15 * This method clears the way to implement other kiss protocols
16 * like mkiss smack g8bpq ..... so far only mkiss is implemented.
17 * 14 *
18 * Hans Alblas <hans@esrac.ele.tue.nl> 15 * Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl>
19 * 16 * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org>
20 * History
21 * Jonathan (G4KLX) Fixed to match Linux networking changes - 2.1.15.
22 * Matthias (DG2FEF) Added support for FlexNet CRC (on special request)
23 * Fixed bug in ax25_close(): dev_lock_wait() was
24 * called twice, causing a deadlock.
25 * Jeroen (PE1RXQ) Removed old MKISS_MAGIC stuff and calls to
26 * MOD_*_USE_COUNT
27 * Remove cli() and fix rtnl lock usage.
28 */ 17 */
29 18
30#include <linux/config.h> 19#include <linux/config.h>
@@ -50,174 +39,296 @@
50 39
51#include <net/ax25.h> 40#include <net/ax25.h>
52 41
53#include "mkiss.h"
54
55#ifdef CONFIG_INET 42#ifdef CONFIG_INET
56#include <linux/ip.h> 43#include <linux/ip.h>
57#include <linux/tcp.h> 44#include <linux/tcp.h>
58#endif 45#endif
59 46
60static char banner[] __initdata = KERN_INFO "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n"; 47#define AX_MTU 236
61 48
62typedef struct ax25_ctrl { 49/* SLIP/KISS protocol characters. */
63 struct ax_disp ctrl; /* */ 50#define END 0300 /* indicates end of frame */
64 struct net_device dev; /* the device */ 51#define ESC 0333 /* indicates byte stuffing */
65} ax25_ctrl_t; 52#define ESC_END 0334 /* ESC ESC_END means END 'data' */
66 53#define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
67static ax25_ctrl_t **ax25_ctrls; 54
68 55struct mkiss {
69int ax25_maxdev = AX25_MAXDEV; /* Can be overridden with insmod! */ 56 struct tty_struct *tty; /* ptr to TTY structure */
70 57 struct net_device *dev; /* easy for intr handling */
71static struct tty_ldisc ax_ldisc; 58
72 59 /* These are pointers to the malloc()ed frame buffers. */
73static int ax25_init(struct net_device *); 60 spinlock_t buflock;/* lock for rbuf and xbuf */
74static int kiss_esc(unsigned char *, unsigned char *, int); 61 unsigned char *rbuff; /* receiver buffer */
75static int kiss_esc_crc(unsigned char *, unsigned char *, unsigned short, int); 62 int rcount; /* received chars counter */
76static void kiss_unesc(struct ax_disp *, unsigned char); 63 unsigned char *xbuff; /* transmitter buffer */
64 unsigned char *xhead; /* pointer to next byte to XMIT */
65 int xleft; /* bytes left in XMIT queue */
66
67 struct net_device_stats stats;
68
69 /* Detailed SLIP statistics. */
70 int mtu; /* Our mtu (to spot changes!) */
71 int buffsize; /* Max buffers sizes */
72
73 unsigned long flags; /* Flag values/ mode etc */
74 /* long req'd: used by set_bit --RR */
75#define AXF_INUSE 0 /* Channel in use */
76#define AXF_ESCAPE 1 /* ESC received */
77#define AXF_ERROR 2 /* Parity, etc. error */
78#define AXF_KEEPTEST 3 /* Keepalive test flag */
79#define AXF_OUTWAIT 4 /* is outpacket was flag */
80
81 int mode;
82 int crcmode; /* MW: for FlexNet, SMACK etc. */
83#define CRC_MODE_NONE 0
84#define CRC_MODE_FLEX 1
85#define CRC_MODE_SMACK 2
86
87 atomic_t refcnt;
88 struct semaphore dead_sem;
89};
77 90
78/*---------------------------------------------------------------------------*/ 91/*---------------------------------------------------------------------------*/
79 92
80static const unsigned short Crc_flex_table[] = { 93static const unsigned short crc_flex_table[] = {
81 0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38, 94 0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38,
82 0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770, 95 0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770,
83 0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9, 96 0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9,
84 0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1, 97 0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1,
85 0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a, 98 0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a,
86 0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672, 99 0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672,
87 0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb, 100 0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb,
88 0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3, 101 0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3,
89 0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c, 102 0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c,
90 0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574, 103 0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574,
91 0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd, 104 0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd,
92 0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5, 105 0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5,
93 0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e, 106 0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e,
94 0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476, 107 0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476,
95 0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf, 108 0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf,
96 0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7, 109 0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7,
97 0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30, 110 0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30,
98 0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378, 111 0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378,
99 0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1, 112 0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1,
100 0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9, 113 0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9,
101 0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32, 114 0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32,
102 0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a, 115 0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a,
103 0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3, 116 0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3,
104 0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb, 117 0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb,
105 0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34, 118 0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34,
106 0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c, 119 0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c,
107 0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5, 120 0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5,
108 0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd, 121 0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd,
109 0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36, 122 0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36,
110 0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e, 123 0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e,
111 0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7, 124 0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7,
112 0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff 125 0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff
113}; 126};
114 127
115/*---------------------------------------------------------------------------*/
116
117static unsigned short calc_crc_flex(unsigned char *cp, int size) 128static unsigned short calc_crc_flex(unsigned char *cp, int size)
118{ 129{
119 unsigned short crc = 0xffff; 130 unsigned short crc = 0xffff;
120
121 while (size--)
122 crc = (crc << 8) ^ Crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];
123 131
124 return crc; 132 while (size--)
125} 133 crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];
126 134
127/*---------------------------------------------------------------------------*/ 135 return crc;
136}
128 137
129static int check_crc_flex(unsigned char *cp, int size) 138static int check_crc_flex(unsigned char *cp, int size)
130{ 139{
131 unsigned short crc = 0xffff; 140 unsigned short crc = 0xffff;
132 141
133 if (size < 3) 142 if (size < 3)
134 return -1; 143 return -1;
135 144
136 while (size--) 145 while (size--)
137 crc = (crc << 8) ^ Crc_flex_table[((crc >> 8) ^ *cp++) & 0xff]; 146 crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];
138 147
139 if ((crc & 0xffff) != 0x7070) 148 if ((crc & 0xffff) != 0x7070)
140 return -1; 149 return -1;
141 150
142 return 0; 151 return 0;
143} 152}
144 153
145/*---------------------------------------------------------------------------*/ 154/*
155 * Standard encapsulation
156 */
146 157
147/* Find a free channel, and link in this `tty' line. */ 158static int kiss_esc(unsigned char *s, unsigned char *d, int len)
148static inline struct ax_disp *ax_alloc(void)
149{ 159{
150 ax25_ctrl_t *axp=NULL; 160 unsigned char *ptr = d;
151 int i; 161 unsigned char c;
152 162
153 for (i = 0; i < ax25_maxdev; i++) { 163 /*
154 axp = ax25_ctrls[i]; 164 * Send an initial END character to flush out any data that may have
165 * accumulated in the receiver due to line noise.
166 */
155 167
156 /* Not allocated ? */ 168 *ptr++ = END;
157 if (axp == NULL)
158 break;
159 169
160 /* Not in use ? */ 170 while (len-- > 0) {
161 if (!test_and_set_bit(AXF_INUSE, &axp->ctrl.flags)) 171 switch (c = *s++) {
172 case END:
173 *ptr++ = ESC;
174 *ptr++ = ESC_END;
162 break; 175 break;
176 case ESC:
177 *ptr++ = ESC;
178 *ptr++ = ESC_ESC;
179 break;
180 default:
181 *ptr++ = c;
182 break;
183 }
163 } 184 }
164 185
165 /* Sorry, too many, all slots in use */ 186 *ptr++ = END;
166 if (i >= ax25_maxdev) 187
167 return NULL; 188 return ptr - d;
189}
190
191/*
192 * MW:
193 * OK its ugly, but tell me a better solution without copying the
194 * packet to a temporary buffer :-)
195 */
196static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc,
197 int len)
198{
199 unsigned char *ptr = d;
200 unsigned char c=0;
201
202 *ptr++ = END;
203 while (len > 0) {
204 if (len > 2)
205 c = *s++;
206 else if (len > 1)
207 c = crc >> 8;
208 else if (len > 0)
209 c = crc & 0xff;
210
211 len--;
168 212
169 /* If no channels are available, allocate one */ 213 switch (c) {
170 if (axp == NULL && (ax25_ctrls[i] = kmalloc(sizeof(ax25_ctrl_t), GFP_KERNEL)) != NULL) { 214 case END:
171 axp = ax25_ctrls[i]; 215 *ptr++ = ESC;
216 *ptr++ = ESC_END;
217 break;
218 case ESC:
219 *ptr++ = ESC;
220 *ptr++ = ESC_ESC;
221 break;
222 default:
223 *ptr++ = c;
224 break;
225 }
172 } 226 }
173 memset(axp, 0, sizeof(ax25_ctrl_t)); 227 *ptr++ = END;
174 228
175 /* Initialize channel control data */ 229 return ptr - d;
176 set_bit(AXF_INUSE, &axp->ctrl.flags); 230}
177 sprintf(axp->dev.name, "ax%d", i++); 231
178 axp->ctrl.tty = NULL; 232/* Send one completely decapsulated AX.25 packet to the AX.25 layer. */
179 axp->dev.base_addr = i; 233static void ax_bump(struct mkiss *ax)
180 axp->dev.priv = (void *)&axp->ctrl; 234{
181 axp->dev.next = NULL; 235 struct sk_buff *skb;
182 axp->dev.init = ax25_init; 236 int count;
183 237
184 if (axp != NULL) { 238 spin_lock_bh(&ax->buflock);
185 /* 239 if (ax->rbuff[0] > 0x0f) {
186 * register device so that it can be ifconfig'ed 240 if (ax->rbuff[0] & 0x20) {
187 * ax25_init() will be called as a side-effect 241 ax->crcmode = CRC_MODE_FLEX;
188 * SIDE-EFFECT WARNING: ax25_init() CLEARS axp->ctrl ! 242 if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
189 */ 243 ax->stats.rx_errors++;
190 if (register_netdev(&axp->dev) == 0) { 244 return;
191 /* (Re-)Set the INUSE bit. Very Important! */ 245 }
192 set_bit(AXF_INUSE, &axp->ctrl.flags); 246 ax->rcount -= 2;
193 axp->ctrl.dev = &axp->dev; 247 /* dl9sau bugfix: the trailling two bytes flexnet crc
194 axp->dev.priv = (void *) &axp->ctrl; 248 * will not be passed to the kernel. thus we have
195 249 * to correct the kissparm signature, because it
196 return &axp->ctrl; 250 * indicates a crc but there's none
197 } else { 251 */
198 clear_bit(AXF_INUSE,&axp->ctrl.flags); 252 *ax->rbuff &= ~0x20;
199 printk(KERN_ERR "mkiss: ax_alloc() - register_netdev() failure.\n");
200 } 253 }
254 }
255 spin_unlock_bh(&ax->buflock);
256
257 count = ax->rcount;
258
259 if ((skb = dev_alloc_skb(count)) == NULL) {
260 printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n",
261 ax->dev->name);
262 ax->stats.rx_dropped++;
263 return;
201 } 264 }
202 265
203 return NULL; 266 spin_lock_bh(&ax->buflock);
267 memcpy(skb_put(skb,count), ax->rbuff, count);
268 spin_unlock_bh(&ax->buflock);
269 skb->protocol = ax25_type_trans(skb, ax->dev);
270 netif_rx(skb);
271 ax->dev->last_rx = jiffies;
272 ax->stats.rx_packets++;
273 ax->stats.rx_bytes += count;
204} 274}
205 275
206/* Free an AX25 channel. */ 276static void kiss_unesc(struct mkiss *ax, unsigned char s)
207static inline void ax_free(struct ax_disp *ax)
208{ 277{
209 /* Free all AX25 frame buffers. */ 278 switch (s) {
210 if (ax->rbuff) 279 case END:
211 kfree(ax->rbuff); 280 /* drop keeptest bit = VSV */
212 ax->rbuff = NULL; 281 if (test_bit(AXF_KEEPTEST, &ax->flags))
213 if (ax->xbuff) 282 clear_bit(AXF_KEEPTEST, &ax->flags);
214 kfree(ax->xbuff); 283
215 ax->xbuff = NULL; 284 if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2))
216 if (!test_and_clear_bit(AXF_INUSE, &ax->flags)) 285 ax_bump(ax);
217 printk(KERN_ERR "mkiss: %s: ax_free for already free unit.\n", ax->dev->name); 286
287 clear_bit(AXF_ESCAPE, &ax->flags);
288 ax->rcount = 0;
289 return;
290
291 case ESC:
292 set_bit(AXF_ESCAPE, &ax->flags);
293 return;
294 case ESC_ESC:
295 if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
296 s = ESC;
297 break;
298 case ESC_END:
299 if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
300 s = END;
301 break;
302 }
303
304 spin_lock_bh(&ax->buflock);
305 if (!test_bit(AXF_ERROR, &ax->flags)) {
306 if (ax->rcount < ax->buffsize) {
307 ax->rbuff[ax->rcount++] = s;
308 spin_unlock_bh(&ax->buflock);
309 return;
310 }
311
312 ax->stats.rx_over_errors++;
313 set_bit(AXF_ERROR, &ax->flags);
314 }
315 spin_unlock_bh(&ax->buflock);
316}
317
318static int ax_set_mac_address(struct net_device *dev, void *addr)
319{
320 struct sockaddr_ax25 *sa = addr;
321
322 spin_lock_irq(&dev->xmit_lock);
323 memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
324 spin_unlock_irq(&dev->xmit_lock);
325
326 return 0;
218} 327}
219 328
220static void ax_changedmtu(struct ax_disp *ax) 329/*---------------------------------------------------------------------------*/
330
331static void ax_changedmtu(struct mkiss *ax)
221{ 332{
222 struct net_device *dev = ax->dev; 333 struct net_device *dev = ax->dev;
223 unsigned char *xbuff, *rbuff, *oxbuff, *orbuff; 334 unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
@@ -237,7 +348,8 @@ static void ax_changedmtu(struct ax_disp *ax)
237 rbuff = kmalloc(len + 4, GFP_ATOMIC); 348 rbuff = kmalloc(len + 4, GFP_ATOMIC);
238 349
239 if (xbuff == NULL || rbuff == NULL) { 350 if (xbuff == NULL || rbuff == NULL) {
240 printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, MTU change cancelled.\n", 351 printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, "
352 "MTU change cancelled.\n",
241 ax->dev->name); 353 ax->dev->name);
242 dev->mtu = ax->mtu; 354 dev->mtu = ax->mtu;
243 if (xbuff != NULL) 355 if (xbuff != NULL)
@@ -259,7 +371,7 @@ static void ax_changedmtu(struct ax_disp *ax)
259 memcpy(ax->xbuff, ax->xhead, ax->xleft); 371 memcpy(ax->xbuff, ax->xhead, ax->xleft);
260 } else { 372 } else {
261 ax->xleft = 0; 373 ax->xleft = 0;
262 ax->tx_dropped++; 374 ax->stats.tx_dropped++;
263 } 375 }
264 } 376 }
265 377
@@ -270,7 +382,7 @@ static void ax_changedmtu(struct ax_disp *ax)
270 memcpy(ax->rbuff, orbuff, ax->rcount); 382 memcpy(ax->rbuff, orbuff, ax->rcount);
271 } else { 383 } else {
272 ax->rcount = 0; 384 ax->rcount = 0;
273 ax->rx_over_errors++; 385 ax->stats.rx_over_errors++;
274 set_bit(AXF_ERROR, &ax->flags); 386 set_bit(AXF_ERROR, &ax->flags);
275 } 387 }
276 } 388 }
@@ -280,72 +392,14 @@ static void ax_changedmtu(struct ax_disp *ax)
280 392
281 spin_unlock_bh(&ax->buflock); 393 spin_unlock_bh(&ax->buflock);
282 394
283 if (oxbuff != NULL) 395 kfree(oxbuff);
284 kfree(oxbuff); 396 kfree(orbuff);
285 if (orbuff != NULL)
286 kfree(orbuff);
287}
288
289
290/* Set the "sending" flag. This must be atomic. */
291static inline void ax_lock(struct ax_disp *ax)
292{
293 netif_stop_queue(ax->dev);
294}
295
296
297/* Clear the "sending" flag. This must be atomic. */
298static inline void ax_unlock(struct ax_disp *ax)
299{
300 netif_start_queue(ax->dev);
301}
302
303/* Send one completely decapsulated AX.25 packet to the AX.25 layer. */
304static void ax_bump(struct ax_disp *ax)
305{
306 struct sk_buff *skb;
307 int count;
308
309 spin_lock_bh(&ax->buflock);
310 if (ax->rbuff[0] > 0x0f) {
311 if (ax->rbuff[0] & 0x20) {
312 ax->crcmode = CRC_MODE_FLEX;
313 if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
314 ax->rx_errors++;
315 return;
316 }
317 ax->rcount -= 2;
318 /* dl9sau bugfix: the trailling two bytes flexnet crc
319 * will not be passed to the kernel. thus we have
320 * to correct the kissparm signature, because it
321 * indicates a crc but there's none
322 */
323 *ax->rbuff &= ~0x20;
324 }
325 }
326 spin_unlock_bh(&ax->buflock);
327
328 count = ax->rcount;
329
330 if ((skb = dev_alloc_skb(count)) == NULL) {
331 printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n", ax->dev->name);
332 ax->rx_dropped++;
333 return;
334 }
335
336 spin_lock_bh(&ax->buflock);
337 memcpy(skb_put(skb,count), ax->rbuff, count);
338 spin_unlock_bh(&ax->buflock);
339 skb->protocol = ax25_type_trans(skb, ax->dev);
340 netif_rx(skb);
341 ax->dev->last_rx = jiffies;
342 ax->rx_packets++;
343 ax->rx_bytes+=count;
344} 397}
345 398
346/* Encapsulate one AX.25 packet and stuff into a TTY queue. */ 399/* Encapsulate one AX.25 packet and stuff into a TTY queue. */
347static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len) 400static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
348{ 401{
402 struct mkiss *ax = netdev_priv(dev);
349 unsigned char *p; 403 unsigned char *p;
350 int actual, count; 404 int actual, count;
351 405
@@ -355,8 +409,8 @@ static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len)
355 if (len > ax->mtu) { /* Sigh, shouldn't occur BUT ... */ 409 if (len > ax->mtu) { /* Sigh, shouldn't occur BUT ... */
356 len = ax->mtu; 410 len = ax->mtu;
357 printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name); 411 printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name);
358 ax->tx_dropped++; 412 ax->stats.tx_dropped++;
359 ax_unlock(ax); 413 netif_start_queue(dev);
360 return; 414 return;
361 } 415 }
362 416
@@ -377,10 +431,11 @@ static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len)
377 break; 431 break;
378 } 432 }
379 433
380 ax->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); 434 set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
381 actual = ax->tty->driver->write(ax->tty, ax->xbuff, count); 435 actual = ax->tty->driver->write(ax->tty, ax->xbuff, count);
382 ax->tx_packets++; 436 ax->stats.tx_packets++;
383 ax->tx_bytes+=actual; 437 ax->stats.tx_bytes += actual;
438
384 ax->dev->trans_start = jiffies; 439 ax->dev->trans_start = jiffies;
385 ax->xleft = count - actual; 440 ax->xleft = count - actual;
386 ax->xhead = ax->xbuff + actual; 441 ax->xhead = ax->xbuff + actual;
@@ -388,37 +443,10 @@ static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len)
388 spin_unlock_bh(&ax->buflock); 443 spin_unlock_bh(&ax->buflock);
389} 444}
390 445
391/*
392 * Called by the driver when there's room for more data. If we have
393 * more packets to send, we send them here.
394 */
395static void ax25_write_wakeup(struct tty_struct *tty)
396{
397 int actual;
398 struct ax_disp *ax = (struct ax_disp *) tty->disc_data;
399
400 /* First make sure we're connected. */
401 if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev))
402 return;
403 if (ax->xleft <= 0) {
404 /* Now serial buffer is almost free & we can start
405 * transmission of another packet
406 */
407 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
408
409 netif_wake_queue(ax->dev);
410 return;
411 }
412
413 actual = tty->driver->write(tty, ax->xhead, ax->xleft);
414 ax->xleft -= actual;
415 ax->xhead += actual;
416}
417
418/* Encapsulate an AX.25 packet and kick it into a TTY queue. */ 446/* Encapsulate an AX.25 packet and kick it into a TTY queue. */
419static int ax_xmit(struct sk_buff *skb, struct net_device *dev) 447static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
420{ 448{
421 struct ax_disp *ax = netdev_priv(dev); 449 struct mkiss *ax = netdev_priv(dev);
422 450
423 if (!netif_running(dev)) { 451 if (!netif_running(dev)) {
424 printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); 452 printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name);
@@ -440,20 +468,30 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
440 "bad line quality" : "driver error"); 468 "bad line quality" : "driver error");
441 469
442 ax->xleft = 0; 470 ax->xleft = 0;
443 ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); 471 clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
444 ax_unlock(ax); 472 netif_start_queue(dev);
445 } 473 }
446 474
447 /* We were not busy, so we are now... :-) */ 475 /* We were not busy, so we are now... :-) */
448 if (skb != NULL) { 476 if (skb != NULL) {
449 ax_lock(ax); 477 netif_stop_queue(dev);
450 ax_encaps(ax, skb->data, skb->len); 478 ax_encaps(dev, skb->data, skb->len);
451 kfree_skb(skb); 479 kfree_skb(skb);
452 } 480 }
453 481
454 return 0; 482 return 0;
455} 483}
456 484
485static int ax_open_dev(struct net_device *dev)
486{
487 struct mkiss *ax = netdev_priv(dev);
488
489 if (ax->tty == NULL)
490 return -ENODEV;
491
492 return 0;
493}
494
457#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) 495#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
458 496
459/* Return the frame type ID */ 497/* Return the frame type ID */
@@ -482,7 +520,7 @@ static int ax_rebuild_header(struct sk_buff *skb)
482/* Open the low-level part of the AX25 channel. Easy! */ 520/* Open the low-level part of the AX25 channel. Easy! */
483static int ax_open(struct net_device *dev) 521static int ax_open(struct net_device *dev)
484{ 522{
485 struct ax_disp *ax = netdev_priv(dev); 523 struct mkiss *ax = netdev_priv(dev);
486 unsigned long len; 524 unsigned long len;
487 525
488 if (ax->tty == NULL) 526 if (ax->tty == NULL)
@@ -519,7 +557,6 @@ static int ax_open(struct net_device *dev)
519 557
520 spin_lock_init(&ax->buflock); 558 spin_lock_init(&ax->buflock);
521 559
522 netif_start_queue(dev);
523 return 0; 560 return 0;
524 561
525noxbuff: 562noxbuff:
@@ -533,68 +570,100 @@ norbuff:
533/* Close the low-level part of the AX25 channel. Easy! */ 570/* Close the low-level part of the AX25 channel. Easy! */
534static int ax_close(struct net_device *dev) 571static int ax_close(struct net_device *dev)
535{ 572{
536 struct ax_disp *ax = netdev_priv(dev); 573 struct mkiss *ax = netdev_priv(dev);
537 574
538 if (ax->tty == NULL) 575 if (ax->tty)
539 return -EBUSY; 576 clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
540
541 ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
542 577
543 netif_stop_queue(dev); 578 netif_stop_queue(dev);
544 579
545 return 0; 580 return 0;
546} 581}
547 582
548static int ax25_receive_room(struct tty_struct *tty) 583static struct net_device_stats *ax_get_stats(struct net_device *dev)
549{ 584{
550 return 65536; /* We can handle an infinite amount of data. :-) */ 585 struct mkiss *ax = netdev_priv(dev);
586
587 return &ax->stats;
588}
589
590static void ax_setup(struct net_device *dev)
591{
592 static char ax25_bcast[AX25_ADDR_LEN] =
593 {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
594 static char ax25_test[AX25_ADDR_LEN] =
595 {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
596
597 /* Finish setting up the DEVICE info. */
598 dev->mtu = AX_MTU;
599 dev->hard_start_xmit = ax_xmit;
600 dev->open = ax_open_dev;
601 dev->stop = ax_close;
602 dev->get_stats = ax_get_stats;
603 dev->set_mac_address = ax_set_mac_address;
604 dev->hard_header_len = 0;
605 dev->addr_len = 0;
606 dev->type = ARPHRD_AX25;
607 dev->tx_queue_len = 10;
608 dev->hard_header = ax_header;
609 dev->rebuild_header = ax_rebuild_header;
610
611 memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
612 memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN);
613
614 dev->flags = IFF_BROADCAST | IFF_MULTICAST;
551} 615}
552 616
553/* 617/*
554 * Handle the 'receiver data ready' interrupt. 618 * We have a potential race on dereferencing tty->disc_data, because the tty
555 * This function is called by the 'tty_io' module in the kernel when 619 * layer provides no locking at all - thus one cpu could be running
556 * a block of data has been received, which can now be decapsulated 620 * sixpack_receive_buf while another calls sixpack_close, which zeroes
557 * and sent on to the AX.25 layer for further processing. 621 * tty->disc_data and frees the memory that sixpack_receive_buf is using. The
622 * best way to fix this is to use a rwlock in the tty struct, but for now we
623 * use a single global rwlock for all ttys in ppp line discipline.
558 */ 624 */
559static void ax25_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) 625static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
626
627static struct mkiss *mkiss_get(struct tty_struct *tty)
560{ 628{
561 struct ax_disp *ax = (struct ax_disp *) tty->disc_data; 629 struct mkiss *ax;
562 630
563 if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev)) 631 read_lock(&disc_data_lock);
564 return; 632 ax = tty->disc_data;
633 if (ax)
634 atomic_inc(&ax->refcnt);
635 read_unlock(&disc_data_lock);
565 636
566 /* 637 return ax;
567 * Argh! mtu change time! - costs us the packet part received 638}
568 * at the change
569 */
570 if (ax->mtu != ax->dev->mtu + 73)
571 ax_changedmtu(ax);
572
573 /* Read the characters out of the buffer */
574 while (count--) {
575 if (fp != NULL && *fp++) {
576 if (!test_and_set_bit(AXF_ERROR, &ax->flags))
577 ax->rx_errors++;
578 cp++;
579 continue;
580 }
581 639
582 kiss_unesc(ax, *cp++); 640static void mkiss_put(struct mkiss *ax)
583 } 641{
642 if (atomic_dec_and_test(&ax->refcnt))
643 up(&ax->dead_sem);
584} 644}
585 645
586static int ax25_open(struct tty_struct *tty) 646static int mkiss_open(struct tty_struct *tty)
587{ 647{
588 struct ax_disp *ax = (struct ax_disp *) tty->disc_data; 648 struct net_device *dev;
649 struct mkiss *ax;
589 int err; 650 int err;
590 651
591 /* First make sure we're not already connected. */ 652 if (!capable(CAP_NET_ADMIN))
592 if (ax && ax->magic == AX25_MAGIC) 653 return -EPERM;
593 return -EEXIST;
594 654
595 /* OK. Find a free AX25 channel to use. */ 655 dev = alloc_netdev(sizeof(struct mkiss), "ax%d", ax_setup);
596 if ((ax = ax_alloc()) == NULL) 656 if (!dev) {
597 return -ENFILE; 657 err = -ENOMEM;
658 goto out;
659 }
660
661 ax = netdev_priv(dev);
662 ax->dev = dev;
663
664 spin_lock_init(&ax->buflock);
665 atomic_set(&ax->refcnt, 1);
666 init_MUTEX_LOCKED(&ax->dead_sem);
598 667
599 ax->tty = tty; 668 ax->tty = tty;
600 tty->disc_data = ax; 669 tty->disc_data = ax;
@@ -603,283 +672,212 @@ static int ax25_open(struct tty_struct *tty)
603 tty->driver->flush_buffer(tty); 672 tty->driver->flush_buffer(tty);
604 673
605 /* Restore default settings */ 674 /* Restore default settings */
606 ax->dev->type = ARPHRD_AX25; 675 dev->type = ARPHRD_AX25;
607 676
608 /* Perform the low-level AX25 initialization. */ 677 /* Perform the low-level AX25 initialization. */
609 if ((err = ax_open(ax->dev))) 678 if ((err = ax_open(ax->dev))) {
610 return err; 679 goto out_free_netdev;
680 }
611 681
612 /* Done. We have linked the TTY line to a channel. */ 682 if (register_netdev(dev))
613 return ax->dev->base_addr; 683 goto out_free_buffers;
614}
615 684
616static void ax25_close(struct tty_struct *tty) 685 netif_start_queue(dev);
617{
618 struct ax_disp *ax = (struct ax_disp *) tty->disc_data;
619 686
620 /* First make sure we're connected. */ 687 /* Done. We have linked the TTY line to a channel. */
621 if (ax == NULL || ax->magic != AX25_MAGIC) 688 return 0;
622 return;
623 689
624 unregister_netdev(ax->dev); 690out_free_buffers:
691 kfree(ax->rbuff);
692 kfree(ax->xbuff);
625 693
626 tty->disc_data = NULL; 694out_free_netdev:
627 ax->tty = NULL; 695 free_netdev(dev);
628 696
629 ax_free(ax); 697out:
698 return err;
630} 699}
631 700
632 701static void mkiss_close(struct tty_struct *tty)
633static struct net_device_stats *ax_get_stats(struct net_device *dev)
634{ 702{
635 static struct net_device_stats stats; 703 struct mkiss *ax;
636 struct ax_disp *ax = netdev_priv(dev);
637
638 memset(&stats, 0, sizeof(struct net_device_stats));
639
640 stats.rx_packets = ax->rx_packets;
641 stats.tx_packets = ax->tx_packets;
642 stats.rx_bytes = ax->rx_bytes;
643 stats.tx_bytes = ax->tx_bytes;
644 stats.rx_dropped = ax->rx_dropped;
645 stats.tx_dropped = ax->tx_dropped;
646 stats.tx_errors = ax->tx_errors;
647 stats.rx_errors = ax->rx_errors;
648 stats.rx_over_errors = ax->rx_over_errors;
649
650 return &stats;
651}
652 704
705 write_lock(&disc_data_lock);
706 ax = tty->disc_data;
707 tty->disc_data = NULL;
708 write_unlock(&disc_data_lock);
653 709
654/************************************************************************ 710 if (ax == 0)
655 * STANDARD ENCAPSULATION * 711 return;
656 ************************************************************************/
657
658static int kiss_esc(unsigned char *s, unsigned char *d, int len)
659{
660 unsigned char *ptr = d;
661 unsigned char c;
662 712
663 /* 713 /*
664 * Send an initial END character to flush out any 714 * We have now ensured that nobody can start using ap from now on, but
665 * data that may have accumulated in the receiver 715 * we have to wait for all existing users to finish.
666 * due to line noise.
667 */ 716 */
717 if (!atomic_dec_and_test(&ax->refcnt))
718 down(&ax->dead_sem);
668 719
669 *ptr++ = END; 720 unregister_netdev(ax->dev);
670
671 while (len-- > 0) {
672 switch (c = *s++) {
673 case END:
674 *ptr++ = ESC;
675 *ptr++ = ESC_END;
676 break;
677 case ESC:
678 *ptr++ = ESC;
679 *ptr++ = ESC_ESC;
680 break;
681 default:
682 *ptr++ = c;
683 break;
684 }
685 }
686 721
687 *ptr++ = END; 722 /* Free all AX25 frame buffers. */
723 kfree(ax->rbuff);
724 kfree(ax->xbuff);
688 725
689 return ptr - d; 726 ax->tty = NULL;
690} 727}
691 728
692/* 729/* Perform I/O control on an active ax25 channel. */
693 * MW: 730static int mkiss_ioctl(struct tty_struct *tty, struct file *file,
694 * OK its ugly, but tell me a better solution without copying the 731 unsigned int cmd, unsigned long arg)
695 * packet to a temporary buffer :-)
696 */
697static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc, int len)
698{ 732{
699 unsigned char *ptr = d; 733 struct mkiss *ax = mkiss_get(tty);
700 unsigned char c=0; 734 struct net_device *dev = ax->dev;
701 735 unsigned int tmp, err;
702 *ptr++ = END;
703 while (len > 0) {
704 if (len > 2)
705 c = *s++;
706 else if (len > 1)
707 c = crc >> 8;
708 else if (len > 0)
709 c = crc & 0xff;
710 736
711 len--; 737 /* First make sure we're connected. */
738 if (ax == NULL)
739 return -ENXIO;
712 740
713 switch (c) { 741 switch (cmd) {
714 case END: 742 case SIOCGIFNAME:
715 *ptr++ = ESC; 743 err = copy_to_user((void __user *) arg, ax->dev->name,
716 *ptr++ = ESC_END; 744 strlen(ax->dev->name) + 1) ? -EFAULT : 0;
717 break; 745 break;
718 case ESC: 746
719 *ptr++ = ESC; 747 case SIOCGIFENCAP:
720 *ptr++ = ESC_ESC; 748 err = put_user(4, (int __user *) arg);
721 break; 749 break;
722 default: 750
723 *ptr++ = c; 751 case SIOCSIFENCAP:
724 break; 752 if (get_user(tmp, (int __user *) arg)) {
753 err = -EFAULT;
754 break;
725 } 755 }
726 }
727 *ptr++ = END;
728 return ptr - d;
729}
730 756
731static void kiss_unesc(struct ax_disp *ax, unsigned char s) 757 ax->mode = tmp;
732{ 758 dev->addr_len = AX25_ADDR_LEN;
733 switch (s) { 759 dev->hard_header_len = AX25_KISS_HEADER_LEN +
734 case END: 760 AX25_MAX_HEADER_LEN + 3;
735 /* drop keeptest bit = VSV */ 761 dev->type = ARPHRD_AX25;
736 if (test_bit(AXF_KEEPTEST, &ax->flags))
737 clear_bit(AXF_KEEPTEST, &ax->flags);
738 762
739 if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2)) 763 err = 0;
740 ax_bump(ax); 764 break;
741 765
742 clear_bit(AXF_ESCAPE, &ax->flags); 766 case SIOCSIFHWADDR: {
743 ax->rcount = 0; 767 char addr[AX25_ADDR_LEN];
744 return; 768printk(KERN_INFO "In SIOCSIFHWADDR");
745 769
746 case ESC: 770 if (copy_from_user(&addr,
747 set_bit(AXF_ESCAPE, &ax->flags); 771 (void __user *) arg, AX25_ADDR_LEN)) {
748 return; 772 err = -EFAULT;
749 case ESC_ESC:
750 if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
751 s = ESC;
752 break; 773 break;
753 case ESC_END:
754 if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
755 s = END;
756 break;
757 }
758
759 spin_lock_bh(&ax->buflock);
760 if (!test_bit(AXF_ERROR, &ax->flags)) {
761 if (ax->rcount < ax->buffsize) {
762 ax->rbuff[ax->rcount++] = s;
763 spin_unlock_bh(&ax->buflock);
764 return;
765 } 774 }
766 775
767 ax->rx_over_errors++; 776 spin_lock_irq(&dev->xmit_lock);
768 set_bit(AXF_ERROR, &ax->flags); 777 memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
778 spin_unlock_irq(&dev->xmit_lock);
779
780 err = 0;
781 break;
782 }
783 default:
784 err = -ENOIOCTLCMD;
769 } 785 }
770 spin_unlock_bh(&ax->buflock);
771}
772 786
787 mkiss_put(ax);
773 788
774static int ax_set_mac_address(struct net_device *dev, void __user *addr) 789 return err;
775{
776 if (copy_from_user(dev->dev_addr, addr, AX25_ADDR_LEN))
777 return -EFAULT;
778 return 0;
779} 790}
780 791
781static int ax_set_dev_mac_address(struct net_device *dev, void *addr) 792/*
793 * Handle the 'receiver data ready' interrupt.
794 * This function is called by the 'tty_io' module in the kernel when
795 * a block of data has been received, which can now be decapsulated
796 * and sent on to the AX.25 layer for further processing.
797 */
798static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
799 char *fp, int count)
782{ 800{
783 struct sockaddr *sa = addr; 801 struct mkiss *ax = mkiss_get(tty);
784
785 memcpy(dev->dev_addr, sa->sa_data, AX25_ADDR_LEN);
786 802
787 return 0; 803 if (!ax)
788} 804 return;
789
790
791/* Perform I/O control on an active ax25 channel. */
792static int ax25_disp_ioctl(struct tty_struct *tty, void *file, int cmd, void __user *arg)
793{
794 struct ax_disp *ax = (struct ax_disp *) tty->disc_data;
795 unsigned int tmp;
796 805
797 /* First make sure we're connected. */ 806 /*
798 if (ax == NULL || ax->magic != AX25_MAGIC) 807 * Argh! mtu change time! - costs us the packet part received
799 return -EINVAL; 808 * at the change
809 */
810 if (ax->mtu != ax->dev->mtu + 73)
811 ax_changedmtu(ax);
800 812
801 switch (cmd) { 813 /* Read the characters out of the buffer */
802 case SIOCGIFNAME: 814 while (count--) {
803 if (copy_to_user(arg, ax->dev->name, strlen(ax->dev->name) + 1)) 815 if (fp != NULL && *fp++) {
804 return -EFAULT; 816 if (!test_and_set_bit(AXF_ERROR, &ax->flags))
805 return 0; 817 ax->stats.rx_errors++;
806 818 cp++;
807 case SIOCGIFENCAP: 819 continue;
808 return put_user(4, (int __user *)arg); 820 }
809
810 case SIOCSIFENCAP:
811 if (get_user(tmp, (int __user *)arg))
812 return -EFAULT;
813 ax->mode = tmp;
814 ax->dev->addr_len = AX25_ADDR_LEN; /* sizeof an AX.25 addr */
815 ax->dev->hard_header_len = AX25_KISS_HEADER_LEN + AX25_MAX_HEADER_LEN + 3;
816 ax->dev->type = ARPHRD_AX25;
817 return 0;
818
819 case SIOCSIFHWADDR:
820 return ax_set_mac_address(ax->dev, arg);
821 821
822 default: 822 kiss_unesc(ax, *cp++);
823 return -ENOIOCTLCMD;
824 } 823 }
824
825 mkiss_put(ax);
826 if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
827 && tty->driver->unthrottle)
828 tty->driver->unthrottle(tty);
825} 829}
826 830
827static int ax_open_dev(struct net_device *dev) 831static int mkiss_receive_room(struct tty_struct *tty)
828{ 832{
829 struct ax_disp *ax = netdev_priv(dev); 833 return 65536; /* We can handle an infinite amount of data. :-) */
830
831 if (ax->tty == NULL)
832 return -ENODEV;
833
834 return 0;
835} 834}
836 835
837 836/*
838/* Initialize the driver. Called by network startup. */ 837 * Called by the driver when there's room for more data. If we have
839static int ax25_init(struct net_device *dev) 838 * more packets to send, we send them here.
839 */
840static void mkiss_write_wakeup(struct tty_struct *tty)
840{ 841{
841 struct ax_disp *ax = netdev_priv(dev); 842 struct mkiss *ax = mkiss_get(tty);
842 843 int actual;
843 static char ax25_bcast[AX25_ADDR_LEN] =
844 {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
845 static char ax25_test[AX25_ADDR_LEN] =
846 {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
847
848 if (ax == NULL) /* Allocation failed ?? */
849 return -ENODEV;
850 844
851 /* Set up the "AX25 Control Block". (And clear statistics) */ 845 if (!ax)
852 memset(ax, 0, sizeof (struct ax_disp)); 846 return;
853 ax->magic = AX25_MAGIC;
854 ax->dev = dev;
855 847
856 /* Finish setting up the DEVICE info. */ 848 if (ax->xleft <= 0) {
857 dev->mtu = AX_MTU; 849 /* Now serial buffer is almost free & we can start
858 dev->hard_start_xmit = ax_xmit; 850 * transmission of another packet
859 dev->open = ax_open_dev; 851 */
860 dev->stop = ax_close; 852 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
861 dev->get_stats = ax_get_stats;
862 dev->set_mac_address = ax_set_dev_mac_address;
863 dev->hard_header_len = 0;
864 dev->addr_len = 0;
865 dev->type = ARPHRD_AX25;
866 dev->tx_queue_len = 10;
867 dev->hard_header = ax_header;
868 dev->rebuild_header = ax_rebuild_header;
869 853
870 memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); 854 netif_wake_queue(ax->dev);
871 memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN); 855 goto out;
856 }
872 857
873 /* New-style flags. */ 858 actual = tty->driver->write(tty, ax->xhead, ax->xleft);
874 dev->flags = IFF_BROADCAST | IFF_MULTICAST; 859 ax->xleft -= actual;
860 ax->xhead += actual;
875 861
876 return 0; 862out:
863 mkiss_put(ax);
877} 864}
878 865
866static struct tty_ldisc ax_ldisc = {
867 .magic = TTY_LDISC_MAGIC,
868 .name = "mkiss",
869 .open = mkiss_open,
870 .close = mkiss_close,
871 .ioctl = mkiss_ioctl,
872 .receive_buf = mkiss_receive_buf,
873 .receive_room = mkiss_receive_room,
874 .write_wakeup = mkiss_write_wakeup
875};
879 876
880/* ******************************************************************** */ 877static char banner[] __initdata = KERN_INFO \
881/* * Init MKISS driver * */ 878 "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
882/* ******************************************************************** */ 879static char msg_regfail[] __initdata = KERN_ERR \
880 "mkiss: can't register line discipline (err = %d)\n";
883 881
884static int __init mkiss_init_driver(void) 882static int __init mkiss_init_driver(void)
885{ 883{
@@ -887,64 +885,27 @@ static int __init mkiss_init_driver(void)
887 885
888 printk(banner); 886 printk(banner);
889 887
890 if (ax25_maxdev < 4) 888 if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0)
891 ax25_maxdev = 4; /* Sanity */ 889 printk(msg_regfail);
892 890
893 if ((ax25_ctrls = kmalloc(sizeof(void *) * ax25_maxdev, GFP_KERNEL)) == NULL) {
894 printk(KERN_ERR "mkiss: Can't allocate ax25_ctrls[] array!\n");
895 return -ENOMEM;
896 }
897
898 /* Clear the pointer array, we allocate devices when we need them */
899 memset(ax25_ctrls, 0, sizeof(void*) * ax25_maxdev); /* Pointers */
900
901 /* Fill in our line protocol discipline, and register it */
902 ax_ldisc.magic = TTY_LDISC_MAGIC;
903 ax_ldisc.name = "mkiss";
904 ax_ldisc.open = ax25_open;
905 ax_ldisc.close = ax25_close;
906 ax_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *,
907 unsigned int, unsigned long))ax25_disp_ioctl;
908 ax_ldisc.receive_buf = ax25_receive_buf;
909 ax_ldisc.receive_room = ax25_receive_room;
910 ax_ldisc.write_wakeup = ax25_write_wakeup;
911
912 if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0) {
913 printk(KERN_ERR "mkiss: can't register line discipline (err = %d)\n", status);
914 kfree(ax25_ctrls);
915 }
916 return status; 891 return status;
917} 892}
918 893
894static const char msg_unregfail[] __exitdata = KERN_ERR \
895 "mkiss: can't unregister line discipline (err = %d)\n";
896
919static void __exit mkiss_exit_driver(void) 897static void __exit mkiss_exit_driver(void)
920{ 898{
921 int i; 899 int ret;
922
923 for (i = 0; i < ax25_maxdev; i++) {
924 if (ax25_ctrls[i]) {
925 /*
926 * VSV = if dev->start==0, then device
927 * unregistered while close proc.
928 */
929 if (netif_running(&ax25_ctrls[i]->dev))
930 unregister_netdev(&ax25_ctrls[i]->dev);
931 kfree(ax25_ctrls[i]);
932 }
933 }
934 900
935 kfree(ax25_ctrls); 901 if ((ret = tty_unregister_ldisc(N_AX25)))
936 ax25_ctrls = NULL; 902 printk(msg_unregfail, ret);
937
938 if ((i = tty_unregister_ldisc(N_AX25)))
939 printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i);
940} 903}
941 904
942MODULE_AUTHOR("Hans Albas PE1AYX <hans@esrac.ele.tue.nl>"); 905MODULE_AUTHOR("Ralf Baechle DL5RB <ralf@linux-mips.org>");
943MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs"); 906MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
944MODULE_PARM(ax25_maxdev, "i");
945MODULE_PARM_DESC(ax25_maxdev, "number of MKISS devices");
946MODULE_LICENSE("GPL"); 907MODULE_LICENSE("GPL");
947MODULE_ALIAS_LDISC(N_AX25); 908MODULE_ALIAS_LDISC(N_AX25);
909
948module_init(mkiss_init_driver); 910module_init(mkiss_init_driver);
949module_exit(mkiss_exit_driver); 911module_exit(mkiss_exit_driver);
950