Import 2.3.10pre5
[davej-history.git] / drivers / net / hamradio / baycom_epp.c
blobd72719e5c0558a1d47fd72f9a45a421ec716f079
1 /*****************************************************************************/
3 /*
4 * baycom_epp.c -- baycom epp radio modem driver.
6 * Copyright (C) 1998
7 * Thomas Sailer (sailer@ife.ee.ethz.ch)
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Please note that the GPL allows you to use the driver, NOT the radio.
24 * In order to use the radio, you need a license from the communications
25 * authority of your country.
28 * History:
29 * 0.1 xx.xx.98 Initial version by Matthias Welwarsky (dg2fef)
30 * 0.2 21.04.98 Massive rework by Thomas Sailer
31 * Integrated FPGA EPP modem configuration routines
32 * 0.3 11.05.98 Took FPGA config out and moved it into a separate program
36 /*****************************************************************************/
38 #include <linux/config.h>
39 #include <linux/module.h>
40 #include <linux/kernel.h>
41 #include <linux/types.h>
42 #include <linux/ptrace.h>
43 #include <linux/socket.h>
44 #include <linux/sched.h>
45 #include <linux/interrupt.h>
46 #include <linux/ioport.h>
47 #include <linux/in.h>
48 #include <linux/string.h>
49 #include <linux/parport.h>
50 #include <linux/bitops.h>
51 #include <asm/system.h>
52 #include <asm/io.h>
53 #include <asm/processor.h>
54 #include <linux/delay.h>
55 #include <linux/errno.h>
56 #include <linux/netdevice.h>
57 #include <linux/if_arp.h>
58 //#include <net/ax25dev.h>
59 #include <linux/kmod.h>
60 #include <linux/hdlcdrv.h>
61 #include <linux/baycom.h>
62 #include <linux/soundmodem.h>
63 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
64 /* prototypes for ax25_encapsulate and ax25_rebuild_header */
65 #include <net/ax25.h>
66 #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
68 #define __KERNEL_SYSCALLS__
69 #include <linux/unistd.h>
71 /* --------------------------------------------------------------------- */
74 * currently this module is supposed to support both module styles, i.e.
75 * the old one present up to about 2.1.9, and the new one functioning
76 * starting with 2.1.21. The reason is I have a kit allowing to compile
77 * this module also under 2.0.x which was requested by several people.
78 * This will go in 2.2
80 #include <linux/version.h>
82 #if LINUX_VERSION_CODE >= 0x20100
83 #include <asm/uaccess.h>
84 #else
85 #include <asm/segment.h>
86 #include <linux/mm.h>
88 #undef put_user
89 #undef get_user
91 #define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
92 #define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
94 extern inline int copy_from_user(void *to, const void *from, unsigned long n)
96 int i = verify_area(VERIFY_READ, from, n);
97 if (i)
98 return i;
99 memcpy_fromfs(to, from, n);
100 return 0;
103 extern inline int copy_to_user(void *to, const void *from, unsigned long n)
105 int i = verify_area(VERIFY_WRITE, to, n);
106 if (i)
107 return i;
108 memcpy_tofs(to, from, n);
109 return 0;
111 #endif
113 #if LINUX_VERSION_CODE >= 0x20123
114 #include <linux/init.h>
115 #else
116 #define __init
117 #define __initdata
118 #define __initfunc(x) x
119 #endif
121 /* --------------------------------------------------------------------- */
123 #define BAYCOM_DEBUG
124 #define BAYCOM_MAGIC 19730510
126 /* --------------------------------------------------------------------- */
128 static const char paranoia_str[] = KERN_ERR
129 "baycom_epp: bad magic number for hdlcdrv_state struct in routine %s\n";
131 #define baycom_paranoia_check(dev,routine,retval) \
132 ({ \
133 if (!dev || !dev->priv || ((struct baycom_state *)dev->priv)->magic != BAYCOM_MAGIC) { \
134 printk(paranoia_str, routine); \
135 return retval; \
139 #define baycom_paranoia_check_void(dev,routine) \
140 ({ \
141 if (!dev || !dev->priv || ((struct baycom_state *)dev->priv)->magic != BAYCOM_MAGIC) { \
142 printk(paranoia_str, routine); \
143 return; \
147 /* --------------------------------------------------------------------- */
149 static const char bc_drvname[] = "baycom_epp";
150 static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998 Thomas Sailer, HB9JNX/AE4WA\n"
151 KERN_INFO "baycom_epp: version 0.3 compiled " __TIME__ " " __DATE__ "\n";
153 /* --------------------------------------------------------------------- */
155 #define NR_PORTS 4
157 static struct device baycom_device[NR_PORTS];
159 static struct {
160 const char *mode;
161 int iobase;
162 } baycom_ports[NR_PORTS] = { { NULL, 0 }, };
164 /* --------------------------------------------------------------------- */
166 /* EPP status register */
167 #define EPP_DCDBIT 0x80
168 #define EPP_PTTBIT 0x08
169 #define EPP_NREF 0x01
170 #define EPP_NRAEF 0x02
171 #define EPP_NRHF 0x04
172 #define EPP_NTHF 0x20
173 #define EPP_NTAEF 0x10
174 #define EPP_NTEF EPP_PTTBIT
176 /* EPP control register */
177 #define EPP_TX_FIFO_ENABLE 0x10
178 #define EPP_RX_FIFO_ENABLE 0x08
179 #define EPP_MODEM_ENABLE 0x20
180 #define EPP_LEDS 0xC0
181 #define EPP_IRQ_ENABLE 0x10
183 /* LPT registers */
184 #define LPTREG_ECONTROL 0x402
185 #define LPTREG_CONFIGB 0x401
186 #define LPTREG_CONFIGA 0x400
187 #define LPTREG_EPPDATA 0x004
188 #define LPTREG_EPPADDR 0x003
189 #define LPTREG_CONTROL 0x002
190 #define LPTREG_STATUS 0x001
191 #define LPTREG_DATA 0x000
193 /* LPT control register */
194 #define LPTCTRL_PROGRAM 0x04 /* 0 to reprogram */
195 #define LPTCTRL_WRITE 0x01
196 #define LPTCTRL_ADDRSTB 0x08
197 #define LPTCTRL_DATASTB 0x02
198 #define LPTCTRL_INTEN 0x10
200 /* LPT status register */
201 #define LPTSTAT_SHIFT_NINTR 6
202 #define LPTSTAT_WAIT 0x80
203 #define LPTSTAT_NINTR (1<<LPTSTAT_SHIFT_NINTR)
204 #define LPTSTAT_PE 0x20
205 #define LPTSTAT_DONE 0x10
206 #define LPTSTAT_NERROR 0x08
207 #define LPTSTAT_EPPTIMEOUT 0x01
209 /* LPT data register */
210 #define LPTDATA_SHIFT_TDI 0
211 #define LPTDATA_SHIFT_TMS 2
212 #define LPTDATA_TDI (1<<LPTDATA_SHIFT_TDI)
213 #define LPTDATA_TCK 0x02
214 #define LPTDATA_TMS (1<<LPTDATA_SHIFT_TMS)
215 #define LPTDATA_INITBIAS 0x80
218 /* EPP modem config/status bits */
219 #define EPP_DCDBIT 0x80
220 #define EPP_PTTBIT 0x08
221 #define EPP_RXEBIT 0x01
222 #define EPP_RXAEBIT 0x02
223 #define EPP_RXHFULL 0x04
225 #define EPP_NTHF 0x20
226 #define EPP_NTAEF 0x10
227 #define EPP_NTEF EPP_PTTBIT
229 #define EPP_TX_FIFO_ENABLE 0x10
230 #define EPP_RX_FIFO_ENABLE 0x08
231 #define EPP_MODEM_ENABLE 0x20
232 #define EPP_LEDS 0xC0
233 #define EPP_IRQ_ENABLE 0x10
235 /* Xilinx 4k JTAG instructions */
236 #define XC4K_IRLENGTH 3
237 #define XC4K_EXTEST 0
238 #define XC4K_PRELOAD 1
239 #define XC4K_CONFIGURE 5
240 #define XC4K_BYPASS 7
242 #define EPP_CONVENTIONAL 0
243 #define EPP_FPGA 1
244 #define EPP_FPGAEXTSTATUS 2
246 #define TXBUFFER_SIZE ((HDLCDRV_MAXFLEN*6/5)+8)
248 /* ---------------------------------------------------------------------- */
250 * Information that need to be kept for each board.
253 struct baycom_state {
254 int magic;
256 struct pardevice *pdev;
257 unsigned int bh_running;
258 struct tq_struct run_bh;
259 unsigned int modem;
260 unsigned int bitrate;
261 unsigned char stat;
263 char ifname[HDLCDRV_IFNAMELEN];
265 struct {
266 unsigned int intclk;
267 unsigned int divider;
268 unsigned int extmodem;
269 unsigned int loopback;
270 } cfg;
272 struct hdlcdrv_channel_params ch_params;
274 struct {
275 unsigned int bitbuf, bitstream, numbits, state;
276 unsigned char *bufptr;
277 int bufcnt;
278 unsigned char buf[TXBUFFER_SIZE];
279 } hdlcrx;
281 struct {
282 int calibrate;
283 int slotcnt;
284 int flags;
285 enum { tx_idle = 0, tx_keyup, tx_data, tx_tail } state;
286 unsigned char *bufptr;
287 int bufcnt;
288 unsigned char buf[TXBUFFER_SIZE];
289 } hdlctx;
291 struct net_device_stats stats;
292 unsigned int ptt_keyed;
293 struct sk_buff_head send_queue; /* Packets awaiting transmission */
296 #ifdef BAYCOM_DEBUG
297 struct debug_vals {
298 unsigned long last_jiffies;
299 unsigned cur_intcnt;
300 unsigned last_intcnt;
301 int cur_pllcorr;
302 int last_pllcorr;
303 unsigned int mod_cycles;
304 unsigned int demod_cycles;
305 } debug_vals;
306 #endif /* BAYCOM_DEBUG */
309 /* --------------------------------------------------------------------- */
311 #define min(a, b) (((a) < (b)) ? (a) : (b))
312 #define max(a, b) (((a) > (b)) ? (a) : (b))
314 /* --------------------------------------------------------------------- */
316 #define KISS_VERBOSE
318 /* --------------------------------------------------------------------- */
320 #define PARAM_TXDELAY 1
321 #define PARAM_PERSIST 2
322 #define PARAM_SLOTTIME 3
323 #define PARAM_TXTAIL 4
324 #define PARAM_FULLDUP 5
325 #define PARAM_HARDWARE 6
326 #define PARAM_RETURN 255
328 /* --------------------------------------------------------------------- */
330 * the CRC routines are stolen from WAMPES
331 * by Dieter Deyke
334 static const unsigned short crc_ccitt_table[] = {
335 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
336 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
337 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
338 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
339 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
340 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
341 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
342 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
343 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
344 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
345 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
346 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
347 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
348 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
349 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
350 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
351 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
352 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
353 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
354 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
355 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
356 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
357 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
358 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
359 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
360 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
361 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
362 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
363 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
364 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
365 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
366 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
369 /*---------------------------------------------------------------------------*/
371 #if 0
372 extern inline void append_crc_ccitt(unsigned char *buffer, int len)
374 unsigned int crc = 0xffff;
376 for (;len>0;len--)
377 crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buffer++) & 0xff];
378 crc ^= 0xffff;
379 *buffer++ = crc;
380 *buffer++ = crc >> 8;
382 #endif
384 /*---------------------------------------------------------------------------*/
386 extern inline int check_crc_ccitt(const unsigned char *buf, int cnt)
388 unsigned int crc = 0xffff;
390 for (; cnt > 0; cnt--)
391 crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
392 return (crc & 0xffff) == 0xf0b8;
395 /*---------------------------------------------------------------------------*/
397 extern inline int calc_crc_ccitt(const unsigned char *buf, int cnt)
399 unsigned int crc = 0xffff;
401 for (; cnt > 0; cnt--)
402 crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
403 crc ^= 0xffff;
404 return (crc & 0xffff);
407 /* ---------------------------------------------------------------------- */
409 #define tenms_to_flags(bc,tenms) ((tenms * bc->bitrate) / 800)
411 /* --------------------------------------------------------------------- */
413 static void inline baycom_int_freq(struct baycom_state *bc)
415 #ifdef BAYCOM_DEBUG
416 unsigned long cur_jiffies = jiffies;
418 * measure the interrupt frequency
420 bc->debug_vals.cur_intcnt++;
421 if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) {
422 bc->debug_vals.last_jiffies = cur_jiffies;
423 bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt;
424 bc->debug_vals.cur_intcnt = 0;
425 bc->debug_vals.last_pllcorr = bc->debug_vals.cur_pllcorr;
426 bc->debug_vals.cur_pllcorr = 0;
428 #endif /* BAYCOM_DEBUG */
431 /* ---------------------------------------------------------------------- */
433 * eppconfig_path should be setable via /proc/sys.
436 char eppconfig_path[256] = "/sbin/eppfpga";
438 static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL };
440 static int errno;
442 static int exec_eppfpga(void *b)
444 struct baycom_state *bc = (struct baycom_state *)b;
445 char modearg[256];
446 char portarg[16];
447 char *argv[] = { eppconfig_path, "-s", "-p", portarg, "-m", modearg, NULL};
448 int i;
450 /* set up arguments */
451 sprintf(modearg, "%sclk,%smodem,divider=%d%s,extstat",
452 bc->cfg.intclk ? "int" : "ext",
453 bc->cfg.extmodem ? "ext" : "int", bc->cfg.divider,
454 bc->cfg.loopback ? ",loopback" : "");
455 sprintf(portarg, "%ld", bc->pdev->port->base);
456 printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg);
458 for (i = 0; i < current->files->max_fds; i++ )
459 if (current->files->fd[i])
460 close(i);
461 set_fs(KERNEL_DS); /* Allow execve args to be in kernel space. */
462 current->uid = current->euid = current->fsuid = 0;
463 if (execve(eppconfig_path, argv, envp) < 0) {
464 printk(KERN_ERR "%s: failed to exec %s -s -p %s -m %s, errno = %d\n",
465 bc_drvname, eppconfig_path, portarg, modearg, errno);
466 return -errno;
468 return 0;
472 /* eppconfig: called during ifconfig up to configure the modem */
474 static int eppconfig(struct baycom_state *bc)
476 int i, pid, r;
477 mm_segment_t fs;
479 pid = kernel_thread(exec_eppfpga, bc, CLONE_FS);
480 if (pid < 0) {
481 printk(KERN_ERR "%s: fork failed, errno %d\n", bc_drvname, -pid);
482 return pid;
484 fs = get_fs();
485 set_fs(KERNEL_DS); /* Allow i to be in kernel space. */
486 r = waitpid(pid, &i, __WCLONE);
487 set_fs(fs);
488 if (r != pid) {
489 printk(KERN_ERR "%s: waitpid(%d) failed, returning %d\n",
490 bc_drvname, pid, r);
491 return -1;
493 printk(KERN_DEBUG "%s: eppfpga returned %d\n", bc_drvname, i);
494 return i;
497 /* ---------------------------------------------------------------------- */
499 static void epp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
503 /* ---------------------------------------------------------------------- */
505 static void inline do_kiss_params(struct baycom_state *bc,
506 unsigned char *data, unsigned long len)
509 #ifdef KISS_VERBOSE
510 #define PKP(a,b) printk(KERN_INFO "%s: channel params: " a "\n", bc->ifname, b)
511 #else /* KISS_VERBOSE */
512 #define PKP(a,b)
513 #endif /* KISS_VERBOSE */
515 if (len < 2)
516 return;
517 switch(data[0]) {
518 case PARAM_TXDELAY:
519 bc->ch_params.tx_delay = data[1];
520 PKP("TX delay = %ums", 10 * bc->ch_params.tx_delay);
521 break;
522 case PARAM_PERSIST:
523 bc->ch_params.ppersist = data[1];
524 PKP("p persistence = %u", bc->ch_params.ppersist);
525 break;
526 case PARAM_SLOTTIME:
527 bc->ch_params.slottime = data[1];
528 PKP("slot time = %ums", bc->ch_params.slottime);
529 break;
530 case PARAM_TXTAIL:
531 bc->ch_params.tx_tail = data[1];
532 PKP("TX tail = %ums", bc->ch_params.tx_tail);
533 break;
534 case PARAM_FULLDUP:
535 bc->ch_params.fulldup = !!data[1];
536 PKP("%s duplex", bc->ch_params.fulldup ? "full" : "half");
537 break;
538 default:
539 break;
541 #undef PKP
544 /* --------------------------------------------------------------------- */
546 * high performance HDLC encoder
547 * yes, it's ugly, but generates pretty good code
550 #define ENCODEITERA(j) \
551 ({ \
552 if (!(notbitstream & (0x1f0 << j))) \
553 goto stuff##j; \
554 encodeend##j: \
557 #define ENCODEITERB(j) \
558 ({ \
559 stuff##j: \
560 bitstream &= ~(0x100 << j); \
561 bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | \
562 ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); \
563 numbit++; \
564 notbitstream = ~bitstream; \
565 goto encodeend##j; \
569 static void encode_hdlc(struct baycom_state *bc)
571 struct sk_buff *skb;
572 unsigned char *wp, *bp;
573 int pkt_len;
574 unsigned bitstream, notbitstream, bitbuf, numbit, crc;
575 unsigned char crcarr[2];
577 if (bc->hdlctx.bufcnt > 0)
578 return;
579 while ((skb = skb_dequeue(&bc->send_queue))) {
580 if (skb->data[0] != 0) {
581 do_kiss_params(bc, skb->data, skb->len);
582 dev_kfree_skb(skb);
583 continue;
585 pkt_len = skb->len-1; /* strip KISS byte */
586 if (pkt_len >= HDLCDRV_MAXFLEN || pkt_len < 2) {
587 dev_kfree_skb(skb);
588 continue;
590 wp = bc->hdlctx.buf;
591 bp = skb->data+1;
592 crc = calc_crc_ccitt(bp, pkt_len);
593 crcarr[0] = crc;
594 crcarr[1] = crc >> 8;
595 *wp++ = 0x7e;
596 bitstream = bitbuf = numbit = 0;
597 while (pkt_len > -2) {
598 bitstream >>= 8;
599 bitstream |= ((unsigned int)*bp) << 8;
600 bitbuf |= ((unsigned int)*bp) << numbit;
601 notbitstream = ~bitstream;
602 bp++;
603 pkt_len--;
604 if (!pkt_len)
605 bp = crcarr;
606 ENCODEITERA(0);
607 ENCODEITERA(1);
608 ENCODEITERA(2);
609 ENCODEITERA(3);
610 ENCODEITERA(4);
611 ENCODEITERA(5);
612 ENCODEITERA(6);
613 ENCODEITERA(7);
614 goto enditer;
615 ENCODEITERB(0);
616 ENCODEITERB(1);
617 ENCODEITERB(2);
618 ENCODEITERB(3);
619 ENCODEITERB(4);
620 ENCODEITERB(5);
621 ENCODEITERB(6);
622 ENCODEITERB(7);
623 enditer:
624 numbit += 8;
625 while (numbit >= 8) {
626 *wp++ = bitbuf;
627 bitbuf >>= 8;
628 numbit -= 8;
631 bitbuf |= 0x7e7e << numbit;
632 numbit += 16;
633 while (numbit >= 8) {
634 *wp++ = bitbuf;
635 bitbuf >>= 8;
636 numbit -= 8;
638 bc->hdlctx.bufptr = bc->hdlctx.buf;
639 bc->hdlctx.bufcnt = wp - bc->hdlctx.buf;
640 dev_kfree_skb(skb);
641 bc->stats.tx_packets++;
642 return;
646 /* ---------------------------------------------------------------------- */
648 static unsigned short random_seed;
650 static inline unsigned short random_num(void)
652 random_seed = 28629 * random_seed + 157;
653 return random_seed;
656 /* ---------------------------------------------------------------------- */
658 static void transmit(struct baycom_state *bc, int cnt, unsigned char stat)
660 struct parport *pp = bc->pdev->port;
661 int i;
663 if (bc->hdlctx.state == tx_tail && !(stat & EPP_PTTBIT))
664 bc->hdlctx.state = tx_idle;
665 if (bc->hdlctx.state == tx_idle && bc->hdlctx.calibrate <= 0) {
666 if (bc->hdlctx.bufcnt <= 0)
667 encode_hdlc(bc);
668 if (bc->hdlctx.bufcnt <= 0)
669 return;
670 if (!bc->ch_params.fulldup) {
671 if (!(stat & EPP_DCDBIT)) {
672 bc->hdlctx.slotcnt = bc->ch_params.slottime;
673 return;
675 if ((--bc->hdlctx.slotcnt) > 0)
676 return;
677 bc->hdlctx.slotcnt = bc->ch_params.slottime;
678 if ((random_num() % 256) > bc->ch_params.ppersist)
679 return;
682 if (bc->hdlctx.state == tx_idle && bc->hdlctx.bufcnt > 0) {
683 bc->hdlctx.state = tx_keyup;
684 bc->hdlctx.flags = tenms_to_flags(bc, bc->ch_params.tx_delay);
685 bc->ptt_keyed++;
687 while (cnt > 0) {
688 switch (bc->hdlctx.state) {
689 case tx_keyup:
690 i = min(cnt, bc->hdlctx.flags);
691 cnt -= i;
692 bc->hdlctx.flags -= i;
693 if (bc->hdlctx.flags <= 0)
694 bc->hdlctx.state = tx_data;
695 for (; i > 0; i--)
696 parport_epp_write_data(pp, 0x7e);
697 break;
699 case tx_data:
700 if (bc->hdlctx.bufcnt <= 0) {
701 encode_hdlc(bc);
702 if (bc->hdlctx.bufcnt <= 0) {
703 bc->hdlctx.state = tx_tail;
704 bc->hdlctx.flags = tenms_to_flags(bc, bc->ch_params.tx_tail);
705 break;
708 i = min(cnt, bc->hdlctx.bufcnt);
709 bc->hdlctx.bufcnt -= i;
710 cnt -= i;
711 for (; i > 0; i--)
712 parport_epp_write_data(pp, *(bc->hdlctx.bufptr)++);
713 break;
715 case tx_tail:
716 encode_hdlc(bc);
717 if (bc->hdlctx.bufcnt > 0) {
718 bc->hdlctx.state = tx_data;
719 break;
721 i = min(cnt, bc->hdlctx.flags);
722 if (i) {
723 cnt -= i;
724 bc->hdlctx.flags -= i;
725 for (; i > 0; i--)
726 parport_epp_write_data(pp, 0x7e);
727 break;
730 default: /* fall through */
731 if (bc->hdlctx.calibrate <= 0)
732 return;
733 i = min(cnt, bc->hdlctx.calibrate);
734 cnt -= i;
735 bc->hdlctx.calibrate -= i;
736 for (; i > 0; i--)
737 parport_epp_write_data(pp, 0);
738 break;
743 /* ---------------------------------------------------------------------- */
745 static void do_rxpacket(struct device *dev)
747 struct baycom_state *bc = (struct baycom_state *)dev->priv;
748 struct sk_buff *skb;
749 unsigned char *cp;
750 unsigned pktlen;
752 if (bc->hdlcrx.bufcnt < 4)
753 return;
754 if (!check_crc_ccitt(bc->hdlcrx.buf, bc->hdlcrx.bufcnt))
755 return;
756 pktlen = bc->hdlcrx.bufcnt-2+1; /* KISS kludge */
757 if (!(skb = dev_alloc_skb(pktlen))) {
758 printk("%s: memory squeeze, dropping packet\n", bc->ifname);
759 bc->stats.rx_dropped++;
760 return;
762 skb->dev = dev;
763 cp = skb_put(skb, pktlen);
764 *cp++ = 0; /* KISS kludge */
765 memcpy(cp, bc->hdlcrx.buf, pktlen - 1);
766 skb->protocol = htons(ETH_P_AX25);
767 skb->mac.raw = skb->data;
768 netif_rx(skb);
769 bc->stats.rx_packets++;
772 #define DECODEITERA(j) \
773 ({ \
774 if (!(notbitstream & (0x0fc << j))) /* flag or abort */ \
775 goto flgabrt##j; \
776 if ((bitstream & (0x1f8 << j)) == (0xf8 << j)) /* stuffed bit */ \
777 goto stuff##j; \
778 enditer##j: \
781 #define DECODEITERB(j) \
782 ({ \
783 flgabrt##j: \
784 if (!(notbitstream & (0x1fc << j))) { /* abort received */ \
785 state = 0; \
786 goto enditer##j; \
788 if ((bitstream & (0x1fe << j)) != (0x0fc << j)) /* flag received */ \
789 goto enditer##j; \
790 if (state) \
791 do_rxpacket(dev); \
792 bc->hdlcrx.bufcnt = 0; \
793 bc->hdlcrx.bufptr = bc->hdlcrx.buf; \
794 state = 1; \
795 numbits = 7-j; \
796 goto enditer##j; \
797 stuff##j: \
798 numbits--; \
799 bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); \
800 goto enditer##j; \
803 static void receive(struct device *dev, int cnt)
805 struct baycom_state *bc = (struct baycom_state *)dev->priv;
806 struct parport *pp = bc->pdev->port;
807 unsigned int bitbuf, notbitstream, bitstream, numbits, state;
808 unsigned char ch;
810 numbits = bc->hdlcrx.numbits;
811 state = bc->hdlcrx.state;
812 bitstream = bc->hdlcrx.bitstream;
813 bitbuf = bc->hdlcrx.bitbuf;
814 for (; cnt > 0; cnt--) {
815 ch = parport_epp_read_data(pp);
816 bitstream >>= 8;
817 bitstream |= ch << 8;
818 bitbuf >>= 8;
819 bitbuf |= ch << 8;
820 numbits += 8;
821 notbitstream = ~bitstream;
822 DECODEITERA(0);
823 DECODEITERA(1);
824 DECODEITERA(2);
825 DECODEITERA(3);
826 DECODEITERA(4);
827 DECODEITERA(5);
828 DECODEITERA(6);
829 DECODEITERA(7);
830 goto enddec;
831 DECODEITERB(0);
832 DECODEITERB(1);
833 DECODEITERB(2);
834 DECODEITERB(3);
835 DECODEITERB(4);
836 DECODEITERB(5);
837 DECODEITERB(6);
838 DECODEITERB(7);
839 enddec:
840 while (state && numbits >= 8) {
841 if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) {
842 state = 0;
843 } else {
844 *(bc->hdlcrx.bufptr)++ = bitbuf >> (16-numbits);
845 bc->hdlcrx.bufcnt++;
846 numbits -= 8;
850 bc->hdlcrx.numbits = numbits;
851 bc->hdlcrx.state = state;
852 bc->hdlcrx.bitstream = bitstream;
853 bc->hdlcrx.bitbuf = bitbuf;
856 /* --------------------------------------------------------------------- */
858 #ifdef __i386__
859 #define GETTICK(x) \
860 ({ \
861 if (current_cpu_data.x86_capability & X86_FEATURE_TSC) \
862 __asm__ __volatile__("rdtsc" : "=a" (x) : : "dx");\
864 #else /* __i386__ */
865 #define GETTICK(x)
866 #endif /* __i386__ */
868 static void epp_bh(struct device *dev)
870 struct baycom_state *bc;
871 struct parport *pp;
872 unsigned char stat;
873 unsigned int time1 = 0, time2 = 0, time3 = 0;
874 int cnt, cnt2;
876 baycom_paranoia_check_void(dev, "epp_bh");
877 bc = (struct baycom_state *)dev->priv;
878 if (!bc->bh_running)
879 return;
880 baycom_int_freq(bc);
881 pp = bc->pdev->port;
882 /* update status */
883 bc->stat = stat = parport_epp_read_addr(pp);
884 bc->debug_vals.last_pllcorr = stat;
885 GETTICK(time1);
886 if (bc->modem == EPP_FPGAEXTSTATUS) {
887 /* get input count */
888 parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE|1);
889 cnt = parport_epp_read_addr(pp);
890 cnt |= parport_epp_read_addr(pp) << 8;
891 cnt &= 0x7fff;
892 /* get output count */
893 parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE|2);
894 cnt2 = parport_epp_read_addr(pp);
895 cnt2 |= parport_epp_read_addr(pp) << 8;
896 cnt2 = 16384 - (cnt2 & 0x7fff);
897 /* return to normal */
898 parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE);
899 transmit(bc, cnt2, stat);
900 GETTICK(time2);
901 receive(dev, cnt);
902 bc->stat = stat = parport_epp_read_addr(pp);
903 } else {
904 /* try to tx */
905 switch (stat & (EPP_NTAEF|EPP_NTHF)) {
906 case EPP_NTHF:
907 cnt = 2048 - 256;
908 break;
910 case EPP_NTAEF:
911 cnt = 2048 - 1793;
912 break;
914 case 0:
915 cnt = 0;
916 break;
918 default:
919 cnt = 2048 - 1025;
920 break;
922 transmit(bc, cnt, stat);
923 GETTICK(time2);
924 /* do receiver */
925 while ((stat & (EPP_NRAEF|EPP_NRHF)) != EPP_NRHF) {
926 switch (stat & (EPP_NRAEF|EPP_NRHF)) {
927 case EPP_NRAEF:
928 cnt = 1025;
929 break;
931 case 0:
932 cnt = 1793;
933 break;
935 default:
936 cnt = 256;
937 break;
939 receive(dev, cnt);
940 stat = parport_epp_read_addr(pp);
941 if (parport_epp_check_timeout(pp))
942 goto epptimeout;
944 cnt = 0;
945 if (bc->bitrate < 50000)
946 cnt = 256;
947 else if (bc->bitrate < 100000)
948 cnt = 128;
949 while (cnt > 0 && stat & EPP_NREF) {
950 receive(dev, 1);
951 cnt--;
952 stat = parport_epp_read_addr(pp);
955 GETTICK(time3);
956 #ifdef BAYCOM_DEBUG
957 bc->debug_vals.mod_cycles = time2 - time1;
958 bc->debug_vals.demod_cycles = time3 - time2;
959 #endif /* BAYCOM_DEBUG */
960 if (parport_epp_check_timeout(pp))
961 goto epptimeout;
962 queue_task(&bc->run_bh, &tq_timer);
963 return;
964 epptimeout:
965 printk(KERN_ERR "%s: EPP timeout!\n", bc_drvname);
968 /* ---------------------------------------------------------------------- */
970 * ===================== network driver interface =========================
973 static int baycom_send_packet(struct sk_buff *skb, struct device *dev)
975 struct baycom_state *bc;
977 baycom_paranoia_check(dev, "baycom_send_packet", 0);
978 bc = (struct baycom_state *)dev->priv;
979 skb_queue_tail(&bc->send_queue, skb);
980 dev->trans_start = jiffies;
981 return 0;
984 /* --------------------------------------------------------------------- */
986 static int baycom_set_mac_address(struct device *dev, void *addr)
988 struct sockaddr *sa = (struct sockaddr *)addr;
990 /* addr is an AX.25 shifted ASCII mac address */
991 memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
992 return 0;
995 /* --------------------------------------------------------------------- */
997 static struct net_device_stats *baycom_get_stats(struct device *dev)
999 struct baycom_state *bc;
1001 baycom_paranoia_check(dev, "baycom_get_stats", NULL);
1002 bc = (struct baycom_state *)dev->priv;
1004 * Get the current statistics. This may be called with the
1005 * card open or closed.
1007 return &bc->stats;
1010 /* --------------------------------------------------------------------- */
1012 static void epp_wakeup(void *handle)
1014 struct device *dev = (struct device *)handle;
1015 struct baycom_state *bc;
1017 baycom_paranoia_check_void(dev, "epp_wakeup");
1018 bc = (struct baycom_state *)dev->priv;
1019 printk(KERN_DEBUG "baycom_epp: %s: why am I being woken up?\n", dev->name);
1020 if (!parport_claim(bc->pdev))
1021 printk(KERN_DEBUG "baycom_epp: %s: I'm broken.\n", dev->name);
1024 /* --------------------------------------------------------------------- */
1027 * Open/initialize the board. This is called (in the current kernel)
1028 * sometime after booting when the 'ifconfig' program is run.
1030 * This routine should set everything up anew at each open, even
1031 * registers that "should" only need to be set once at boot, so that
1032 * there is non-reboot way to recover if something goes wrong.
1035 static int epp_open(struct device *dev)
1037 struct baycom_state *bc;
1038 struct parport *pp;
1039 const struct tq_struct run_bh = {
1040 0, 0, (void *)(void *)epp_bh, dev
1042 unsigned int i, j;
1043 unsigned char stat;
1044 unsigned long tstart;
1046 baycom_paranoia_check(dev, "epp_open", -ENXIO);
1047 bc = (struct baycom_state *)dev->priv;
1048 if (dev->start)
1049 return 0;
1050 pp = parport_enumerate();
1051 while (pp && pp->base != dev->base_addr)
1052 pp = pp->next;
1053 if (!pp) {
1054 printk(KERN_ERR "%s: parport at 0x%lx unknown\n", bc_drvname, dev->base_addr);
1055 return -ENXIO;
1057 #if 0
1058 if (pp->irq < 0) {
1059 printk(KERN_ERR "%s: parport at 0x%lx has no irq\n", bc_drvname, pp->base);
1060 return -ENXIO;
1062 #endif
1063 memset(&bc->modem, 0, sizeof(bc->modem));
1064 if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, epp_wakeup,
1065 epp_interrupt, PARPORT_DEV_EXCL, dev))) {
1066 printk(KERN_ERR "%s: cannot register parport at 0x%lx\n", bc_drvname, pp->base);
1067 return -ENXIO;
1069 if (parport_claim(bc->pdev)) {
1070 printk(KERN_ERR "%s: parport at 0x%lx busy\n", bc_drvname, pp->base);
1071 parport_unregister_device(bc->pdev);
1072 return -EBUSY;
1074 if (!(pp->modes & (PARPORT_MODE_PCECPEPP|PARPORT_MODE_PCEPP))) {
1075 printk(KERN_ERR "%s: parport at 0x%lx does not support any EPP mode\n",
1076 bc_drvname, pp->base);
1077 parport_release(bc->pdev);
1078 parport_unregister_device(bc->pdev);
1079 return -EIO;
1081 dev->irq = /*pp->irq*/ 0;
1082 bc->run_bh = run_bh;
1083 bc->bh_running = 1;
1084 if (pp->modes & PARPORT_MODE_PCECPEPP) {
1085 printk(KERN_INFO "%s: trying to enable EPP mode\n", bc_drvname);
1086 parport_frob_econtrol(pp, 0xe0, 0x80);
1088 /* bc->pdev->port->ops->change_mode(bc->pdev->port, PARPORT_MODE_PCEPP); not yet implemented */
1089 bc->modem = EPP_CONVENTIONAL;
1090 if (eppconfig(bc))
1091 printk(KERN_INFO "%s: no FPGA detected, assuming conventional EPP modem\n", bc_drvname);
1092 else
1093 bc->modem = /*EPP_FPGA*/ EPP_FPGAEXTSTATUS;
1094 parport_write_control(pp, LPTCTRL_PROGRAM); /* prepare EPP mode; we aren't using interrupts */
1095 /* reset the modem */
1096 parport_epp_write_addr(pp, 0);
1097 parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE);
1098 /* autoprobe baud rate */
1099 tstart = jiffies;
1100 i = 0;
1101 while ((signed)(jiffies-tstart-HZ/3) < 0) {
1102 stat = parport_epp_read_addr(pp);
1103 if ((stat & (EPP_NRAEF|EPP_NRHF)) == EPP_NRHF) {
1104 schedule();
1105 continue;
1107 for (j = 0; j < 256; j++)
1108 parport_epp_read_data(pp);
1109 i += 256;
1111 for (j = 0; j < 256; j++) {
1112 stat = parport_epp_read_addr(pp);
1113 if (!(stat & EPP_NREF))
1114 break;
1115 parport_epp_read_data(pp);
1116 i++;
1118 tstart = jiffies - tstart;
1119 bc->bitrate = i * (8 * HZ) / tstart;
1120 j = 1;
1121 i = bc->bitrate >> 3;
1122 while (j < 7 && i > 150) {
1123 j++;
1124 i >>= 1;
1126 printk(KERN_INFO "%s: autoprobed bitrate: %d int divider: %d int rate: %d\n",
1127 bc_drvname, bc->bitrate, j, bc->bitrate >> (j+2));
1128 parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE/*|j*/);
1130 * initialise hdlc variables
1132 bc->hdlcrx.state = 0;
1133 bc->hdlcrx.numbits = 0;
1134 bc->hdlctx.state = tx_idle;
1135 bc->hdlctx.bufcnt = 0;
1136 bc->hdlctx.slotcnt = bc->ch_params.slottime;
1137 bc->hdlctx.calibrate = 0;
1138 dev->start = 1;
1139 dev->tbusy = 0;
1140 dev->interrupt = 0;
1141 /* start the bottom half stuff */
1142 queue_task(&bc->run_bh, &tq_timer);
1143 MOD_INC_USE_COUNT;
1144 return 0;
1146 #if 0
1147 errreturn:
1148 parport_release(bc->pdev);
1149 parport_unregister_device(bc->pdev);
1150 return -EIO;
1151 #endif
1154 /* --------------------------------------------------------------------- */
1156 static int epp_close(struct device *dev)
1158 struct baycom_state *bc;
1159 struct parport *pp;
1160 struct sk_buff *skb;
1162 baycom_paranoia_check(dev, "epp_close", -EINVAL);
1163 if (!dev->start)
1164 return 0;
1165 bc = (struct baycom_state *)dev->priv;
1166 pp = bc->pdev->port;
1167 bc->bh_running = 0;
1168 dev->start = 0;
1169 dev->tbusy = 1;
1170 run_task_queue(&tq_timer); /* dequeue bottom half */
1171 bc->stat = EPP_DCDBIT;
1172 parport_epp_write_addr(pp, 0);
1173 parport_write_control(pp, 0); /* reset the adapter */
1174 parport_release(bc->pdev);
1175 parport_unregister_device(bc->pdev);
1176 /* Free any buffers left in the hardware transmit queue */
1177 while ((skb = skb_dequeue(&bc->send_queue)))
1178 dev_kfree_skb(skb);
1179 printk(KERN_INFO "%s: close epp at iobase 0x%lx irq %u\n",
1180 bc_drvname, dev->base_addr, dev->irq);
1181 MOD_DEC_USE_COUNT;
1182 return 0;
1185 /* --------------------------------------------------------------------- */
1187 static int baycom_setmode(struct baycom_state *bc, const char *modestr)
1189 const char *cp;
1191 if (strstr(modestr,"intclk"))
1192 bc->cfg.intclk = 1;
1193 if (strstr(modestr,"extclk"))
1194 bc->cfg.intclk = 0;
1195 if (strstr(modestr,"intmodem"))
1196 bc->cfg.extmodem = 0;
1197 if (strstr(modestr,"extmodem"))
1198 bc->cfg.extmodem = 1;
1199 if (strstr(modestr,"noloopback"))
1200 bc->cfg.loopback = 0;
1201 if (strstr(modestr,"loopback"))
1202 bc->cfg.loopback = 1;
1203 if ((cp = strstr(modestr,"divider="))) {
1204 bc->cfg.divider = simple_strtoul(cp+8, NULL, 0);
1205 if (bc->cfg.divider < 1)
1206 bc->cfg.divider = 1;
1207 if (bc->cfg.divider > 1023)
1208 bc->cfg.divider = 1023;
1210 return 0;
1213 /* --------------------------------------------------------------------- */
1215 static int baycom_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
1217 struct baycom_state *bc;
1218 struct baycom_ioctl bi;
1219 struct hdlcdrv_ioctl hi;
1220 struct sm_ioctl si;
1222 baycom_paranoia_check(dev, "baycom_ioctl", -EINVAL);
1223 bc = (struct baycom_state *)dev->priv;
1224 if (cmd != SIOCDEVPRIVATE)
1225 return -ENOIOCTLCMD;
1226 if (get_user(cmd, (int *)ifr->ifr_data))
1227 return -EFAULT;
1228 #ifdef BAYCOM_DEBUG
1229 if (cmd == BAYCOMCTL_GETDEBUG) {
1230 bi.data.dbg.debug1 = bc->ptt_keyed;
1231 bi.data.dbg.debug2 = bc->debug_vals.last_intcnt;
1232 bi.data.dbg.debug3 = bc->debug_vals.last_pllcorr;
1233 bc->debug_vals.last_intcnt = 0;
1234 if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
1235 return -EFAULT;
1236 return 0;
1238 if (cmd == SMCTL_GETDEBUG) {
1239 si.data.dbg.int_rate = bc->debug_vals.last_intcnt;
1240 si.data.dbg.mod_cycles = bc->debug_vals.mod_cycles;
1241 si.data.dbg.demod_cycles = bc->debug_vals.demod_cycles;
1242 si.data.dbg.dma_residue = 0;
1243 bc->debug_vals.mod_cycles = bc->debug_vals.demod_cycles = 0;
1244 bc->debug_vals.last_intcnt = 0;
1245 if (copy_to_user(ifr->ifr_data, &si, sizeof(si)))
1246 return -EFAULT;
1247 return 0;
1249 #endif /* BAYCOM_DEBUG */
1251 if (copy_from_user(&hi, ifr->ifr_data, sizeof(hi)))
1252 return -EFAULT;
1253 switch (hi.cmd) {
1254 default:
1255 return -ENOIOCTLCMD;
1257 case HDLCDRVCTL_GETCHANNELPAR:
1258 hi.data.cp.tx_delay = bc->ch_params.tx_delay;
1259 hi.data.cp.tx_tail = bc->ch_params.tx_tail;
1260 hi.data.cp.slottime = bc->ch_params.slottime;
1261 hi.data.cp.ppersist = bc->ch_params.ppersist;
1262 hi.data.cp.fulldup = bc->ch_params.fulldup;
1263 break;
1265 case HDLCDRVCTL_SETCHANNELPAR:
1266 if (!suser())
1267 return -EACCES;
1268 bc->ch_params.tx_delay = hi.data.cp.tx_delay;
1269 bc->ch_params.tx_tail = hi.data.cp.tx_tail;
1270 bc->ch_params.slottime = hi.data.cp.slottime;
1271 bc->ch_params.ppersist = hi.data.cp.ppersist;
1272 bc->ch_params.fulldup = hi.data.cp.fulldup;
1273 bc->hdlctx.slotcnt = 1;
1274 return 0;
1276 case HDLCDRVCTL_GETMODEMPAR:
1277 hi.data.mp.iobase = dev->base_addr;
1278 hi.data.mp.irq = dev->irq;
1279 hi.data.mp.dma = dev->dma;
1280 hi.data.mp.dma2 = 0;
1281 hi.data.mp.seriobase = 0;
1282 hi.data.mp.pariobase = 0;
1283 hi.data.mp.midiiobase = 0;
1284 break;
1286 case HDLCDRVCTL_SETMODEMPAR:
1287 if ((!suser()) || dev->start)
1288 return -EACCES;
1289 dev->base_addr = hi.data.mp.iobase;
1290 dev->irq = /*hi.data.mp.irq*/0;
1291 dev->dma = /*hi.data.mp.dma*/0;
1292 return 0;
1294 case HDLCDRVCTL_GETSTAT:
1295 hi.data.cs.ptt = !!(bc->stat & EPP_PTTBIT);
1296 hi.data.cs.dcd = !(bc->stat & EPP_DCDBIT);
1297 hi.data.cs.ptt_keyed = bc->ptt_keyed;
1298 hi.data.cs.tx_packets = bc->stats.tx_packets;
1299 hi.data.cs.tx_errors = bc->stats.tx_errors;
1300 hi.data.cs.rx_packets = bc->stats.rx_packets;
1301 hi.data.cs.rx_errors = bc->stats.rx_errors;
1302 break;
1304 case HDLCDRVCTL_OLDGETSTAT:
1305 hi.data.ocs.ptt = !!(bc->stat & EPP_PTTBIT);
1306 hi.data.ocs.dcd = !(bc->stat & EPP_DCDBIT);
1307 hi.data.ocs.ptt_keyed = bc->ptt_keyed;
1308 break;
1310 case HDLCDRVCTL_CALIBRATE:
1311 bc->hdlctx.calibrate = hi.data.calibrate * bc->bitrate / 8;
1312 return 0;
1314 case HDLCDRVCTL_DRIVERNAME:
1315 strncpy(hi.data.drivername, "baycom_epp", sizeof(hi.data.drivername));
1316 break;
1318 case HDLCDRVCTL_GETMODE:
1319 sprintf(hi.data.modename, "%sclk,%smodem,divider=%d%s",
1320 bc->cfg.intclk ? "int" : "ext",
1321 bc->cfg.extmodem ? "ext" : "int", bc->cfg.divider,
1322 bc->cfg.loopback ? ",loopback" : "");
1323 break;
1325 case HDLCDRVCTL_SETMODE:
1326 if (!suser() || dev->start)
1327 return -EACCES;
1328 hi.data.modename[sizeof(hi.data.modename)-1] = '\0';
1329 return baycom_setmode(bc, hi.data.modename);
1331 case HDLCDRVCTL_MODELIST:
1332 strncpy(hi.data.modename, "intclk,extclk,intmodem,extmodem,divider=x",
1333 sizeof(hi.data.modename));
1334 break;
1336 case HDLCDRVCTL_MODEMPARMASK:
1337 return HDLCDRV_PARMASK_IOBASE;
1340 if (copy_to_user(ifr->ifr_data, &hi, sizeof(hi)))
1341 return -EFAULT;
1342 return 0;
1345 /* --------------------------------------------------------------------- */
1348 * Check for a network adaptor of this type, and return '0' if one exists.
1349 * If dev->base_addr == 0, probe all likely locations.
1350 * If dev->base_addr == 1, always return failure.
1351 * If dev->base_addr == 2, allocate space for the device and return success
1352 * (detachable devices only).
1354 static int baycom_probe(struct device *dev)
1356 static char ax25_bcast[AX25_ADDR_LEN] = {
1357 'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1
1359 static char ax25_nocall[AX25_ADDR_LEN] = {
1360 'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1
1362 const struct hdlcdrv_channel_params dflt_ch_params = {
1363 20, 2, 10, 40, 0
1365 struct baycom_state *bc;
1367 if (!dev)
1368 return -ENXIO;
1369 baycom_paranoia_check(dev, "baycom_probe", -ENXIO);
1371 * not a real probe! only initialize data structures
1373 bc = (struct baycom_state *)dev->priv;
1375 * initialize the baycom_state struct
1377 bc->ch_params = dflt_ch_params;
1378 bc->ptt_keyed = 0;
1381 * initialize the device struct
1383 dev->open = epp_open;
1384 dev->stop = epp_close;
1385 dev->do_ioctl = baycom_ioctl;
1386 dev->hard_start_xmit = baycom_send_packet;
1387 dev->get_stats = baycom_get_stats;
1389 /* Fill in the fields of the device structure */
1390 dev_init_buffers(dev);
1392 skb_queue_head_init(&bc->send_queue);
1394 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
1395 dev->hard_header = ax25_encapsulate;
1396 dev->rebuild_header = ax25_rebuild_header;
1397 #else /* CONFIG_AX25 || CONFIG_AX25_MODULE */
1398 dev->hard_header = NULL;
1399 dev->rebuild_header = NULL;
1400 #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
1401 dev->set_mac_address = baycom_set_mac_address;
1403 dev->type = ARPHRD_AX25; /* AF_AX25 device */
1404 dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
1405 dev->mtu = AX25_DEF_PACLEN; /* eth_mtu is the default */
1406 dev->addr_len = AX25_ADDR_LEN; /* sizeof an ax.25 address */
1407 memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
1408 memcpy(dev->dev_addr, ax25_nocall, AX25_ADDR_LEN);
1410 /* New style flags */
1411 dev->flags = 0;
1413 return 0;
1416 /* --------------------------------------------------------------------- */
1418 __initfunc(int baycom_epp_init(void))
1420 struct device *dev;
1421 int i, found = 0;
1422 char set_hw = 1;
1423 struct baycom_state *bc;
1425 printk(bc_drvinfo);
1427 * register net devices
1429 for (i = 0; i < NR_PORTS; i++) {
1430 dev = baycom_device+i;
1431 if (!baycom_ports[i].mode)
1432 set_hw = 0;
1433 if (!set_hw)
1434 baycom_ports[i].iobase = 0;
1435 memset(dev, 0, sizeof(struct device));
1436 if (!(bc = dev->priv = kmalloc(sizeof(struct baycom_state), GFP_KERNEL)))
1437 return -ENOMEM;
1439 * initialize part of the baycom_state struct
1441 memset(bc, 0, sizeof(struct baycom_state));
1442 bc->magic = BAYCOM_MAGIC;
1443 sprintf(bc->ifname, "bce%d", i);
1445 * initialize part of the device struct
1447 dev->name = bc->ifname;
1448 dev->if_port = 0;
1449 dev->init = baycom_probe;
1450 dev->start = 0;
1451 dev->tbusy = 1;
1452 dev->base_addr = baycom_ports[i].iobase;
1453 dev->irq = 0;
1454 dev->dma = 0;
1455 if (register_netdev(dev)) {
1456 printk(KERN_WARNING "%s: cannot register net device %s\n", bc_drvname, bc->ifname);
1457 kfree(dev->priv);
1458 return -ENXIO;
1460 if (set_hw && baycom_setmode(bc, baycom_ports[i].mode))
1461 set_hw = 0;
1462 found++;
1464 if (!found)
1465 return -ENXIO;
1466 return 0;
1469 /* --------------------------------------------------------------------- */
1471 #ifdef MODULE
1474 * command line settable parameters
1476 static const char *mode[NR_PORTS] = { "epp", };
1477 static int iobase[NR_PORTS] = { 0x378, };
1479 #if LINUX_VERSION_CODE >= 0x20115
1481 MODULE_PARM(mode, "s");
1482 MODULE_PARM_DESC(mode, "baycom operating mode; epp");
1483 MODULE_PARM(iobase, "i");
1484 MODULE_PARM_DESC(iobase, "baycom io base address");
1486 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
1487 MODULE_DESCRIPTION("Baycom epp amateur radio modem driver");
1489 #endif
1491 __initfunc(int init_module(void))
1493 int i;
1495 for (i = 0; (i < NR_PORTS) && (mode[i]); i++) {
1496 baycom_ports[i].mode = mode[i];
1497 baycom_ports[i].iobase = iobase[i];
1499 if (i < NR_PORTS-1)
1500 baycom_ports[i+1].mode = NULL;
1501 return baycom_epp_init();
1504 /* --------------------------------------------------------------------- */
1506 void cleanup_module(void)
1508 struct device *dev;
1509 struct baycom_state *bc;
1510 int i;
1512 for(i = 0; i < NR_PORTS; i++) {
1513 dev = baycom_device+i;
1514 bc = (struct baycom_state *)dev->priv;
1515 if (bc) {
1516 if (bc->magic == BAYCOM_MAGIC) {
1517 unregister_netdev(dev);
1518 kfree(dev->priv);
1519 } else
1520 printk(paranoia_str, "cleanup_module");
1525 #else /* MODULE */
1526 /* --------------------------------------------------------------------- */
1528 * format: baycom=io,mode
1529 * mode: epp
1532 __initfunc(void baycom_epp_setup(char *str, int *ints))
1534 int i;
1536 for (i = 0; (i < NR_PORTS) && (baycom_ports[i].mode); i++);
1537 if ((i >= NR_PORTS) || (ints[0] < 1)) {
1538 printk(KERN_INFO "%s: too many or invalid interface "
1539 "specifications\n", bc_drvname);
1540 return;
1542 baycom_ports[i].mode = str;
1543 baycom_ports[i].iobase = ints[1];
1544 if (i < NR_PORTS-1)
1545 baycom_ports[i+1].mode = NULL;
1548 #endif /* MODULE */
1549 /* --------------------------------------------------------------------- */