1 /*****************************************************************************/
4 * yam.c -- YAM radio modem driver.
6 * Copyright (C) 1998 Frederic Rible F1OAT (frible@teaser.fr)
7 * Adapted from baycom.c driver written by 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.0 F1OAT 06.06.98 Begin of work with baycom.c source code V 0.3
30 * 0.1 F1OAT 07.06.98 Add timer polling routine for channel arbitration
31 * 0.2 F6FBB 08.06.98 Added delay after FPGA programming
32 * 0.3 F6FBB 29.07.98 Delayed PTT implementation for dupmode=2
33 * 0.4 F6FBB 30.07.98 Added TxTail, Slottime and Persistance
34 * 0.5 F6FBB 01.08.98 Shared IRQs, /proc/net and network statistics
35 * 0.6 F6FBB 25.08.98 Added 1200Bds format
36 * 0.7 F6FBB 12.09.98 Added to the kernel configuration
37 * 0.8 F6FBB 14.10.98 Fixed slottime/persistance timing bug
40 /*****************************************************************************/
42 #include <linux/config.h>
43 #include <linux/module.h>
44 #include <linux/types.h>
45 #include <linux/net.h>
48 #include <linux/malloc.h>
49 #include <linux/errno.h>
50 #include <asm/bitops.h>
52 #include <asm/system.h>
53 #include <linux/interrupt.h>
54 #include <linux/ioport.h>
56 #include <linux/netdevice.h>
57 #include <linux/if_arp.h>
58 #include <linux/etherdevice.h>
59 #include <linux/skbuff.h>
60 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
61 /* prototypes for ax25_encapsulate and ax25_rebuild_header */
63 #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
65 /* make genksyms happy */
67 #include <linux/udp.h>
68 #include <linux/tcp.h>
70 #include <linux/kernel.h>
71 #include <linux/proc_fs.h>
73 #include <linux/yam.h>
77 /* --------------------------------------------------------------------- */
80 * currently this module is supposed to support both module styles, i.e.
81 * the old one present up to about 2.1.9, and the new one functioning
82 * starting with 2.1.21. The reason is I have a kit allowing to compile
83 * this module also under 2.0.x which was requested by several people.
86 #include <linux/version.h>
88 #if LINUX_VERSION_CODE >= 0x20100
89 #include <asm/uaccess.h>
91 #include <asm/segment.h>
97 #define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
98 #define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
100 extern inline int copy_from_user(void *to
, const void *from
, unsigned long n
)
102 int i
= verify_area(VERIFY_READ
, from
, n
);
105 memcpy_fromfs(to
, from
, n
);
109 extern inline int copy_to_user(void *to
, const void *from
, unsigned long n
)
111 int i
= verify_area(VERIFY_WRITE
, to
, n
);
114 memcpy_tofs(to
, from
, n
);
119 #if LINUX_VERSION_CODE < 0x20115
120 extern __inline__
void dev_init_buffers(struct net_device
*dev
)
123 for (i
= 0; i
< DEV_NUMBUFFS
; i
++) {
124 skb_queue_head_init(&dev
->buffs
[i
]);
129 #if LINUX_VERSION_CODE >= 0x20123
130 #include <linux/init.h>
136 /* --------------------------------------------------------------------- */
138 static const char yam_drvname
[] = "yam";
139 static const char yam_drvinfo
[] = KERN_INFO
"YAM driver version 0.8 by F1OAT/F6FBB\n";
141 /* --------------------------------------------------------------------- */
147 #define YAM_MAGIC 0xF10A7654
149 /* Transmitter states */
158 #define YAM_MAX_FRAME 1024
160 #define DEFAULT_BITRATE 9600 /* bps */
161 #define DEFAULT_HOLDD 10 /* sec */
162 #define DEFAULT_TXD 300 /* ms */
163 #define DEFAULT_TXTAIL 10 /* ms */
164 #define DEFAULT_SLOT 100 /* ms */
165 #define DEFAULT_PERS 64 /* 0->255 */
176 struct net_device dev
;
180 #if LINUX_VERSION_CODE < 0x20119
181 struct enet_statistics stats
;
183 struct net_device_stats stats
;
188 /* Parameters section */
190 int txd
; /* tx delay */
191 int holdd
; /* duplex ptt delay */
192 int txtail
; /* txtail delay */
193 int slot
; /* slottime */
194 int pers
; /* persistence */
201 unsigned char tx_buf
[YAM_MAX_FRAME
];
203 int tx_crcl
, tx_crch
;
204 struct sk_buff_head send_queue
; /* Packets awaiting transmission */
209 unsigned char rx_buf
[YAM_MAX_FRAME
];
211 int rx_crcl
, rx_crch
;
215 unsigned char bits
[YAM_FPGA_SIZE
];
217 struct yam_mcs
*next
;
220 static struct yam_port yam_ports
[NR_PORTS
];
222 static struct yam_mcs
*yam_data
= NULL
;
224 static unsigned irqs
[16];
226 static char ax25_bcast
[7] =
227 {'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1};
228 static char ax25_test
[7] =
229 {'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1};
231 static struct timer_list yam_timer
;
233 /* --------------------------------------------------------------------- */
235 #define RBR(iobase) (iobase+0)
236 #define THR(iobase) (iobase+0)
237 #define IER(iobase) (iobase+1)
238 #define IIR(iobase) (iobase+2)
239 #define FCR(iobase) (iobase+2)
240 #define LCR(iobase) (iobase+3)
241 #define MCR(iobase) (iobase+4)
242 #define LSR(iobase) (iobase+5)
243 #define MSR(iobase) (iobase+6)
244 #define SCR(iobase) (iobase+7)
245 #define DLL(iobase) (iobase+0)
246 #define DLM(iobase) (iobase+1)
250 /* Interrupt Identification Register Bit Masks */
256 #define IIR_TIMEOUT 12 /* Fifo mode only */
258 #define IIR_MASK 0x0F
260 /* Interrupt Enable Register Bit Masks */
261 #define IER_RX 1 /* enable rx interrupt */
262 #define IER_TX 2 /* enable tx interrupt */
263 #define IER_LSR 4 /* enable line status interrupts */
264 #define IER_MSR 8 /* enable modem status interrupts */
266 /* Modem Control Register Bit Masks */
267 #define MCR_DTR 0x01 /* DTR output */
268 #define MCR_RTS 0x02 /* RTS output */
269 #define MCR_OUT1 0x04 /* OUT1 output (not accessible in RS232) */
270 #define MCR_OUT2 0x08 /* Master Interrupt enable (must be set on PCs) */
271 #define MCR_LOOP 0x10 /* Loopback enable */
273 /* Modem Status Register Bit Masks */
274 #define MSR_DCTS 0x01 /* Delta CTS input */
275 #define MSR_DDSR 0x02 /* Delta DSR */
276 #define MSR_DRIN 0x04 /* Delta RI */
277 #define MSR_DDCD 0x08 /* Delta DCD */
278 #define MSR_CTS 0x10 /* CTS input */
279 #define MSR_DSR 0x20 /* DSR input */
280 #define MSR_RING 0x40 /* RI input */
281 #define MSR_DCD 0x80 /* DCD input */
283 /* line status register bit mask */
288 #define LSR_BREAK 0x10
289 #define LSR_THRE 0x20
290 #define LSR_TSRE 0x40
292 /* Line Control Register Bit Masks */
293 #define LCR_DLAB 0x80
294 #define LCR_BREAK 0x40
295 #define LCR_PZERO 0x28
296 #define LCR_PEVEN 0x18
297 #define LCR_PODD 0x08
298 #define LCR_STOP1 0x00
299 #define LCR_STOP2 0x04
300 #define LCR_BIT5 0x00
301 #define LCR_BIT6 0x02
302 #define LCR_BIT7 0x01
303 #define LCR_BIT8 0x03
305 /* YAM Modem <-> UART Port mapping */
307 #define TX_RDY MSR_DCTS /* transmitter ready to send */
308 #define RX_DCD MSR_DCD /* carrier detect */
309 #define RX_FLAG MSR_RING /* hdlc flag received */
310 #define FPGA_DONE MSR_DSR /* FPGA is configured */
311 #define PTT_ON (MCR_RTS|MCR_OUT2) /* activate PTT */
312 #define PTT_OFF (MCR_DTR|MCR_OUT2) /* release PTT */
314 #define ENABLE_RXINT IER_RX /* enable uart rx interrupt during rx */
315 #define ENABLE_TXINT IER_MSR /* enable uart ms interrupt during tx */
316 #define ENABLE_RTXINT (IER_RX|IER_MSR) /* full duplex operations */
318 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
319 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
321 /*************************************************************************
323 ************************************************************************/
325 static const unsigned char chktabl
[256] =
326 {0x00, 0x89, 0x12, 0x9b, 0x24, 0xad, 0x36, 0xbf, 0x48, 0xc1, 0x5a, 0xd3, 0x6c, 0xe5, 0x7e,
327 0xf7, 0x81, 0x08, 0x93, 0x1a, 0xa5, 0x2c, 0xb7, 0x3e, 0xc9, 0x40, 0xdb, 0x52, 0xed, 0x64,
328 0xff, 0x76, 0x02, 0x8b, 0x10, 0x99, 0x26, 0xaf, 0x34, 0xbd, 0x4a, 0xc3, 0x58, 0xd1, 0x6e,
329 0xe7, 0x7c, 0xf5, 0x83, 0x0a, 0x91, 0x18, 0xa7, 0x2e, 0xb5, 0x3c, 0xcb, 0x42, 0xd9, 0x50,
330 0xef, 0x66, 0xfd, 0x74, 0x04, 0x8d, 0x16, 0x9f, 0x20, 0xa9, 0x32, 0xbb, 0x4c, 0xc5, 0x5e,
331 0xd7, 0x68, 0xe1, 0x7a, 0xf3, 0x85, 0x0c, 0x97, 0x1e, 0xa1, 0x28, 0xb3, 0x3a, 0xcd, 0x44,
332 0xdf, 0x56, 0xe9, 0x60, 0xfb, 0x72, 0x06, 0x8f, 0x14, 0x9d, 0x22, 0xab, 0x30, 0xb9, 0x4e,
333 0xc7, 0x5c, 0xd5, 0x6a, 0xe3, 0x78, 0xf1, 0x87, 0x0e, 0x95, 0x1c, 0xa3, 0x2a, 0xb1, 0x38,
334 0xcf, 0x46, 0xdd, 0x54, 0xeb, 0x62, 0xf9, 0x70, 0x08, 0x81, 0x1a, 0x93, 0x2c, 0xa5, 0x3e,
335 0xb7, 0x40, 0xc9, 0x52, 0xdb, 0x64, 0xed, 0x76, 0xff, 0x89, 0x00, 0x9b, 0x12, 0xad, 0x24,
336 0xbf, 0x36, 0xc1, 0x48, 0xd3, 0x5a, 0xe5, 0x6c, 0xf7, 0x7e, 0x0a, 0x83, 0x18, 0x91, 0x2e,
337 0xa7, 0x3c, 0xb5, 0x42, 0xcb, 0x50, 0xd9, 0x66, 0xef, 0x74, 0xfd, 0x8b, 0x02, 0x99, 0x10,
338 0xaf, 0x26, 0xbd, 0x34, 0xc3, 0x4a, 0xd1, 0x58, 0xe7, 0x6e, 0xf5, 0x7c, 0x0c, 0x85, 0x1e,
339 0x97, 0x28, 0xa1, 0x3a, 0xb3, 0x44, 0xcd, 0x56, 0xdf, 0x60, 0xe9, 0x72, 0xfb, 0x8d, 0x04,
340 0x9f, 0x16, 0xa9, 0x20, 0xbb, 0x32, 0xc5, 0x4c, 0xd7, 0x5e, 0xe1, 0x68, 0xf3, 0x7a, 0x0e,
341 0x87, 0x1c, 0x95, 0x2a, 0xa3, 0x38, 0xb1, 0x46, 0xcf, 0x54, 0xdd, 0x62, 0xeb, 0x70, 0xf9,
342 0x8f, 0x06, 0x9d, 0x14, 0xab, 0x22, 0xb9, 0x30, 0xc7, 0x4e, 0xd5, 0x5c, 0xe3, 0x6a, 0xf1,
344 static const unsigned char chktabh
[256] =
345 {0x00, 0x11, 0x23, 0x32, 0x46, 0x57, 0x65, 0x74, 0x8c, 0x9d, 0xaf, 0xbe, 0xca, 0xdb, 0xe9,
346 0xf8, 0x10, 0x01, 0x33, 0x22, 0x56, 0x47, 0x75, 0x64, 0x9c, 0x8d, 0xbf, 0xae, 0xda, 0xcb,
347 0xf9, 0xe8, 0x21, 0x30, 0x02, 0x13, 0x67, 0x76, 0x44, 0x55, 0xad, 0xbc, 0x8e, 0x9f, 0xeb,
348 0xfa, 0xc8, 0xd9, 0x31, 0x20, 0x12, 0x03, 0x77, 0x66, 0x54, 0x45, 0xbd, 0xac, 0x9e, 0x8f,
349 0xfb, 0xea, 0xd8, 0xc9, 0x42, 0x53, 0x61, 0x70, 0x04, 0x15, 0x27, 0x36, 0xce, 0xdf, 0xed,
350 0xfc, 0x88, 0x99, 0xab, 0xba, 0x52, 0x43, 0x71, 0x60, 0x14, 0x05, 0x37, 0x26, 0xde, 0xcf,
351 0xfd, 0xec, 0x98, 0x89, 0xbb, 0xaa, 0x63, 0x72, 0x40, 0x51, 0x25, 0x34, 0x06, 0x17, 0xef,
352 0xfe, 0xcc, 0xdd, 0xa9, 0xb8, 0x8a, 0x9b, 0x73, 0x62, 0x50, 0x41, 0x35, 0x24, 0x16, 0x07,
353 0xff, 0xee, 0xdc, 0xcd, 0xb9, 0xa8, 0x9a, 0x8b, 0x84, 0x95, 0xa7, 0xb6, 0xc2, 0xd3, 0xe1,
354 0xf0, 0x08, 0x19, 0x2b, 0x3a, 0x4e, 0x5f, 0x6d, 0x7c, 0x94, 0x85, 0xb7, 0xa6, 0xd2, 0xc3,
355 0xf1, 0xe0, 0x18, 0x09, 0x3b, 0x2a, 0x5e, 0x4f, 0x7d, 0x6c, 0xa5, 0xb4, 0x86, 0x97, 0xe3,
356 0xf2, 0xc0, 0xd1, 0x29, 0x38, 0x0a, 0x1b, 0x6f, 0x7e, 0x4c, 0x5d, 0xb5, 0xa4, 0x96, 0x87,
357 0xf3, 0xe2, 0xd0, 0xc1, 0x39, 0x28, 0x1a, 0x0b, 0x7f, 0x6e, 0x5c, 0x4d, 0xc6, 0xd7, 0xe5,
358 0xf4, 0x80, 0x91, 0xa3, 0xb2, 0x4a, 0x5b, 0x69, 0x78, 0x0c, 0x1d, 0x2f, 0x3e, 0xd6, 0xc7,
359 0xf5, 0xe4, 0x90, 0x81, 0xb3, 0xa2, 0x5a, 0x4b, 0x79, 0x68, 0x1c, 0x0d, 0x3f, 0x2e, 0xe7,
360 0xf6, 0xc4, 0xd5, 0xa1, 0xb0, 0x82, 0x93, 0x6b, 0x7a, 0x48, 0x59, 0x2d, 0x3c, 0x0e, 0x1f,
361 0xf7, 0xe6, 0xd4, 0xc5, 0xb1, 0xa0, 0x92, 0x83, 0x7b, 0x6a, 0x58, 0x49, 0x3d, 0x2c, 0x1e,
364 /*************************************************************************
366 ************************************************************************/
368 static void delay(int ms
)
370 unsigned long timeout
= jiffies
+ ((ms
* HZ
) / 1000);
371 while (jiffies
< timeout
);
378 static void fpga_reset(int iobase
)
380 outb(0, IER(iobase
));
381 outb(LCR_DLAB
| LCR_BIT5
, LCR(iobase
));
382 outb(1, DLL(iobase
));
383 outb(0, DLM(iobase
));
385 outb(LCR_BIT5
, LCR(iobase
));
388 /* turn off FPGA supply voltage */
389 outb(MCR_OUT1
| MCR_OUT2
, MCR(iobase
));
391 /* turn on FPGA supply voltage again */
392 outb(MCR_DTR
| MCR_RTS
| MCR_OUT1
| MCR_OUT2
, MCR(iobase
));
397 * send one byte to FPGA
400 static int fpga_write(int iobase
, unsigned char wrd
)
404 unsigned long timeout
= jiffies
+ HZ
/ 10;
406 for (k
= 0; k
< 8; k
++) {
407 bit
= (wrd
& 0x80) ? (MCR_RTS
| MCR_DTR
) : MCR_DTR
;
408 outb(bit
| MCR_OUT1
| MCR_OUT2
, MCR(iobase
));
410 outb(0xfc, THR(iobase
));
411 while ((inb(LSR(iobase
)) & LSR_TSRE
) == 0)
412 if (jiffies
> timeout
)
420 static void free_mcs(void)
426 yam_data
= yam_data
->next
;
432 static unsigned char *
433 add_mcs(unsigned char *bits
, int bitrate
)
437 /* If it already exists, replace the bit data */
440 if (p
->bitrate
== bitrate
) {
441 memcpy(p
->bits
, bits
, YAM_FPGA_SIZE
);
447 /* Allocate a new mcs */
448 p
= kmalloc(sizeof(struct yam_mcs
), GFP_ATOMIC
);
450 printk(KERN_WARNING
"YAM: no memory to allocate mcs\n");
453 memcpy(p
->bits
, bits
, YAM_FPGA_SIZE
);
454 p
->bitrate
= bitrate
;
461 static unsigned char *get_mcs(int bitrate
)
467 if (p
->bitrate
== bitrate
)
472 /* Load predefined mcs data */
475 return add_mcs(bits_1200
, bitrate
);
477 return add_mcs(bits_9600
, bitrate
);
482 * download bitstream to FPGA
483 * data is contained in bits[] array in fpgaconf.h
486 static int fpga_download(int iobase
, int bitrate
)
489 unsigned char *pbits
;
491 pbits
= get_mcs(bitrate
);
496 for (i
= 0; i
< YAM_FPGA_SIZE
; i
++) {
497 if (fpga_write(iobase
, pbits
[i
])) {
498 printk("yam: error in write cycle\n");
499 return -1; /* write... */
503 fpga_write(iobase
, 0xFF);
504 rc
= inb(MSR(iobase
)); /* check DONE signal */
506 /* Needed for some hardwares */
509 return (rc
& MSR_DSR
) ? 0 : -1;
513 /************************************************************************
515 ************************************************************************/
517 static void yam_set_uart(struct net_device
*dev
)
519 struct yam_port
*yp
= (struct yam_port
*) dev
->priv
;
520 int divisor
= 115200 / yp
->baudrate
;
522 outb(0, IER(dev
->base_addr
));
523 outb(LCR_DLAB
| LCR_BIT8
, LCR(dev
->base_addr
));
524 outb(divisor
, DLL(dev
->base_addr
));
525 outb(0, DLM(dev
->base_addr
));
526 outb(LCR_BIT8
, LCR(dev
->base_addr
));
527 outb(PTT_OFF
, MCR(dev
->base_addr
));
528 outb(0x00, FCR(dev
->base_addr
));
530 /* Flush pending irq */
532 inb(RBR(dev
->base_addr
));
533 inb(MSR(dev
->base_addr
));
537 outb(ENABLE_RTXINT
, IER(dev
->base_addr
));
541 /* --------------------------------------------------------------------- */
544 c_uart_unknown
, c_uart_8250
,
545 c_uart_16450
, c_uart_16550
, c_uart_16550A
548 static const char *uart_str
[] =
549 {"unknown", "8250", "16450", "16550", "16550A"};
551 static enum uart
yam_check_uart(unsigned int iobase
)
553 unsigned char b1
, b2
, b3
;
555 enum uart uart_tab
[] =
556 {c_uart_16450
, c_uart_unknown
, c_uart_16550
, c_uart_16550A
};
558 b1
= inb(MCR(iobase
));
559 outb(b1
| 0x10, MCR(iobase
)); /* loopback mode */
560 b2
= inb(MSR(iobase
));
561 outb(0x1a, MCR(iobase
));
562 b3
= inb(MSR(iobase
)) & 0xf0;
563 outb(b1
, MCR(iobase
)); /* restore old values */
564 outb(b2
, MSR(iobase
));
566 return c_uart_unknown
;
569 outb(0x01, FCR(iobase
)); /* enable FIFOs */
570 u
= uart_tab
[(inb(IIR(iobase
)) >> 6) & 3];
571 if (u
== c_uart_16450
) {
572 outb(0x5a, SCR(iobase
));
573 b1
= inb(SCR(iobase
));
574 outb(0xa5, SCR(iobase
));
575 b2
= inb(SCR(iobase
));
576 if ((b1
!= 0x5a) || (b2
!= 0xa5))
582 /******************************************************************************
584 ******************************************************************************/
586 yam_rx_flag(struct net_device
*dev
, struct yam_port
*yp
)
588 if (yp
->dcd
&& yp
->rx_len
>= 3 && yp
->rx_len
< YAM_MAX_FRAME
) {
589 int pkt_len
= yp
->rx_len
- 2 + 1; /* -CRC + kiss */
592 if ((yp
->rx_crch
& yp
->rx_crcl
) != 0xFF) {
595 if (!(skb
= dev_alloc_skb(pkt_len
))) {
596 printk("%s: memory squeeze, dropping packet\n", dev
->name
);
597 ++yp
->stats
.rx_dropped
;
601 cp
= skb_put(skb
, pkt_len
);
602 *cp
++ = 0; /* KISS kludge */
603 memcpy(cp
, yp
->rx_buf
, pkt_len
- 1);
604 skb
->protocol
= htons(ETH_P_AX25
);
605 skb
->mac
.raw
= skb
->data
;
607 ++yp
->stats
.rx_packets
;
617 yam_rx_byte(struct net_device
*dev
, struct yam_port
*yp
, unsigned char rxb
)
619 if (yp
->rx_len
< YAM_MAX_FRAME
) {
620 unsigned char c
= yp
->rx_crcl
;
621 yp
->rx_crcl
= (chktabl
[c
] ^ yp
->rx_crch
);
622 yp
->rx_crch
= (chktabh
[c
] ^ rxb
);
623 yp
->rx_buf
[yp
->rx_len
++] = rxb
;
627 /********************************************************************************
629 ********************************************************************************/
631 static void ptt_on(struct net_device
*dev
)
633 outb(PTT_ON
, MCR(dev
->base_addr
));
636 static void ptt_off(struct net_device
*dev
)
638 outb(PTT_OFF
, MCR(dev
->base_addr
));
641 static int yam_send_packet(struct sk_buff
*skb
, struct net_device
*dev
)
643 struct yam_port
*yp
= dev
->priv
;
648 skb_queue_tail(&yp
->send_queue
, skb
);
649 dev
->trans_start
= jiffies
;
653 static void yam_start_tx(struct net_device
*dev
, struct yam_port
*yp
)
655 if ((yp
->tx_state
== TX_TAIL
) || (yp
->txd
== 0))
658 yp
->tx_count
= (yp
->bitrate
* yp
->txd
) / 8000;
659 yp
->tx_state
= TX_HEAD
;
663 static unsigned short random_seed
;
665 static inline unsigned short random_num(void)
667 random_seed
= 28629 * random_seed
+ 157;
671 static void yam_arbitrate(struct net_device
*dev
)
673 struct yam_port
*yp
= dev
->priv
;
675 if (!yp
|| yp
->magic
!= YAM_MAGIC
676 || yp
->tx_state
!= TX_OFF
|| skb_queue_empty(&yp
->send_queue
)) {
679 /* tx_state is TX_OFF and there is data to send */
682 /* Full duplex mode, don't wait */
683 yam_start_tx(dev
, yp
);
687 /* DCD on, wait slotime ... */
688 yp
->slotcnt
= yp
->slot
/ 10;
691 /* Is slottime passed ? */
692 if ((--yp
->slotcnt
) > 0)
695 yp
->slotcnt
= yp
->slot
/ 10;
697 /* is random > persist ? */
698 if ((random_num() % 256) > yp
->pers
)
701 yam_start_tx(dev
, yp
);
704 static void yam_dotimer(unsigned long dummy
)
708 for (i
= 0; i
< NR_PORTS
; i
++) {
709 struct net_device
*dev
= &yam_ports
[i
].dev
;
713 yam_timer
.expires
= jiffies
+ HZ
/ 100;
714 add_timer(&yam_timer
);
717 static void yam_tx_byte(struct net_device
*dev
, struct yam_port
*yp
)
720 unsigned char b
, temp
;
722 switch (yp
->tx_state
) {
726 if (--yp
->tx_count
<= 0) {
727 if (!(skb
= skb_dequeue(&yp
->send_queue
))) {
729 yp
->tx_state
= TX_OFF
;
732 yp
->tx_state
= TX_DATA
;
733 if (skb
->data
[0] != 0) {
734 /* do_kiss_params(s, skb->data, skb->len); */
738 yp
->tx_len
= skb
->len
- 1; /* strip KISS byte */
739 if (yp
->tx_len
>= YAM_MAX_FRAME
|| yp
->tx_len
< 2) {
743 memcpy(yp
->tx_buf
, skb
->data
+ 1, yp
->tx_len
);
748 yp
->tx_state
= TX_DATA
;
752 b
= yp
->tx_buf
[yp
->tx_count
++];
753 outb(b
, THR(dev
->base_addr
));
755 yp
->tx_crcl
= chktabl
[temp
] ^ yp
->tx_crch
;
756 yp
->tx_crch
= chktabh
[temp
] ^ b
;
757 if (yp
->tx_count
>= yp
->tx_len
) {
758 yp
->tx_state
= TX_CRC1
;
762 yp
->tx_crch
= chktabl
[yp
->tx_crcl
] ^ yp
->tx_crch
;
763 yp
->tx_crcl
= chktabh
[yp
->tx_crcl
] ^ chktabl
[yp
->tx_crch
] ^ 0xff;
764 outb(yp
->tx_crcl
, THR(dev
->base_addr
));
765 yp
->tx_state
= TX_CRC2
;
768 outb(chktabh
[yp
->tx_crch
] ^ 0xFF, THR(dev
->base_addr
));
769 if (skb_queue_empty(&yp
->send_queue
)) {
770 yp
->tx_count
= (yp
->bitrate
* yp
->txtail
) / 8000;
771 if (yp
->dupmode
== 2)
772 yp
->tx_count
+= (yp
->bitrate
* yp
->holdd
) / 8;
773 if (yp
->tx_count
== 0)
775 yp
->tx_state
= TX_TAIL
;
778 yp
->tx_state
= TX_HEAD
;
780 ++yp
->stats
.tx_packets
;
783 if (--yp
->tx_count
<= 0) {
784 yp
->tx_state
= TX_OFF
;
791 /***********************************************************************************
793 ************************************************************************************/
795 static void yam_interrupt(int irq
, void *dev_id
, struct pt_regs
*regs
)
797 struct net_device
*dev
;
805 for (i
= 0; i
< NR_PORTS
; i
++) {
812 while ((iir
= IIR_MASK
& inb(IIR(dev
->base_addr
))) != IIR_NOPEND
) {
813 unsigned char msr
= inb(MSR(dev
->base_addr
));
814 unsigned char lsr
= inb(LSR(dev
->base_addr
));
818 ++yp
->stats
.rx_fifo_errors
;
820 yp
->dcd
= (msr
& RX_DCD
) ? 1 : 0;
822 if (--counter
<= 0) {
823 printk("%s: too many irq iir=%d\n", dev
->name
, iir
);
828 yam_tx_byte(dev
, yp
);
832 rxb
= inb(RBR(dev
->base_addr
));
834 yam_rx_flag(dev
, yp
);
836 yam_rx_byte(dev
, yp
, rxb
);
842 static int yam_net_get_info(char *buffer
, char **start
, off_t offset
, int length
, int dummy
)
851 for (i
= 0; i
< NR_PORTS
; i
++) {
852 if (yam_ports
[i
].iobase
== 0 || yam_ports
[i
].irq
== 0)
854 len
+= sprintf(buffer
+ len
, "Device %s\n", yam_ports
[i
].name
);
855 len
+= sprintf(buffer
+ len
, " Up %d\n", yam_ports
[i
].dev
.start
);
856 len
+= sprintf(buffer
+ len
, " Speed %u\n", yam_ports
[i
].bitrate
);
857 len
+= sprintf(buffer
+ len
, " IoBase 0x%x\n", yam_ports
[i
].iobase
);
858 len
+= sprintf(buffer
+ len
, " BaudRate %u\n", yam_ports
[i
].baudrate
);
859 len
+= sprintf(buffer
+ len
, " IRQ %u\n", yam_ports
[i
].irq
);
860 len
+= sprintf(buffer
+ len
, " TxState %u\n", yam_ports
[i
].tx_state
);
861 len
+= sprintf(buffer
+ len
, " Duplex %u\n", yam_ports
[i
].dupmode
);
862 len
+= sprintf(buffer
+ len
, " HoldDly %u\n", yam_ports
[i
].holdd
);
863 len
+= sprintf(buffer
+ len
, " TxDelay %u\n", yam_ports
[i
].txd
);
864 len
+= sprintf(buffer
+ len
, " TxTail %u\n", yam_ports
[i
].txtail
);
865 len
+= sprintf(buffer
+ len
, " SlotTime %u\n", yam_ports
[i
].slot
);
866 len
+= sprintf(buffer
+ len
, " Persist %u\n", yam_ports
[i
].pers
);
867 len
+= sprintf(buffer
+ len
, " TxFrames %lu\n", yam_ports
[i
].stats
.tx_packets
);
868 len
+= sprintf(buffer
+ len
, " RxFrames %lu\n", yam_ports
[i
].stats
.rx_packets
);
869 len
+= sprintf(buffer
+ len
, " TxInt %u\n", yam_ports
[i
].nb_mdint
);
870 len
+= sprintf(buffer
+ len
, " RxInt %u\n", yam_ports
[i
].nb_rxint
);
871 len
+= sprintf(buffer
+ len
, " RxOver %lu\n", yam_ports
[i
].stats
.rx_fifo_errors
);
872 len
+= sprintf(buffer
+ len
, "\n");
880 if (pos
> offset
+ length
)
886 *start
= buffer
+ (offset
- begin
);
887 len
-= (offset
- begin
);
896 #ifdef CONFIG_PROC_FS
897 #define yam_net_procfs_init() proc_net_create("yam",0,yam_net_get_info)
898 #define yam_net_procfs_remove() proc_net_remove("yam")
900 #define yam_net_procfs_init()
901 #define yam_net_procfs_remove()
902 #endif /* CONFIG_PROC_FS */
904 #define yam_net_procfs_init()
905 #define yam_net_procfs_remove()
906 #endif /* CONFIG_INET */
908 /* --------------------------------------------------------------------- */
910 #if LINUX_VERSION_CODE >= 0x20119
911 static struct net_device_stats
*
912 yam_get_stats(struct net_device
*dev
)
914 static struct enet_statistics
*
915 yam_get_stats(struct net_device
*dev
)
920 if (!dev
|| !dev
->priv
)
923 yp
= (struct yam_port
*) dev
->priv
;
924 if (yp
->magic
!= YAM_MAGIC
)
928 * Get the current statistics. This may be called with the
929 * card open or closed.
934 /* --------------------------------------------------------------------- */
936 static int yam_open(struct net_device
*dev
)
938 struct yam_port
*yp
= (struct yam_port
*) dev
->priv
;
942 printk(KERN_INFO
"Trying %s at iobase 0x%lx irq %u\n", dev
->name
, dev
->base_addr
, dev
->irq
);
944 if (!dev
|| !yp
|| !yp
->bitrate
)
946 if (!dev
->base_addr
|| dev
->base_addr
> 0x1000 - YAM_EXTENT
||
947 dev
->irq
< 2 || dev
->irq
> 15) {
950 if (check_region(dev
->base_addr
, YAM_EXTENT
)) {
951 printk("%s: cannot 0x%lx busy\n", dev
->name
, dev
->base_addr
);
954 if ((u
= yam_check_uart(dev
->base_addr
)) == c_uart_unknown
) {
955 printk("%s: cannot find uart type\n", dev
->name
);
958 if (fpga_download(dev
->base_addr
, yp
->bitrate
)) {
959 printk("%s: cannot init FPGA\n", dev
->name
);
962 outb(0, IER(dev
->base_addr
));
963 if (request_irq(dev
->irq
, yam_interrupt
, SA_INTERRUPT
| SA_SHIRQ
, dev
->name
, NULL
)) {
964 printk("%s: irq %d busy\n", dev
->name
, dev
->irq
);
967 request_region(dev
->base_addr
, YAM_EXTENT
, dev
->name
);
971 yp
->slotcnt
= yp
->slot
/ 10;
973 /* Reset overruns for all ports - FPGA programming makes overruns */
974 for (i
= 0; i
< NR_PORTS
; i
++) {
975 inb(LSR(yam_ports
[i
].dev
.base_addr
));
976 yam_ports
[i
].stats
.rx_fifo_errors
= 0;
979 printk(KERN_INFO
"%s at iobase 0x%lx irq %u uart %s\n", dev
->name
, dev
->base_addr
, dev
->irq
,
985 /* --------------------------------------------------------------------- */
987 static int yam_close(struct net_device
*dev
)
990 struct yam_port
*yp
= (struct yam_port
*) dev
->priv
;
997 outb(0, IER(dev
->base_addr
));
998 outb(1, MCR(dev
->base_addr
));
999 /* Remove IRQ handler if last */
1000 free_irq(dev
->irq
, NULL
);
1001 release_region(dev
->base_addr
, YAM_EXTENT
);
1004 while ((skb
= skb_dequeue(&yp
->send_queue
)))
1007 printk(KERN_INFO
"%s: close yam at iobase 0x%lx irq %u\n",
1008 yam_drvname
, dev
->base_addr
, dev
->irq
);
1013 /* --------------------------------------------------------------------- */
1015 static int yam_ioctl(struct net_device
*dev
, struct ifreq
*ifr
, int cmd
)
1017 struct yam_port
*yp
= (struct yam_port
*) dev
->priv
;
1018 struct yamdrv_ioctl_cfg yi
;
1019 struct yamdrv_ioctl_mcs
*ym
;
1022 if (copy_from_user(&ioctl_cmd
, ifr
->ifr_data
, sizeof(int)))
1025 if (yp
== NULL
|| yp
->magic
!= YAM_MAGIC
)
1031 if (cmd
!= SIOCDEVPRIVATE
)
1034 switch (ioctl_cmd
) {
1036 case SIOCYAMRESERVED
:
1037 return -EINVAL
; /* unused */
1041 return -EINVAL
; /* Cannot change this parameter when up */
1042 ym
= kmalloc(sizeof(struct yamdrv_ioctl_mcs
), GFP_ATOMIC
);
1044 if (copy_from_user(ym
, ifr
->ifr_data
, sizeof(struct yamdrv_ioctl_mcs
)))
1046 if (ym
->bitrate
> YAM_MAXBITRATE
)
1048 add_mcs(ym
->bits
, ym
->bitrate
);
1053 if (copy_from_user(&yi
, ifr
->ifr_data
, sizeof(struct yamdrv_ioctl_cfg
)))
1056 if ((yi
.cfg
.mask
& YAM_IOBASE
) && dev
->start
)
1057 return -EINVAL
; /* Cannot change this parameter when up */
1058 if ((yi
.cfg
.mask
& YAM_IRQ
) && dev
->start
)
1059 return -EINVAL
; /* Cannot change this parameter when up */
1060 if ((yi
.cfg
.mask
& YAM_BITRATE
) && dev
->start
)
1061 return -EINVAL
; /* Cannot change this parameter when up */
1062 if ((yi
.cfg
.mask
& YAM_BAUDRATE
) && dev
->start
)
1063 return -EINVAL
; /* Cannot change this parameter when up */
1065 if (yi
.cfg
.mask
& YAM_IOBASE
) {
1066 yp
->iobase
= yi
.cfg
.iobase
;
1067 dev
->base_addr
= yi
.cfg
.iobase
;
1069 if (yi
.cfg
.mask
& YAM_IRQ
) {
1070 if (yi
.cfg
.irq
> 15)
1072 yp
->irq
= yi
.cfg
.irq
;
1073 dev
->irq
= yi
.cfg
.irq
;
1075 if (yi
.cfg
.mask
& YAM_BITRATE
) {
1076 if (yi
.cfg
.bitrate
> YAM_MAXBITRATE
)
1078 yp
->bitrate
= yi
.cfg
.bitrate
;
1080 if (yi
.cfg
.mask
& YAM_BAUDRATE
) {
1081 if (yi
.cfg
.baudrate
> YAM_MAXBAUDRATE
)
1083 yp
->baudrate
= yi
.cfg
.baudrate
;
1085 if (yi
.cfg
.mask
& YAM_MODE
) {
1086 if (yi
.cfg
.mode
> YAM_MAXMODE
)
1088 yp
->dupmode
= yi
.cfg
.mode
;
1090 if (yi
.cfg
.mask
& YAM_HOLDDLY
) {
1091 if (yi
.cfg
.holddly
> YAM_MAXHOLDDLY
)
1093 yp
->holdd
= yi
.cfg
.holddly
;
1095 if (yi
.cfg
.mask
& YAM_TXDELAY
) {
1096 if (yi
.cfg
.txdelay
> YAM_MAXTXDELAY
)
1098 yp
->txd
= yi
.cfg
.txdelay
;
1100 if (yi
.cfg
.mask
& YAM_TXTAIL
) {
1101 if (yi
.cfg
.txtail
> YAM_MAXTXTAIL
)
1103 yp
->txtail
= yi
.cfg
.txtail
;
1105 if (yi
.cfg
.mask
& YAM_PERSIST
) {
1106 if (yi
.cfg
.persist
> YAM_MAXPERSIST
)
1108 yp
->pers
= yi
.cfg
.persist
;
1110 if (yi
.cfg
.mask
& YAM_SLOTTIME
) {
1111 if (yi
.cfg
.slottime
> YAM_MAXSLOTTIME
)
1113 yp
->slot
= yi
.cfg
.slottime
;
1114 yp
->slotcnt
= yp
->slot
/ 10;
1119 yi
.cfg
.mask
= 0xffffffff;
1120 yi
.cfg
.iobase
= yp
->iobase
;
1121 yi
.cfg
.irq
= yp
->irq
;
1122 yi
.cfg
.bitrate
= yp
->bitrate
;
1123 yi
.cfg
.baudrate
= yp
->baudrate
;
1124 yi
.cfg
.mode
= yp
->dupmode
;
1125 yi
.cfg
.txdelay
= yp
->txd
;
1126 yi
.cfg
.holddly
= yp
->holdd
;
1127 yi
.cfg
.txtail
= yp
->txtail
;
1128 yi
.cfg
.persist
= yp
->pers
;
1129 yi
.cfg
.slottime
= yp
->slot
;
1130 if (copy_to_user(ifr
->ifr_data
, &yi
, sizeof(struct yamdrv_ioctl_cfg
)))
1142 /* --------------------------------------------------------------------- */
1144 static int yam_set_mac_address(struct net_device
*dev
, void *addr
)
1146 struct sockaddr
*sa
= (struct sockaddr
*) addr
;
1148 /* addr is an AX.25 shifted ASCII mac address */
1149 memcpy(dev
->dev_addr
, sa
->sa_data
, dev
->addr_len
);
1153 /* --------------------------------------------------------------------- */
1155 static int yam_probe(struct net_device
*dev
)
1157 struct yam_port
*yp
;
1162 yp
= (struct yam_port
*) dev
->priv
;
1164 dev
->open
= yam_open
;
1165 dev
->stop
= yam_close
;
1166 dev
->do_ioctl
= yam_ioctl
;
1167 dev
->hard_start_xmit
= yam_send_packet
;
1168 dev
->get_stats
= yam_get_stats
;
1170 dev_init_buffers(dev
);
1171 skb_queue_head_init(&yp
->send_queue
);
1173 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
1174 dev
->hard_header
= ax25_encapsulate
;
1175 dev
->rebuild_header
= ax25_rebuild_header
;
1176 #else /* CONFIG_AX25 || CONFIG_AX25_MODULE */
1177 dev
->hard_header
= NULL
;
1178 dev
->rebuild_header
= NULL
;
1179 #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
1181 dev
->set_mac_address
= yam_set_mac_address
;
1183 dev
->type
= ARPHRD_AX25
; /* AF_AX25 device */
1184 dev
->hard_header_len
= 73; /* We do digipeaters now */
1185 dev
->mtu
= 256; /* AX25 is the default */
1186 dev
->addr_len
= 7; /* sizeof an ax.25 address */
1187 memcpy(dev
->broadcast
, ax25_bcast
, 7);
1188 memcpy(dev
->dev_addr
, ax25_test
, 7);
1190 /* New style flags */
1196 /* --------------------------------------------------------------------- */
1198 int __init
yam_init(struct net_device
*dev
)
1202 printk(yam_drvinfo
);
1204 /* Clears the IRQ table */
1205 memset(irqs
, 0, sizeof(irqs
));
1206 memset(yam_ports
, 0, sizeof(yam_ports
));
1208 for (i
= 0; i
< NR_PORTS
; i
++) {
1209 sprintf(yam_ports
[i
].name
, "yam%d", i
);
1210 yam_ports
[i
].magic
= YAM_MAGIC
;
1211 yam_ports
[i
].bitrate
= DEFAULT_BITRATE
;
1212 yam_ports
[i
].baudrate
= DEFAULT_BITRATE
* 2;
1213 yam_ports
[i
].iobase
= 0;
1214 yam_ports
[i
].irq
= 0;
1215 yam_ports
[i
].dupmode
= 0;
1216 yam_ports
[i
].holdd
= DEFAULT_HOLDD
;
1217 yam_ports
[i
].txd
= DEFAULT_TXD
;
1218 yam_ports
[i
].txtail
= DEFAULT_TXTAIL
;
1219 yam_ports
[i
].slot
= DEFAULT_SLOT
;
1220 yam_ports
[i
].pers
= DEFAULT_PERS
;
1222 dev
= &yam_ports
[i
].dev
;
1224 dev
->priv
= &yam_ports
[i
];
1225 dev
->name
= yam_ports
[i
].name
;
1226 dev
->base_addr
= yam_ports
[i
].iobase
;
1227 dev
->irq
= yam_ports
[i
].irq
;
1228 dev
->init
= yam_probe
;
1233 if (register_netdev(dev
)) {
1234 printk(KERN_WARNING
"yam: cannot register net device %s\n", dev
->name
);
1239 yam_timer
.function
= yam_dotimer
;
1240 yam_timer
.expires
= jiffies
+ HZ
/ 100;
1241 add_timer(&yam_timer
);
1243 yam_net_procfs_init();
1245 /* do not keep this device */
1249 /* --------------------------------------------------------------------- */
1254 * command line settable parameters
1257 #if LINUX_VERSION_CODE >= 0x20115
1259 MODULE_AUTHOR("Frederic Rible F1OAT frible@teaser.fr");
1260 MODULE_DESCRIPTION("Yam amateur radio modem driver");
1264 int init_module(void)
1266 int ret
= yam_init(NULL
);
1268 return (ret
== 1) ? 0 : ret
;
1271 /* --------------------------------------------------------------------- */
1273 void cleanup_module(void)
1277 del_timer(&yam_timer
);
1278 for (i
= 0; i
< NR_PORTS
; i
++) {
1279 struct net_device
*dev
= &yam_ports
[i
].dev
;
1284 unregister_netdev(dev
);
1287 yam_net_procfs_remove();
1291 /* --------------------------------------------------------------------- */