1 /*****************************************************************************/
4 * baycom_epp.c -- baycom epp radio modem driver.
6 * Copyright (C) 1998-2000
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.1998 Initial version by Matthias Welwarsky (dg2fef)
30 * 0.2 21.04.1998 Massive rework by Thomas Sailer
31 * Integrated FPGA EPP modem configuration routines
32 * 0.3 11.05.1998 Took FPGA config out and moved it into a separate program
33 * 0.4 26.07.1999 Adapted to new lowlevel parport driver interface
34 * 0.5 03.08.1999 adapt to Linus' new __setup/__initcall
35 * removed some pre-2.2 kernel compatibility cruft
36 * 0.6 10.08.1999 Check if parport can do SPP and is safe to access during interrupt contexts
37 * 0.7 12.02.2000 adapted to softnet driver interface
41 /*****************************************************************************/
43 #include <linux/config.h>
44 #include <linux/module.h>
45 #include <linux/kernel.h>
46 #include <linux/init.h>
47 #include <linux/string.h>
48 #include <linux/workqueue.h>
50 #include <linux/parport.h>
51 #include <linux/smp_lock.h>
52 #include <asm/uaccess.h>
53 #include <linux/if_arp.h>
54 #include <linux/kmod.h>
55 #include <linux/hdlcdrv.h>
56 #include <linux/baycom.h>
57 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
58 /* prototypes for ax25_encapsulate and ax25_rebuild_header */
60 #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
62 #define __KERNEL_SYSCALLS__
63 #include <linux/unistd.h>
65 /* --------------------------------------------------------------------- */
68 #define BAYCOM_MAGIC 19730510
70 /* --------------------------------------------------------------------- */
72 static const char paranoia_str
[] = KERN_ERR
73 "baycom_epp: bad magic number for hdlcdrv_state struct in routine %s\n";
75 #define baycom_paranoia_check(dev,routine,retval) \
77 if (!dev || !dev->priv || ((struct baycom_state *)dev->priv)->magic != BAYCOM_MAGIC) { \
78 printk(paranoia_str, routine); \
83 #define baycom_paranoia_check_void(dev,routine) \
85 if (!dev || !dev->priv || ((struct baycom_state *)dev->priv)->magic != BAYCOM_MAGIC) { \
86 printk(paranoia_str, routine); \
91 /* --------------------------------------------------------------------- */
93 static const char bc_drvname
[] = "baycom_epp";
94 static const char bc_drvinfo
[] = KERN_INFO
"baycom_epp: (C) 1998-2000 Thomas Sailer, HB9JNX/AE4WA\n"
95 KERN_INFO
"baycom_epp: version 0.7 compiled " __TIME__
" " __DATE__
"\n";
97 /* --------------------------------------------------------------------- */
101 static struct net_device baycom_device
[NR_PORTS
];
103 /* --------------------------------------------------------------------- */
105 /* EPP status register */
106 #define EPP_DCDBIT 0x80
107 #define EPP_PTTBIT 0x08
108 #define EPP_NREF 0x01
109 #define EPP_NRAEF 0x02
110 #define EPP_NRHF 0x04
111 #define EPP_NTHF 0x20
112 #define EPP_NTAEF 0x10
113 #define EPP_NTEF EPP_PTTBIT
115 /* EPP control register */
116 #define EPP_TX_FIFO_ENABLE 0x10
117 #define EPP_RX_FIFO_ENABLE 0x08
118 #define EPP_MODEM_ENABLE 0x20
119 #define EPP_LEDS 0xC0
120 #define EPP_IRQ_ENABLE 0x10
123 #define LPTREG_ECONTROL 0x402
124 #define LPTREG_CONFIGB 0x401
125 #define LPTREG_CONFIGA 0x400
126 #define LPTREG_EPPDATA 0x004
127 #define LPTREG_EPPADDR 0x003
128 #define LPTREG_CONTROL 0x002
129 #define LPTREG_STATUS 0x001
130 #define LPTREG_DATA 0x000
132 /* LPT control register */
133 #define LPTCTRL_PROGRAM 0x04 /* 0 to reprogram */
134 #define LPTCTRL_WRITE 0x01
135 #define LPTCTRL_ADDRSTB 0x08
136 #define LPTCTRL_DATASTB 0x02
137 #define LPTCTRL_INTEN 0x10
139 /* LPT status register */
140 #define LPTSTAT_SHIFT_NINTR 6
141 #define LPTSTAT_WAIT 0x80
142 #define LPTSTAT_NINTR (1<<LPTSTAT_SHIFT_NINTR)
143 #define LPTSTAT_PE 0x20
144 #define LPTSTAT_DONE 0x10
145 #define LPTSTAT_NERROR 0x08
146 #define LPTSTAT_EPPTIMEOUT 0x01
148 /* LPT data register */
149 #define LPTDATA_SHIFT_TDI 0
150 #define LPTDATA_SHIFT_TMS 2
151 #define LPTDATA_TDI (1<<LPTDATA_SHIFT_TDI)
152 #define LPTDATA_TCK 0x02
153 #define LPTDATA_TMS (1<<LPTDATA_SHIFT_TMS)
154 #define LPTDATA_INITBIAS 0x80
157 /* EPP modem config/status bits */
158 #define EPP_DCDBIT 0x80
159 #define EPP_PTTBIT 0x08
160 #define EPP_RXEBIT 0x01
161 #define EPP_RXAEBIT 0x02
162 #define EPP_RXHFULL 0x04
164 #define EPP_NTHF 0x20
165 #define EPP_NTAEF 0x10
166 #define EPP_NTEF EPP_PTTBIT
168 #define EPP_TX_FIFO_ENABLE 0x10
169 #define EPP_RX_FIFO_ENABLE 0x08
170 #define EPP_MODEM_ENABLE 0x20
171 #define EPP_LEDS 0xC0
172 #define EPP_IRQ_ENABLE 0x10
174 /* Xilinx 4k JTAG instructions */
175 #define XC4K_IRLENGTH 3
176 #define XC4K_EXTEST 0
177 #define XC4K_PRELOAD 1
178 #define XC4K_CONFIGURE 5
179 #define XC4K_BYPASS 7
181 #define EPP_CONVENTIONAL 0
183 #define EPP_FPGAEXTSTATUS 2
185 #define TXBUFFER_SIZE ((HDLCDRV_MAXFLEN*6/5)+8)
187 /* ---------------------------------------------------------------------- */
189 * Information that need to be kept for each board.
192 struct baycom_state
{
195 struct pardevice
*pdev
;
196 unsigned int work_running
;
197 struct work_struct run_work
;
199 unsigned int bitrate
;
206 unsigned int extmodem
;
207 unsigned int loopback
;
210 struct hdlcdrv_channel_params ch_params
;
213 unsigned int bitbuf
, bitstream
, numbits
, state
;
214 unsigned char *bufptr
;
216 unsigned char buf
[TXBUFFER_SIZE
];
223 enum { tx_idle
= 0, tx_keyup
, tx_data
, tx_tail
} state
;
224 unsigned char *bufptr
;
226 unsigned char buf
[TXBUFFER_SIZE
];
229 struct net_device_stats stats
;
230 unsigned int ptt_keyed
;
231 struct sk_buff
*skb
; /* next transmit packet */
235 unsigned long last_jiffies
;
237 unsigned last_intcnt
;
240 unsigned int mod_cycles
;
241 unsigned int demod_cycles
;
243 #endif /* BAYCOM_DEBUG */
246 /* --------------------------------------------------------------------- */
250 /* --------------------------------------------------------------------- */
252 #define PARAM_TXDELAY 1
253 #define PARAM_PERSIST 2
254 #define PARAM_SLOTTIME 3
255 #define PARAM_TXTAIL 4
256 #define PARAM_FULLDUP 5
257 #define PARAM_HARDWARE 6
258 #define PARAM_RETURN 255
260 /* --------------------------------------------------------------------- */
262 * the CRC routines are stolen from WAMPES
266 static const unsigned short crc_ccitt_table
[] = {
267 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
268 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
269 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
270 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
271 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
272 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
273 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
274 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
275 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
276 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
277 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
278 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
279 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
280 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
281 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
282 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
283 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
284 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
285 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
286 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
287 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
288 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
289 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
290 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
291 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
292 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
293 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
294 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
295 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
296 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
297 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
298 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
301 /*---------------------------------------------------------------------------*/
304 static inline void append_crc_ccitt(unsigned char *buffer
, int len
)
306 unsigned int crc
= 0xffff;
309 crc
= (crc
>> 8) ^ crc_ccitt_table
[(crc
^ *buffer
++) & 0xff];
312 *buffer
++ = crc
>> 8;
316 /*---------------------------------------------------------------------------*/
318 static inline int check_crc_ccitt(const unsigned char *buf
, int cnt
)
320 unsigned int crc
= 0xffff;
322 for (; cnt
> 0; cnt
--)
323 crc
= (crc
>> 8) ^ crc_ccitt_table
[(crc
^ *buf
++) & 0xff];
324 return (crc
& 0xffff) == 0xf0b8;
327 /*---------------------------------------------------------------------------*/
329 static inline int calc_crc_ccitt(const unsigned char *buf
, int cnt
)
331 unsigned int crc
= 0xffff;
333 for (; cnt
> 0; cnt
--)
334 crc
= (crc
>> 8) ^ crc_ccitt_table
[(crc
^ *buf
++) & 0xff];
336 return (crc
& 0xffff);
339 /* ---------------------------------------------------------------------- */
341 #define tenms_to_flags(bc,tenms) ((tenms * bc->bitrate) / 800)
343 /* --------------------------------------------------------------------- */
345 static inline void baycom_int_freq(struct baycom_state
*bc
)
348 unsigned long cur_jiffies
= jiffies
;
350 * measure the interrupt frequency
352 bc
->debug_vals
.cur_intcnt
++;
353 if ((cur_jiffies
- bc
->debug_vals
.last_jiffies
) >= HZ
) {
354 bc
->debug_vals
.last_jiffies
= cur_jiffies
;
355 bc
->debug_vals
.last_intcnt
= bc
->debug_vals
.cur_intcnt
;
356 bc
->debug_vals
.cur_intcnt
= 0;
357 bc
->debug_vals
.last_pllcorr
= bc
->debug_vals
.cur_pllcorr
;
358 bc
->debug_vals
.cur_pllcorr
= 0;
360 #endif /* BAYCOM_DEBUG */
363 /* ---------------------------------------------------------------------- */
365 * eppconfig_path should be setable via /proc/sys.
368 static char eppconfig_path
[256] = "/usr/sbin/eppfpga";
370 static char *envp
[] = { "HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL
};
372 /* eppconfig: called during ifconfig up to configure the modem */
373 static int eppconfig(struct baycom_state
*bc
)
377 char *argv
[] = { eppconfig_path
, "-s", "-p", portarg
, "-m", modearg
,
380 /* set up arguments */
381 sprintf(modearg
, "%sclk,%smodem,fclk=%d,bps=%d,divider=%d%s,extstat",
382 bc
->cfg
.intclk
? "int" : "ext",
383 bc
->cfg
.extmodem
? "ext" : "int", bc
->cfg
.fclk
, bc
->cfg
.bps
,
384 (bc
->cfg
.fclk
+ 8 * bc
->cfg
.bps
) / (16 * bc
->cfg
.bps
),
385 bc
->cfg
.loopback
? ",loopback" : "");
386 sprintf(portarg
, "%ld", bc
->pdev
->port
->base
);
387 printk(KERN_DEBUG
"%s: %s -s -p %s -m %s\n", bc_drvname
, eppconfig_path
, portarg
, modearg
);
389 return call_usermodehelper(eppconfig_path
, argv
, envp
, 1);
392 /* ---------------------------------------------------------------------- */
394 static void epp_interrupt(int irq
, void *dev_id
, struct pt_regs
*regs
)
398 /* ---------------------------------------------------------------------- */
400 static inline void do_kiss_params(struct baycom_state
*bc
,
401 unsigned char *data
, unsigned long len
)
405 #define PKP(a,b) printk(KERN_INFO "baycomm_epp: channel params: " a "\n", b)
406 #else /* KISS_VERBOSE */
408 #endif /* KISS_VERBOSE */
414 bc
->ch_params
.tx_delay
= data
[1];
415 PKP("TX delay = %ums", 10 * bc
->ch_params
.tx_delay
);
418 bc
->ch_params
.ppersist
= data
[1];
419 PKP("p persistence = %u", bc
->ch_params
.ppersist
);
422 bc
->ch_params
.slottime
= data
[1];
423 PKP("slot time = %ums", bc
->ch_params
.slottime
);
426 bc
->ch_params
.tx_tail
= data
[1];
427 PKP("TX tail = %ums", bc
->ch_params
.tx_tail
);
430 bc
->ch_params
.fulldup
= !!data
[1];
431 PKP("%s duplex", bc
->ch_params
.fulldup
? "full" : "half");
439 /* --------------------------------------------------------------------- */
441 * high performance HDLC encoder
442 * yes, it's ugly, but generates pretty good code
445 #define ENCODEITERA(j) \
447 if (!(notbitstream & (0x1f0 << j))) \
452 #define ENCODEITERB(j) \
455 bitstream &= ~(0x100 << j); \
456 bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | \
457 ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); \
459 notbitstream = ~bitstream; \
464 static void encode_hdlc(struct baycom_state
*bc
)
467 unsigned char *wp
, *bp
;
469 unsigned bitstream
, notbitstream
, bitbuf
, numbit
, crc
;
470 unsigned char crcarr
[2];
472 if (bc
->hdlctx
.bufcnt
> 0)
478 pkt_len
= skb
->len
-1; /* strip KISS byte */
481 crc
= calc_crc_ccitt(bp
, pkt_len
);
483 crcarr
[1] = crc
>> 8;
485 bitstream
= bitbuf
= numbit
= 0;
486 while (pkt_len
> -2) {
488 bitstream
|= ((unsigned int)*bp
) << 8;
489 bitbuf
|= ((unsigned int)*bp
) << numbit
;
490 notbitstream
= ~bitstream
;
514 while (numbit
>= 8) {
520 bitbuf
|= 0x7e7e << numbit
;
522 while (numbit
>= 8) {
527 bc
->hdlctx
.bufptr
= bc
->hdlctx
.buf
;
528 bc
->hdlctx
.bufcnt
= wp
- bc
->hdlctx
.buf
;
530 bc
->stats
.tx_packets
++;
533 /* ---------------------------------------------------------------------- */
535 static unsigned short random_seed
;
537 static inline unsigned short random_num(void)
539 random_seed
= 28629 * random_seed
+ 157;
543 /* ---------------------------------------------------------------------- */
545 static int transmit(struct baycom_state
*bc
, int cnt
, unsigned char stat
)
547 struct parport
*pp
= bc
->pdev
->port
;
548 unsigned char tmp
[128];
551 if (bc
->hdlctx
.state
== tx_tail
&& !(stat
& EPP_PTTBIT
))
552 bc
->hdlctx
.state
= tx_idle
;
553 if (bc
->hdlctx
.state
== tx_idle
&& bc
->hdlctx
.calibrate
<= 0) {
554 if (bc
->hdlctx
.bufcnt
<= 0)
556 if (bc
->hdlctx
.bufcnt
<= 0)
558 if (!bc
->ch_params
.fulldup
) {
559 if (!(stat
& EPP_DCDBIT
)) {
560 bc
->hdlctx
.slotcnt
= bc
->ch_params
.slottime
;
563 if ((--bc
->hdlctx
.slotcnt
) > 0)
565 bc
->hdlctx
.slotcnt
= bc
->ch_params
.slottime
;
566 if ((random_num() % 256) > bc
->ch_params
.ppersist
)
570 if (bc
->hdlctx
.state
== tx_idle
&& bc
->hdlctx
.bufcnt
> 0) {
571 bc
->hdlctx
.state
= tx_keyup
;
572 bc
->hdlctx
.flags
= tenms_to_flags(bc
, bc
->ch_params
.tx_delay
);
576 switch (bc
->hdlctx
.state
) {
578 i
= min_t(int, cnt
, bc
->hdlctx
.flags
);
580 bc
->hdlctx
.flags
-= i
;
581 if (bc
->hdlctx
.flags
<= 0)
582 bc
->hdlctx
.state
= tx_data
;
583 memset(tmp
, 0x7e, sizeof(tmp
));
585 j
= (i
> sizeof(tmp
)) ? sizeof(tmp
) : i
;
586 if (j
!= pp
->ops
->epp_write_data(pp
, tmp
, j
, 0))
593 if (bc
->hdlctx
.bufcnt
<= 0) {
595 if (bc
->hdlctx
.bufcnt
<= 0) {
596 bc
->hdlctx
.state
= tx_tail
;
597 bc
->hdlctx
.flags
= tenms_to_flags(bc
, bc
->ch_params
.tx_tail
);
601 i
= min_t(int, cnt
, bc
->hdlctx
.bufcnt
);
602 bc
->hdlctx
.bufcnt
-= i
;
604 if (i
!= pp
->ops
->epp_write_data(pp
, bc
->hdlctx
.bufptr
, i
, 0))
606 bc
->hdlctx
.bufptr
+= i
;
611 if (bc
->hdlctx
.bufcnt
> 0) {
612 bc
->hdlctx
.state
= tx_data
;
615 i
= min_t(int, cnt
, bc
->hdlctx
.flags
);
618 bc
->hdlctx
.flags
-= i
;
619 memset(tmp
, 0x7e, sizeof(tmp
));
621 j
= (i
> sizeof(tmp
)) ? sizeof(tmp
) : i
;
622 if (j
!= pp
->ops
->epp_write_data(pp
, tmp
, j
, 0))
629 default: /* fall through */
630 if (bc
->hdlctx
.calibrate
<= 0)
632 i
= min_t(int, cnt
, bc
->hdlctx
.calibrate
);
634 bc
->hdlctx
.calibrate
-= i
;
635 memset(tmp
, 0, sizeof(tmp
));
637 j
= (i
> sizeof(tmp
)) ? sizeof(tmp
) : i
;
638 if (j
!= pp
->ops
->epp_write_data(pp
, tmp
, j
, 0))
648 /* ---------------------------------------------------------------------- */
650 static void do_rxpacket(struct net_device
*dev
)
652 struct baycom_state
*bc
= (struct baycom_state
*)dev
->priv
;
657 if (bc
->hdlcrx
.bufcnt
< 4)
659 if (!check_crc_ccitt(bc
->hdlcrx
.buf
, bc
->hdlcrx
.bufcnt
))
661 pktlen
= bc
->hdlcrx
.bufcnt
-2+1; /* KISS kludge */
662 if (!(skb
= dev_alloc_skb(pktlen
))) {
663 printk("%s: memory squeeze, dropping packet\n", dev
->name
);
664 bc
->stats
.rx_dropped
++;
668 cp
= skb_put(skb
, pktlen
);
669 *cp
++ = 0; /* KISS kludge */
670 memcpy(cp
, bc
->hdlcrx
.buf
, pktlen
- 1);
671 skb
->protocol
= htons(ETH_P_AX25
);
672 skb
->mac
.raw
= skb
->data
;
674 dev
->last_rx
= jiffies
;
675 bc
->stats
.rx_packets
++;
678 #define DECODEITERA(j) \
680 if (!(notbitstream & (0x0fc << j))) /* flag or abort */ \
682 if ((bitstream & (0x1f8 << j)) == (0xf8 << j)) /* stuffed bit */ \
687 #define DECODEITERB(j) \
690 if (!(notbitstream & (0x1fc << j))) { /* abort received */ \
694 if ((bitstream & (0x1fe << j)) != (0x0fc << j)) /* flag received */ \
698 bc->hdlcrx.bufcnt = 0; \
699 bc->hdlcrx.bufptr = bc->hdlcrx.buf; \
705 bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); \
709 static int receive(struct net_device
*dev
, int cnt
)
711 struct baycom_state
*bc
= (struct baycom_state
*)dev
->priv
;
712 struct parport
*pp
= bc
->pdev
->port
;
713 unsigned int bitbuf
, notbitstream
, bitstream
, numbits
, state
;
714 unsigned char tmp
[128];
718 numbits
= bc
->hdlcrx
.numbits
;
719 state
= bc
->hdlcrx
.state
;
720 bitstream
= bc
->hdlcrx
.bitstream
;
721 bitbuf
= bc
->hdlcrx
.bitbuf
;
723 cnt2
= (cnt
> sizeof(tmp
)) ? sizeof(tmp
) : cnt
;
725 if (cnt2
!= pp
->ops
->epp_read_data(pp
, tmp
, cnt2
, 0)) {
730 for (; cnt2
> 0; cnt2
--, cp
++) {
732 bitstream
|= (*cp
) << 8;
734 bitbuf
|= (*cp
) << 8;
736 notbitstream
= ~bitstream
;
755 while (state
&& numbits
>= 8) {
756 if (bc
->hdlcrx
.bufcnt
>= TXBUFFER_SIZE
) {
759 *(bc
->hdlcrx
.bufptr
)++ = bitbuf
>> (16-numbits
);
766 bc
->hdlcrx
.numbits
= numbits
;
767 bc
->hdlcrx
.state
= state
;
768 bc
->hdlcrx
.bitstream
= bitstream
;
769 bc
->hdlcrx
.bitbuf
= bitbuf
;
773 /* --------------------------------------------------------------------- */
784 #endif /* __i386__ */
786 static void epp_bh(struct net_device
*dev
)
788 struct baycom_state
*bc
;
791 unsigned char tmp
[2];
792 unsigned int time1
= 0, time2
= 0, time3
= 0;
795 baycom_paranoia_check_void(dev
, "epp_bh");
796 bc
= (struct baycom_state
*)dev
->priv
;
797 if (!bc
->work_running
)
802 if (pp
->ops
->epp_read_addr(pp
, &stat
, 1, 0) != 1)
805 bc
->debug_vals
.last_pllcorr
= stat
;
807 if (bc
->modem
== EPP_FPGAEXTSTATUS
) {
808 /* get input count */
809 tmp
[0] = EPP_TX_FIFO_ENABLE
|EPP_RX_FIFO_ENABLE
|EPP_MODEM_ENABLE
|1;
810 if (pp
->ops
->epp_write_addr(pp
, tmp
, 1, 0) != 1)
812 if (pp
->ops
->epp_read_addr(pp
, tmp
, 2, 0) != 2)
814 cnt
= tmp
[0] | (tmp
[1] << 8);
816 /* get output count */
817 tmp
[0] = EPP_TX_FIFO_ENABLE
|EPP_RX_FIFO_ENABLE
|EPP_MODEM_ENABLE
|2;
818 if (pp
->ops
->epp_write_addr(pp
, tmp
, 1, 0) != 1)
820 if (pp
->ops
->epp_read_addr(pp
, tmp
, 2, 0) != 2)
822 cnt2
= tmp
[0] | (tmp
[1] << 8);
823 cnt2
= 16384 - (cnt2
& 0x7fff);
824 /* return to normal */
825 tmp
[0] = EPP_TX_FIFO_ENABLE
|EPP_RX_FIFO_ENABLE
|EPP_MODEM_ENABLE
;
826 if (pp
->ops
->epp_write_addr(pp
, tmp
, 1, 0) != 1)
828 if (transmit(bc
, cnt2
, stat
))
831 if (receive(dev
, cnt
))
833 if (pp
->ops
->epp_read_addr(pp
, &stat
, 1, 0) != 1)
838 switch (stat
& (EPP_NTAEF
|EPP_NTHF
)) {
855 if (transmit(bc
, cnt
, stat
))
859 while ((stat
& (EPP_NRAEF
|EPP_NRHF
)) != EPP_NRHF
) {
860 switch (stat
& (EPP_NRAEF
|EPP_NRHF
)) {
873 if (receive(dev
, cnt
))
875 if (pp
->ops
->epp_read_addr(pp
, &stat
, 1, 0) != 1)
879 if (bc
->bitrate
< 50000)
881 else if (bc
->bitrate
< 100000)
883 while (cnt
> 0 && stat
& EPP_NREF
) {
887 if (pp
->ops
->epp_read_addr(pp
, &stat
, 1, 0) != 1)
893 bc
->debug_vals
.mod_cycles
= time2
- time1
;
894 bc
->debug_vals
.demod_cycles
= time3
- time2
;
895 #endif /* BAYCOM_DEBUG */
896 schedule_delayed_work(&bc
->run_work
, 1);
898 netif_wake_queue(dev
);
901 printk(KERN_ERR
"%s: EPP timeout!\n", bc_drvname
);
904 /* ---------------------------------------------------------------------- */
906 * ===================== network driver interface =========================
909 static int baycom_send_packet(struct sk_buff
*skb
, struct net_device
*dev
)
911 struct baycom_state
*bc
;
913 baycom_paranoia_check(dev
, "baycom_send_packet", 0);
914 bc
= (struct baycom_state
*)dev
->priv
;
915 if (skb
->data
[0] != 0) {
916 do_kiss_params(bc
, skb
->data
, skb
->len
);
922 /* strip KISS byte */
923 if (skb
->len
>= HDLCDRV_MAXFLEN
+1 || skb
->len
< 3) {
927 netif_stop_queue(dev
);
932 /* --------------------------------------------------------------------- */
934 static int baycom_set_mac_address(struct net_device
*dev
, void *addr
)
936 struct sockaddr
*sa
= (struct sockaddr
*)addr
;
938 /* addr is an AX.25 shifted ASCII mac address */
939 memcpy(dev
->dev_addr
, sa
->sa_data
, dev
->addr_len
);
943 /* --------------------------------------------------------------------- */
945 static struct net_device_stats
*baycom_get_stats(struct net_device
*dev
)
947 struct baycom_state
*bc
;
949 baycom_paranoia_check(dev
, "baycom_get_stats", NULL
);
950 bc
= (struct baycom_state
*)dev
->priv
;
952 * Get the current statistics. This may be called with the
953 * card open or closed.
958 /* --------------------------------------------------------------------- */
960 static void epp_wakeup(void *handle
)
962 struct net_device
*dev
= (struct net_device
*)handle
;
963 struct baycom_state
*bc
;
965 baycom_paranoia_check_void(dev
, "epp_wakeup");
966 bc
= (struct baycom_state
*)dev
->priv
;
967 printk(KERN_DEBUG
"baycom_epp: %s: why am I being woken up?\n", dev
->name
);
968 if (!parport_claim(bc
->pdev
))
969 printk(KERN_DEBUG
"baycom_epp: %s: I'm broken.\n", dev
->name
);
972 /* --------------------------------------------------------------------- */
975 * Open/initialize the board. This is called (in the current kernel)
976 * sometime after booting when the 'ifconfig' program is run.
978 * This routine should set everything up anew at each open, even
979 * registers that "should" only need to be set once at boot, so that
980 * there is non-reboot way to recover if something goes wrong.
983 static int epp_open(struct net_device
*dev
)
985 struct baycom_state
*bc
;
988 unsigned char tmp
[128];
990 unsigned long tstart
;
992 baycom_paranoia_check(dev
, "epp_open", -ENXIO
);
993 bc
= (struct baycom_state
*)dev
->priv
;
994 pp
= parport_enumerate();
995 while (pp
&& pp
->base
!= dev
->base_addr
)
998 printk(KERN_ERR
"%s: parport at 0x%lx unknown\n", bc_drvname
, dev
->base_addr
);
1003 printk(KERN_ERR
"%s: parport at 0x%lx has no irq\n", bc_drvname
, pp
->base
);
1007 if ((~pp
->modes
) & (PARPORT_MODE_TRISTATE
| PARPORT_MODE_PCSPP
| PARPORT_MODE_SAFEININT
)) {
1008 printk(KERN_ERR
"%s: parport at 0x%lx cannot be used\n",
1009 bc_drvname
, pp
->base
);
1012 memset(&bc
->modem
, 0, sizeof(bc
->modem
));
1013 if (!(bc
->pdev
= parport_register_device(pp
, dev
->name
, NULL
, epp_wakeup
,
1014 epp_interrupt
, PARPORT_DEV_EXCL
, dev
))) {
1015 printk(KERN_ERR
"%s: cannot register parport at 0x%lx\n", bc_drvname
, pp
->base
);
1018 if (parport_claim(bc
->pdev
)) {
1019 printk(KERN_ERR
"%s: parport at 0x%lx busy\n", bc_drvname
, pp
->base
);
1020 parport_unregister_device(bc
->pdev
);
1023 dev
->irq
= /*pp->irq*/ 0;
1024 INIT_WORK(&bc
->run_work
, (void *)(void *)epp_bh
, dev
);
1025 bc
->work_running
= 1;
1026 bc
->modem
= EPP_CONVENTIONAL
;
1028 printk(KERN_INFO
"%s: no FPGA detected, assuming conventional EPP modem\n", bc_drvname
);
1030 bc
->modem
= /*EPP_FPGA*/ EPP_FPGAEXTSTATUS
;
1031 parport_write_control(pp
, LPTCTRL_PROGRAM
); /* prepare EPP mode; we aren't using interrupts */
1032 /* reset the modem */
1034 tmp
[1] = EPP_TX_FIFO_ENABLE
|EPP_RX_FIFO_ENABLE
|EPP_MODEM_ENABLE
;
1035 if (pp
->ops
->epp_write_addr(pp
, tmp
, 2, 0) != 2)
1037 /* autoprobe baud rate */
1040 while ((signed)(jiffies
-tstart
-HZ
/3) < 0) {
1041 if (pp
->ops
->epp_read_addr(pp
, &stat
, 1, 0) != 1)
1043 if ((stat
& (EPP_NRAEF
|EPP_NRHF
)) == EPP_NRHF
) {
1047 if (pp
->ops
->epp_read_data(pp
, tmp
, 128, 0) != 128)
1049 if (pp
->ops
->epp_read_data(pp
, tmp
, 128, 0) != 128)
1053 for (j
= 0; j
< 256; j
++) {
1054 if (pp
->ops
->epp_read_addr(pp
, &stat
, 1, 0) != 1)
1056 if (!(stat
& EPP_NREF
))
1058 if (pp
->ops
->epp_read_data(pp
, tmp
, 1, 0) != 1)
1062 tstart
= jiffies
- tstart
;
1063 bc
->bitrate
= i
* (8 * HZ
) / tstart
;
1065 i
= bc
->bitrate
>> 3;
1066 while (j
< 7 && i
> 150) {
1070 printk(KERN_INFO
"%s: autoprobed bitrate: %d int divider: %d int rate: %d\n",
1071 bc_drvname
, bc
->bitrate
, j
, bc
->bitrate
>> (j
+2));
1072 tmp
[0] = EPP_TX_FIFO_ENABLE
|EPP_RX_FIFO_ENABLE
|EPP_MODEM_ENABLE
/*|j*/;
1073 if (pp
->ops
->epp_write_addr(pp
, tmp
, 1, 0) != 1)
1076 * initialise hdlc variables
1078 bc
->hdlcrx
.state
= 0;
1079 bc
->hdlcrx
.numbits
= 0;
1080 bc
->hdlctx
.state
= tx_idle
;
1081 bc
->hdlctx
.bufcnt
= 0;
1082 bc
->hdlctx
.slotcnt
= bc
->ch_params
.slottime
;
1083 bc
->hdlctx
.calibrate
= 0;
1084 /* start the bottom half stuff */
1085 schedule_delayed_work(&bc
->run_work
, 1);
1086 netif_start_queue(dev
);
1091 printk(KERN_ERR
"%s: epp timeout during bitrate probe\n", bc_drvname
);
1092 parport_write_control(pp
, 0); /* reset the adapter */
1093 parport_release(bc
->pdev
);
1094 parport_unregister_device(bc
->pdev
);
1098 /* --------------------------------------------------------------------- */
1100 static int epp_close(struct net_device
*dev
)
1102 struct baycom_state
*bc
;
1104 unsigned char tmp
[1];
1106 baycom_paranoia_check(dev
, "epp_close", -EINVAL
);
1107 bc
= (struct baycom_state
*)dev
->priv
;
1108 pp
= bc
->pdev
->port
;
1109 bc
->work_running
= 0;
1110 flush_scheduled_work();
1111 bc
->stat
= EPP_DCDBIT
;
1113 pp
->ops
->epp_write_addr(pp
, tmp
, 1, 0);
1114 parport_write_control(pp
, 0); /* reset the adapter */
1115 parport_release(bc
->pdev
);
1116 parport_unregister_device(bc
->pdev
);
1118 dev_kfree_skb(bc
->skb
);
1120 printk(KERN_INFO
"%s: close epp at iobase 0x%lx irq %u\n",
1121 bc_drvname
, dev
->base_addr
, dev
->irq
);
1126 /* --------------------------------------------------------------------- */
1128 static int baycom_setmode(struct baycom_state
*bc
, const char *modestr
)
1132 if (strstr(modestr
,"intclk"))
1134 if (strstr(modestr
,"extclk"))
1136 if (strstr(modestr
,"intmodem"))
1137 bc
->cfg
.extmodem
= 0;
1138 if (strstr(modestr
,"extmodem"))
1139 bc
->cfg
.extmodem
= 1;
1140 if (strstr(modestr
,"noloopback"))
1141 bc
->cfg
.loopback
= 0;
1142 if (strstr(modestr
,"loopback"))
1143 bc
->cfg
.loopback
= 1;
1144 if ((cp
= strstr(modestr
,"fclk="))) {
1145 bc
->cfg
.fclk
= simple_strtoul(cp
+5, NULL
, 0);
1146 if (bc
->cfg
.fclk
< 1000000)
1147 bc
->cfg
.fclk
= 1000000;
1148 if (bc
->cfg
.fclk
> 25000000)
1149 bc
->cfg
.fclk
= 25000000;
1151 if ((cp
= strstr(modestr
,"bps="))) {
1152 bc
->cfg
.bps
= simple_strtoul(cp
+4, NULL
, 0);
1153 if (bc
->cfg
.bps
< 1000)
1155 if (bc
->cfg
.bps
> 1500000)
1156 bc
->cfg
.bps
= 1500000;
1161 /* --------------------------------------------------------------------- */
1163 static int baycom_ioctl(struct net_device
*dev
, struct ifreq
*ifr
, int cmd
)
1165 struct baycom_state
*bc
;
1166 struct hdlcdrv_ioctl hi
;
1168 baycom_paranoia_check(dev
, "baycom_ioctl", -EINVAL
);
1169 bc
= (struct baycom_state
*)dev
->priv
;
1170 if (cmd
!= SIOCDEVPRIVATE
)
1171 return -ENOIOCTLCMD
;
1172 if (get_user(cmd
, (int *)ifr
->ifr_data
))
1175 if (copy_from_user(&hi
, ifr
->ifr_data
, sizeof(hi
)))
1179 return -ENOIOCTLCMD
;
1181 case HDLCDRVCTL_GETCHANNELPAR
:
1182 hi
.data
.cp
.tx_delay
= bc
->ch_params
.tx_delay
;
1183 hi
.data
.cp
.tx_tail
= bc
->ch_params
.tx_tail
;
1184 hi
.data
.cp
.slottime
= bc
->ch_params
.slottime
;
1185 hi
.data
.cp
.ppersist
= bc
->ch_params
.ppersist
;
1186 hi
.data
.cp
.fulldup
= bc
->ch_params
.fulldup
;
1189 case HDLCDRVCTL_SETCHANNELPAR
:
1190 if (!capable(CAP_NET_ADMIN
))
1192 bc
->ch_params
.tx_delay
= hi
.data
.cp
.tx_delay
;
1193 bc
->ch_params
.tx_tail
= hi
.data
.cp
.tx_tail
;
1194 bc
->ch_params
.slottime
= hi
.data
.cp
.slottime
;
1195 bc
->ch_params
.ppersist
= hi
.data
.cp
.ppersist
;
1196 bc
->ch_params
.fulldup
= hi
.data
.cp
.fulldup
;
1197 bc
->hdlctx
.slotcnt
= 1;
1200 case HDLCDRVCTL_GETMODEMPAR
:
1201 hi
.data
.mp
.iobase
= dev
->base_addr
;
1202 hi
.data
.mp
.irq
= dev
->irq
;
1203 hi
.data
.mp
.dma
= dev
->dma
;
1204 hi
.data
.mp
.dma2
= 0;
1205 hi
.data
.mp
.seriobase
= 0;
1206 hi
.data
.mp
.pariobase
= 0;
1207 hi
.data
.mp
.midiiobase
= 0;
1210 case HDLCDRVCTL_SETMODEMPAR
:
1211 if ((!capable(CAP_SYS_RAWIO
)) || netif_running(dev
))
1213 dev
->base_addr
= hi
.data
.mp
.iobase
;
1214 dev
->irq
= /*hi.data.mp.irq*/0;
1215 dev
->dma
= /*hi.data.mp.dma*/0;
1218 case HDLCDRVCTL_GETSTAT
:
1219 hi
.data
.cs
.ptt
= !!(bc
->stat
& EPP_PTTBIT
);
1220 hi
.data
.cs
.dcd
= !(bc
->stat
& EPP_DCDBIT
);
1221 hi
.data
.cs
.ptt_keyed
= bc
->ptt_keyed
;
1222 hi
.data
.cs
.tx_packets
= bc
->stats
.tx_packets
;
1223 hi
.data
.cs
.tx_errors
= bc
->stats
.tx_errors
;
1224 hi
.data
.cs
.rx_packets
= bc
->stats
.rx_packets
;
1225 hi
.data
.cs
.rx_errors
= bc
->stats
.rx_errors
;
1228 case HDLCDRVCTL_OLDGETSTAT
:
1229 hi
.data
.ocs
.ptt
= !!(bc
->stat
& EPP_PTTBIT
);
1230 hi
.data
.ocs
.dcd
= !(bc
->stat
& EPP_DCDBIT
);
1231 hi
.data
.ocs
.ptt_keyed
= bc
->ptt_keyed
;
1234 case HDLCDRVCTL_CALIBRATE
:
1235 if (!capable(CAP_SYS_RAWIO
))
1237 bc
->hdlctx
.calibrate
= hi
.data
.calibrate
* bc
->bitrate
/ 8;
1240 case HDLCDRVCTL_DRIVERNAME
:
1241 strncpy(hi
.data
.drivername
, "baycom_epp", sizeof(hi
.data
.drivername
));
1244 case HDLCDRVCTL_GETMODE
:
1245 sprintf(hi
.data
.modename
, "%sclk,%smodem,fclk=%d,bps=%d%s",
1246 bc
->cfg
.intclk
? "int" : "ext",
1247 bc
->cfg
.extmodem
? "ext" : "int", bc
->cfg
.fclk
, bc
->cfg
.bps
,
1248 bc
->cfg
.loopback
? ",loopback" : "");
1251 case HDLCDRVCTL_SETMODE
:
1252 if (!capable(CAP_NET_ADMIN
) || netif_running(dev
))
1254 hi
.data
.modename
[sizeof(hi
.data
.modename
)-1] = '\0';
1255 return baycom_setmode(bc
, hi
.data
.modename
);
1257 case HDLCDRVCTL_MODELIST
:
1258 strncpy(hi
.data
.modename
, "intclk,extclk,intmodem,extmodem,divider=x",
1259 sizeof(hi
.data
.modename
));
1262 case HDLCDRVCTL_MODEMPARMASK
:
1263 return HDLCDRV_PARMASK_IOBASE
;
1266 if (copy_to_user(ifr
->ifr_data
, &hi
, sizeof(hi
)))
1271 /* --------------------------------------------------------------------- */
1274 * Check for a network adaptor of this type, and return '0' if one exists.
1275 * If dev->base_addr == 0, probe all likely locations.
1276 * If dev->base_addr == 1, always return failure.
1277 * If dev->base_addr == 2, allocate space for the device and return success
1278 * (detachable devices only).
1280 static int baycom_probe(struct net_device
*dev
)
1282 static char ax25_bcast
[AX25_ADDR_LEN
] = {
1283 'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1
1285 static char ax25_nocall
[AX25_ADDR_LEN
] = {
1286 'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1
1288 const struct hdlcdrv_channel_params dflt_ch_params
= {
1291 struct baycom_state
*bc
;
1295 baycom_paranoia_check(dev
, "baycom_probe", -ENXIO
);
1297 * not a real probe! only initialize data structures
1299 bc
= (struct baycom_state
*)dev
->priv
;
1301 * initialize the baycom_state struct
1303 bc
->ch_params
= dflt_ch_params
;
1307 * initialize the device struct
1309 dev
->open
= epp_open
;
1310 dev
->stop
= epp_close
;
1311 dev
->do_ioctl
= baycom_ioctl
;
1312 dev
->hard_start_xmit
= baycom_send_packet
;
1313 dev
->get_stats
= baycom_get_stats
;
1315 /* Fill in the fields of the device structure */
1318 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
1319 dev
->hard_header
= ax25_encapsulate
;
1320 dev
->rebuild_header
= ax25_rebuild_header
;
1321 #else /* CONFIG_AX25 || CONFIG_AX25_MODULE */
1322 dev
->hard_header
= NULL
;
1323 dev
->rebuild_header
= NULL
;
1324 #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
1325 dev
->set_mac_address
= baycom_set_mac_address
;
1327 dev
->type
= ARPHRD_AX25
; /* AF_AX25 device */
1328 dev
->hard_header_len
= AX25_MAX_HEADER_LEN
+ AX25_BPQ_HEADER_LEN
;
1329 dev
->mtu
= AX25_DEF_PACLEN
; /* eth_mtu is the default */
1330 dev
->addr_len
= AX25_ADDR_LEN
; /* sizeof an ax.25 address */
1331 memcpy(dev
->broadcast
, ax25_bcast
, AX25_ADDR_LEN
);
1332 memcpy(dev
->dev_addr
, ax25_nocall
, AX25_ADDR_LEN
);
1333 dev
->tx_queue_len
= 16;
1335 /* New style flags */
1341 /* --------------------------------------------------------------------- */
1344 * command line settable parameters
1346 static const char *mode
[NR_PORTS
] = { "", };
1347 static int iobase
[NR_PORTS
] = { 0x378, };
1349 MODULE_PARM(mode
, "1-" __MODULE_STRING(NR_PORTS
) "s");
1350 MODULE_PARM_DESC(mode
, "baycom operating mode");
1351 MODULE_PARM(iobase
, "1-" __MODULE_STRING(NR_PORTS
) "i");
1352 MODULE_PARM_DESC(iobase
, "baycom io base address");
1354 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
1355 MODULE_DESCRIPTION("Baycom epp amateur radio modem driver");
1356 MODULE_LICENSE("GPL");
1358 /* --------------------------------------------------------------------- */
1360 static int __init
init_baycomepp(void)
1362 struct net_device
*dev
;
1365 struct baycom_state
*bc
;
1369 * register net devices
1371 for (i
= 0; i
< NR_PORTS
; i
++) {
1372 dev
= baycom_device
+i
;
1377 memset(dev
, 0, sizeof(struct net_device
));
1378 if (!(bc
= dev
->priv
= kmalloc(sizeof(struct baycom_state
), GFP_KERNEL
)))
1381 * initialize part of the baycom_state struct
1383 memset(bc
, 0, sizeof(struct baycom_state
));
1384 bc
->magic
= BAYCOM_MAGIC
;
1385 sprintf(dev
->name
, "bce%d", i
);
1386 bc
->cfg
.fclk
= 19666600;
1389 * initialize part of the device struct
1392 dev
->init
= baycom_probe
;
1393 dev
->base_addr
= iobase
[i
];
1396 if (register_netdev(dev
)) {
1397 printk(KERN_WARNING
"%s: cannot register net device %s\n", bc_drvname
, dev
->name
);
1401 if (set_hw
&& baycom_setmode(bc
, mode
[i
]))
1410 static void __exit
cleanup_baycomepp(void)
1412 struct net_device
*dev
;
1413 struct baycom_state
*bc
;
1416 for(i
= 0; i
< NR_PORTS
; i
++) {
1417 dev
= baycom_device
+i
;
1418 bc
= (struct baycom_state
*)dev
->priv
;
1420 if (bc
->magic
== BAYCOM_MAGIC
) {
1421 unregister_netdev(dev
);
1424 printk(paranoia_str
, "cleanup_module");
1429 module_init(init_baycomepp
);
1430 module_exit(cleanup_baycomepp
);
1432 /* --------------------------------------------------------------------- */
1437 * format: baycom_epp=io,mode
1438 * mode: fpga config options
1441 static int __init
baycom_epp_setup(char *str
)
1443 static unsigned __initdata nr_dev
= 0;
1446 if (nr_dev
>= NR_PORTS
)
1448 str
= get_options(str
, 2, ints
);
1452 iobase
[nr_dev
] = ints
[1];
1457 __setup("baycom_epp=", baycom_epp_setup
);
1460 /* --------------------------------------------------------------------- */