1 /*****************************************************************************/
4 * baycom_epp.c -- baycom epp radio modem driver.
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.
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>
48 #include <linux/string.h>
49 #include <linux/parport.h>
50 #include <linux/bitops.h>
51 #include <asm/system.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 */
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.
80 #include <linux/version.h>
82 #if LINUX_VERSION_CODE >= 0x20100
83 #include <asm/uaccess.h>
85 #include <asm/segment.h>
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
);
99 memcpy_fromfs(to
, from
, n
);
103 extern inline int copy_to_user(void *to
, const void *from
, unsigned long n
)
105 int i
= verify_area(VERIFY_WRITE
, to
, n
);
108 memcpy_tofs(to
, from
, n
);
113 #if LINUX_VERSION_CODE >= 0x20123
114 #include <linux/init.h>
118 #define __initfunc(x) x
121 /* --------------------------------------------------------------------- */
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) \
133 if (!dev || !dev->priv || ((struct baycom_state *)dev->priv)->magic != BAYCOM_MAGIC) { \
134 printk(paranoia_str, routine); \
139 #define baycom_paranoia_check_void(dev,routine) \
141 if (!dev || !dev->priv || ((struct baycom_state *)dev->priv)->magic != BAYCOM_MAGIC) { \
142 printk(paranoia_str, routine); \
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 /* --------------------------------------------------------------------- */
157 static struct device baycom_device
[NR_PORTS
];
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
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
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
{
256 struct pardevice
*pdev
;
257 unsigned int bh_running
;
258 struct tq_struct run_bh
;
260 unsigned int bitrate
;
263 char ifname
[HDLCDRV_IFNAMELEN
];
267 unsigned int divider
;
268 unsigned int extmodem
;
269 unsigned int loopback
;
272 struct hdlcdrv_channel_params ch_params
;
275 unsigned int bitbuf
, bitstream
, numbits
, state
;
276 unsigned char *bufptr
;
278 unsigned char buf
[TXBUFFER_SIZE
];
285 enum { tx_idle
= 0, tx_keyup
, tx_data
, tx_tail
} state
;
286 unsigned char *bufptr
;
288 unsigned char buf
[TXBUFFER_SIZE
];
291 struct net_device_stats stats
;
292 unsigned int ptt_keyed
;
293 struct sk_buff_head send_queue
; /* Packets awaiting transmission */
298 unsigned long last_jiffies
;
300 unsigned last_intcnt
;
303 unsigned int mod_cycles
;
304 unsigned int demod_cycles
;
306 #endif /* BAYCOM_DEBUG */
309 /* --------------------------------------------------------------------- */
311 #define min(a, b) (((a) < (b)) ? (a) : (b))
312 #define max(a, b) (((a) > (b)) ? (a) : (b))
314 /* --------------------------------------------------------------------- */
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
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 /*---------------------------------------------------------------------------*/
372 extern inline void append_crc_ccitt(unsigned char *buffer
, int len
)
374 unsigned int crc
= 0xffff;
377 crc
= (crc
>> 8) ^ crc_ccitt_table
[(crc
^ *buffer
++) & 0xff];
380 *buffer
++ = crc
>> 8;
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];
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
)
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
};
442 static int exec_eppfpga(void *b
)
444 struct baycom_state
*bc
= (struct baycom_state
*)b
;
447 char *argv
[] = { eppconfig_path
, "-s", "-p", portarg
, "-m", modearg
, NULL
};
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
])
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
);
472 /* eppconfig: called during ifconfig up to configure the modem */
474 static int eppconfig(struct baycom_state
*bc
)
479 pid
= kernel_thread(exec_eppfpga
, bc
, CLONE_FS
);
481 printk(KERN_ERR
"%s: fork failed, errno %d\n", bc_drvname
, -pid
);
485 set_fs(KERNEL_DS
); /* Allow i to be in kernel space. */
486 r
= waitpid(pid
, &i
, __WCLONE
);
489 printk(KERN_ERR
"%s: waitpid(%d) failed, returning %d\n",
493 printk(KERN_DEBUG
"%s: eppfpga returned %d\n", bc_drvname
, 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
)
510 #define PKP(a,b) printk(KERN_INFO "%s: channel params: " a "\n", bc->ifname, b)
511 #else /* KISS_VERBOSE */
513 #endif /* KISS_VERBOSE */
519 bc
->ch_params
.tx_delay
= data
[1];
520 PKP("TX delay = %ums", 10 * bc
->ch_params
.tx_delay
);
523 bc
->ch_params
.ppersist
= data
[1];
524 PKP("p persistence = %u", bc
->ch_params
.ppersist
);
527 bc
->ch_params
.slottime
= data
[1];
528 PKP("slot time = %ums", bc
->ch_params
.slottime
);
531 bc
->ch_params
.tx_tail
= data
[1];
532 PKP("TX tail = %ums", bc
->ch_params
.tx_tail
);
535 bc
->ch_params
.fulldup
= !!data
[1];
536 PKP("%s duplex", bc
->ch_params
.fulldup
? "full" : "half");
544 /* --------------------------------------------------------------------- */
546 * high performance HDLC encoder
547 * yes, it's ugly, but generates pretty good code
550 #define ENCODEITERA(j) \
552 if (!(notbitstream & (0x1f0 << j))) \
557 #define ENCODEITERB(j) \
560 bitstream &= ~(0x100 << j); \
561 bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | \
562 ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); \
564 notbitstream = ~bitstream; \
569 static void encode_hdlc(struct baycom_state
*bc
)
572 unsigned char *wp
, *bp
;
574 unsigned bitstream
, notbitstream
, bitbuf
, numbit
, crc
;
575 unsigned char crcarr
[2];
577 if (bc
->hdlctx
.bufcnt
> 0)
579 while ((skb
= skb_dequeue(&bc
->send_queue
))) {
580 if (skb
->data
[0] != 0) {
581 do_kiss_params(bc
, skb
->data
, skb
->len
);
585 pkt_len
= skb
->len
-1; /* strip KISS byte */
586 if (pkt_len
>= HDLCDRV_MAXFLEN
|| pkt_len
< 2) {
592 crc
= calc_crc_ccitt(bp
, pkt_len
);
594 crcarr
[1] = crc
>> 8;
596 bitstream
= bitbuf
= numbit
= 0;
597 while (pkt_len
> -2) {
599 bitstream
|= ((unsigned int)*bp
) << 8;
600 bitbuf
|= ((unsigned int)*bp
) << numbit
;
601 notbitstream
= ~bitstream
;
625 while (numbit
>= 8) {
631 bitbuf
|= 0x7e7e << numbit
;
633 while (numbit
>= 8) {
638 bc
->hdlctx
.bufptr
= bc
->hdlctx
.buf
;
639 bc
->hdlctx
.bufcnt
= wp
- bc
->hdlctx
.buf
;
641 bc
->stats
.tx_packets
++;
646 /* ---------------------------------------------------------------------- */
648 static unsigned short random_seed
;
650 static inline unsigned short random_num(void)
652 random_seed
= 28629 * random_seed
+ 157;
656 /* ---------------------------------------------------------------------- */
658 static void transmit(struct baycom_state
*bc
, int cnt
, unsigned char stat
)
660 struct parport
*pp
= bc
->pdev
->port
;
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)
668 if (bc
->hdlctx
.bufcnt
<= 0)
670 if (!bc
->ch_params
.fulldup
) {
671 if (!(stat
& EPP_DCDBIT
)) {
672 bc
->hdlctx
.slotcnt
= bc
->ch_params
.slottime
;
675 if ((--bc
->hdlctx
.slotcnt
) > 0)
677 bc
->hdlctx
.slotcnt
= bc
->ch_params
.slottime
;
678 if ((random_num() % 256) > bc
->ch_params
.ppersist
)
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
);
688 switch (bc
->hdlctx
.state
) {
690 i
= min(cnt
, bc
->hdlctx
.flags
);
692 bc
->hdlctx
.flags
-= i
;
693 if (bc
->hdlctx
.flags
<= 0)
694 bc
->hdlctx
.state
= tx_data
;
696 parport_epp_write_data(pp
, 0x7e);
700 if (bc
->hdlctx
.bufcnt
<= 0) {
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
);
708 i
= min(cnt
, bc
->hdlctx
.bufcnt
);
709 bc
->hdlctx
.bufcnt
-= i
;
712 parport_epp_write_data(pp
, *(bc
->hdlctx
.bufptr
)++);
717 if (bc
->hdlctx
.bufcnt
> 0) {
718 bc
->hdlctx
.state
= tx_data
;
721 i
= min(cnt
, bc
->hdlctx
.flags
);
724 bc
->hdlctx
.flags
-= i
;
726 parport_epp_write_data(pp
, 0x7e);
730 default: /* fall through */
731 if (bc
->hdlctx
.calibrate
<= 0)
733 i
= min(cnt
, bc
->hdlctx
.calibrate
);
735 bc
->hdlctx
.calibrate
-= i
;
737 parport_epp_write_data(pp
, 0);
743 /* ---------------------------------------------------------------------- */
745 static void do_rxpacket(struct device
*dev
)
747 struct baycom_state
*bc
= (struct baycom_state
*)dev
->priv
;
752 if (bc
->hdlcrx
.bufcnt
< 4)
754 if (!check_crc_ccitt(bc
->hdlcrx
.buf
, bc
->hdlcrx
.bufcnt
))
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
++;
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
;
769 bc
->stats
.rx_packets
++;
772 #define DECODEITERA(j) \
774 if (!(notbitstream & (0x0fc << j))) /* flag or abort */ \
776 if ((bitstream & (0x1f8 << j)) == (0xf8 << j)) /* stuffed bit */ \
781 #define DECODEITERB(j) \
784 if (!(notbitstream & (0x1fc << j))) { /* abort received */ \
788 if ((bitstream & (0x1fe << j)) != (0x0fc << j)) /* flag received */ \
792 bc->hdlcrx.bufcnt = 0; \
793 bc->hdlcrx.bufptr = bc->hdlcrx.buf; \
799 bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); \
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
;
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
);
817 bitstream
|= ch
<< 8;
821 notbitstream
= ~bitstream
;
840 while (state
&& numbits
>= 8) {
841 if (bc
->hdlcrx
.bufcnt
>= TXBUFFER_SIZE
) {
844 *(bc
->hdlcrx
.bufptr
)++ = bitbuf
>> (16-numbits
);
850 bc
->hdlcrx
.numbits
= numbits
;
851 bc
->hdlcrx
.state
= state
;
852 bc
->hdlcrx
.bitstream
= bitstream
;
853 bc
->hdlcrx
.bitbuf
= bitbuf
;
856 /* --------------------------------------------------------------------- */
861 if (current_cpu_data.x86_capability & X86_FEATURE_TSC) \
862 __asm__ __volatile__("rdtsc" : "=a" (x) : : "dx");\
866 #endif /* __i386__ */
868 static void epp_bh(struct device
*dev
)
870 struct baycom_state
*bc
;
873 unsigned int time1
= 0, time2
= 0, time3
= 0;
876 baycom_paranoia_check_void(dev
, "epp_bh");
877 bc
= (struct baycom_state
*)dev
->priv
;
883 bc
->stat
= stat
= parport_epp_read_addr(pp
);
884 bc
->debug_vals
.last_pllcorr
= stat
;
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;
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
);
902 bc
->stat
= stat
= parport_epp_read_addr(pp
);
905 switch (stat
& (EPP_NTAEF
|EPP_NTHF
)) {
922 transmit(bc
, cnt
, stat
);
925 while ((stat
& (EPP_NRAEF
|EPP_NRHF
)) != EPP_NRHF
) {
926 switch (stat
& (EPP_NRAEF
|EPP_NRHF
)) {
940 stat
= parport_epp_read_addr(pp
);
941 if (parport_epp_check_timeout(pp
))
945 if (bc
->bitrate
< 50000)
947 else if (bc
->bitrate
< 100000)
949 while (cnt
> 0 && stat
& EPP_NREF
) {
952 stat
= parport_epp_read_addr(pp
);
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
))
962 queue_task(&bc
->run_bh
, &tq_timer
);
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
;
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
);
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.
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
;
1039 const struct tq_struct run_bh
= {
1040 0, 0, (void *)(void *)epp_bh
, dev
1044 unsigned long tstart
;
1046 baycom_paranoia_check(dev
, "epp_open", -ENXIO
);
1047 bc
= (struct baycom_state
*)dev
->priv
;
1050 pp
= parport_enumerate();
1051 while (pp
&& pp
->base
!= dev
->base_addr
)
1054 printk(KERN_ERR
"%s: parport at 0x%lx unknown\n", bc_drvname
, dev
->base_addr
);
1059 printk(KERN_ERR
"%s: parport at 0x%lx has no irq\n", bc_drvname
, pp
->base
);
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
);
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
);
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
);
1081 dev
->irq
= /*pp->irq*/ 0;
1082 bc
->run_bh
= run_bh
;
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
;
1091 printk(KERN_INFO
"%s: no FPGA detected, assuming conventional EPP modem\n", bc_drvname
);
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 */
1101 while ((signed)(jiffies
-tstart
-HZ
/3) < 0) {
1102 stat
= parport_epp_read_addr(pp
);
1103 if ((stat
& (EPP_NRAEF
|EPP_NRHF
)) == EPP_NRHF
) {
1107 for (j
= 0; j
< 256; j
++)
1108 parport_epp_read_data(pp
);
1111 for (j
= 0; j
< 256; j
++) {
1112 stat
= parport_epp_read_addr(pp
);
1113 if (!(stat
& EPP_NREF
))
1115 parport_epp_read_data(pp
);
1118 tstart
= jiffies
- tstart
;
1119 bc
->bitrate
= i
* (8 * HZ
) / tstart
;
1121 i
= bc
->bitrate
>> 3;
1122 while (j
< 7 && i
> 150) {
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;
1141 /* start the bottom half stuff */
1142 queue_task(&bc
->run_bh
, &tq_timer
);
1148 parport_release(bc
->pdev
);
1149 parport_unregister_device(bc
->pdev
);
1154 /* --------------------------------------------------------------------- */
1156 static int epp_close(struct device
*dev
)
1158 struct baycom_state
*bc
;
1160 struct sk_buff
*skb
;
1162 baycom_paranoia_check(dev
, "epp_close", -EINVAL
);
1165 bc
= (struct baycom_state
*)dev
->priv
;
1166 pp
= bc
->pdev
->port
;
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
)))
1179 printk(KERN_INFO
"%s: close epp at iobase 0x%lx irq %u\n",
1180 bc_drvname
, dev
->base_addr
, dev
->irq
);
1185 /* --------------------------------------------------------------------- */
1187 static int baycom_setmode(struct baycom_state
*bc
, const char *modestr
)
1191 if (strstr(modestr
,"intclk"))
1193 if (strstr(modestr
,"extclk"))
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;
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
;
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
))
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
)))
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
)))
1249 #endif /* BAYCOM_DEBUG */
1251 if (copy_from_user(&hi
, ifr
->ifr_data
, sizeof(hi
)))
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
;
1265 case HDLCDRVCTL_SETCHANNELPAR
:
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;
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;
1286 case HDLCDRVCTL_SETMODEMPAR
:
1287 if ((!suser()) || dev
->start
)
1289 dev
->base_addr
= hi
.data
.mp
.iobase
;
1290 dev
->irq
= /*hi.data.mp.irq*/0;
1291 dev
->dma
= /*hi.data.mp.dma*/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
;
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
;
1310 case HDLCDRVCTL_CALIBRATE
:
1311 bc
->hdlctx
.calibrate
= hi
.data
.calibrate
* bc
->bitrate
/ 8;
1314 case HDLCDRVCTL_DRIVERNAME
:
1315 strncpy(hi
.data
.drivername
, "baycom_epp", sizeof(hi
.data
.drivername
));
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" : "");
1325 case HDLCDRVCTL_SETMODE
:
1326 if (!suser() || dev
->start
)
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
));
1336 case HDLCDRVCTL_MODEMPARMASK
:
1337 return HDLCDRV_PARMASK_IOBASE
;
1340 if (copy_to_user(ifr
->ifr_data
, &hi
, sizeof(hi
)))
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
= {
1365 struct baycom_state
*bc
;
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
;
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 */
1416 /* --------------------------------------------------------------------- */
1418 __initfunc(int baycom_epp_init(void))
1423 struct baycom_state
*bc
;
1427 * register net devices
1429 for (i
= 0; i
< NR_PORTS
; i
++) {
1430 dev
= baycom_device
+i
;
1431 if (!baycom_ports
[i
].mode
)
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
)))
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
;
1449 dev
->init
= baycom_probe
;
1452 dev
->base_addr
= baycom_ports
[i
].iobase
;
1455 if (register_netdev(dev
)) {
1456 printk(KERN_WARNING
"%s: cannot register net device %s\n", bc_drvname
, bc
->ifname
);
1460 if (set_hw
&& baycom_setmode(bc
, baycom_ports
[i
].mode
))
1469 /* --------------------------------------------------------------------- */
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");
1491 __initfunc(int init_module(void))
1495 for (i
= 0; (i
< NR_PORTS
) && (mode
[i
]); i
++) {
1496 baycom_ports
[i
].mode
= mode
[i
];
1497 baycom_ports
[i
].iobase
= iobase
[i
];
1500 baycom_ports
[i
+1].mode
= NULL
;
1501 return baycom_epp_init();
1504 /* --------------------------------------------------------------------- */
1506 void cleanup_module(void)
1509 struct baycom_state
*bc
;
1512 for(i
= 0; i
< NR_PORTS
; i
++) {
1513 dev
= baycom_device
+i
;
1514 bc
= (struct baycom_state
*)dev
->priv
;
1516 if (bc
->magic
== BAYCOM_MAGIC
) {
1517 unregister_netdev(dev
);
1520 printk(paranoia_str
, "cleanup_module");
1526 /* --------------------------------------------------------------------- */
1528 * format: baycom=io,mode
1532 __initfunc(void baycom_epp_setup(char *str
, int *ints
))
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
);
1542 baycom_ports
[i
].mode
= str
;
1543 baycom_ports
[i
].iobase
= ints
[1];
1545 baycom_ports
[i
+1].mode
= NULL
;
1549 /* --------------------------------------------------------------------- */