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
);
898 #define PROC_NET_YAM (PROC_NET_LAST+10) /* Sorry again... */
901 #ifdef CONFIG_PROC_FS
902 struct proc_dir_entry yam_proc_dir_entry
=
904 PROC_NET_YAM
, 3, "yam", S_IFREG
| S_IRUGO
, 1, 0, 0, 0,
905 &proc_net_inode_operations
, yam_net_get_info
908 #define yam_net_procfs_init() proc_net_register(&yam_proc_dir_entry);
909 #define yam_net_procfs_remove() proc_net_unregister(PROC_NET_YAM);
911 #define yam_net_procfs_init()
912 #define yam_net_procfs_remove()
915 #define yam_net_procfs_init()
916 #define yam_net_procfs_remove()
919 /* --------------------------------------------------------------------- */
921 #if LINUX_VERSION_CODE >= 0x20119
922 static struct net_device_stats
*
923 yam_get_stats(struct net_device
*dev
)
925 static struct enet_statistics
*
926 yam_get_stats(struct net_device
*dev
)
931 if (!dev
|| !dev
->priv
)
934 yp
= (struct yam_port
*) dev
->priv
;
935 if (yp
->magic
!= YAM_MAGIC
)
939 * Get the current statistics. This may be called with the
940 * card open or closed.
945 /* --------------------------------------------------------------------- */
947 static int yam_open(struct net_device
*dev
)
949 struct yam_port
*yp
= (struct yam_port
*) dev
->priv
;
953 printk(KERN_INFO
"Trying %s at iobase 0x%lx irq %u\n", dev
->name
, dev
->base_addr
, dev
->irq
);
955 if (!dev
|| !yp
|| !yp
->bitrate
)
957 if (!dev
->base_addr
|| dev
->base_addr
> 0x1000 - YAM_EXTENT
||
958 dev
->irq
< 2 || dev
->irq
> 15) {
961 if (check_region(dev
->base_addr
, YAM_EXTENT
)) {
962 printk("%s: cannot 0x%lx busy\n", dev
->name
, dev
->base_addr
);
965 if ((u
= yam_check_uart(dev
->base_addr
)) == c_uart_unknown
) {
966 printk("%s: cannot find uart type\n", dev
->name
);
969 if (fpga_download(dev
->base_addr
, yp
->bitrate
)) {
970 printk("%s: cannot init FPGA\n", dev
->name
);
973 outb(0, IER(dev
->base_addr
));
974 if (request_irq(dev
->irq
, yam_interrupt
, SA_INTERRUPT
| SA_SHIRQ
, dev
->name
, NULL
)) {
975 printk("%s: irq %d busy\n", dev
->name
, dev
->irq
);
978 request_region(dev
->base_addr
, YAM_EXTENT
, dev
->name
);
982 yp
->slotcnt
= yp
->slot
/ 10;
984 /* Reset overruns for all ports - FPGA programming makes overruns */
985 for (i
= 0; i
< NR_PORTS
; i
++) {
986 inb(LSR(yam_ports
[i
].dev
.base_addr
));
987 yam_ports
[i
].stats
.rx_fifo_errors
= 0;
990 printk(KERN_INFO
"%s at iobase 0x%lx irq %u uart %s\n", dev
->name
, dev
->base_addr
, dev
->irq
,
996 /* --------------------------------------------------------------------- */
998 static int yam_close(struct net_device
*dev
)
1000 struct sk_buff
*skb
;
1001 struct yam_port
*yp
= (struct yam_port
*) dev
->priv
;
1006 * disable interrupts
1008 outb(0, IER(dev
->base_addr
));
1009 outb(1, MCR(dev
->base_addr
));
1010 /* Remove IRQ handler if last */
1011 free_irq(dev
->irq
, NULL
);
1012 release_region(dev
->base_addr
, YAM_EXTENT
);
1015 while ((skb
= skb_dequeue(&yp
->send_queue
)))
1018 printk(KERN_INFO
"%s: close yam at iobase 0x%lx irq %u\n",
1019 yam_drvname
, dev
->base_addr
, dev
->irq
);
1024 /* --------------------------------------------------------------------- */
1026 static int yam_ioctl(struct net_device
*dev
, struct ifreq
*ifr
, int cmd
)
1028 struct yam_port
*yp
= (struct yam_port
*) dev
->priv
;
1029 struct yamdrv_ioctl_cfg yi
;
1030 struct yamdrv_ioctl_mcs
*ym
;
1033 if (copy_from_user(&ioctl_cmd
, ifr
->ifr_data
, sizeof(int)))
1036 if (yp
== NULL
|| yp
->magic
!= YAM_MAGIC
)
1042 if (cmd
!= SIOCDEVPRIVATE
)
1045 switch (ioctl_cmd
) {
1047 case SIOCYAMRESERVED
:
1048 return -EINVAL
; /* unused */
1052 return -EINVAL
; /* Cannot change this parameter when up */
1053 ym
= kmalloc(sizeof(struct yamdrv_ioctl_mcs
), GFP_ATOMIC
);
1055 if (copy_from_user(ym
, ifr
->ifr_data
, sizeof(struct yamdrv_ioctl_mcs
)))
1057 if (ym
->bitrate
> YAM_MAXBITRATE
)
1059 add_mcs(ym
->bits
, ym
->bitrate
);
1064 if (copy_from_user(&yi
, ifr
->ifr_data
, sizeof(struct yamdrv_ioctl_cfg
)))
1067 if ((yi
.cfg
.mask
& YAM_IOBASE
) && dev
->start
)
1068 return -EINVAL
; /* Cannot change this parameter when up */
1069 if ((yi
.cfg
.mask
& YAM_IRQ
) && dev
->start
)
1070 return -EINVAL
; /* Cannot change this parameter when up */
1071 if ((yi
.cfg
.mask
& YAM_BITRATE
) && dev
->start
)
1072 return -EINVAL
; /* Cannot change this parameter when up */
1073 if ((yi
.cfg
.mask
& YAM_BAUDRATE
) && dev
->start
)
1074 return -EINVAL
; /* Cannot change this parameter when up */
1076 if (yi
.cfg
.mask
& YAM_IOBASE
) {
1077 yp
->iobase
= yi
.cfg
.iobase
;
1078 dev
->base_addr
= yi
.cfg
.iobase
;
1080 if (yi
.cfg
.mask
& YAM_IRQ
) {
1081 if (yi
.cfg
.irq
> 15)
1083 yp
->irq
= yi
.cfg
.irq
;
1084 dev
->irq
= yi
.cfg
.irq
;
1086 if (yi
.cfg
.mask
& YAM_BITRATE
) {
1087 if (yi
.cfg
.bitrate
> YAM_MAXBITRATE
)
1089 yp
->bitrate
= yi
.cfg
.bitrate
;
1091 if (yi
.cfg
.mask
& YAM_BAUDRATE
) {
1092 if (yi
.cfg
.baudrate
> YAM_MAXBAUDRATE
)
1094 yp
->baudrate
= yi
.cfg
.baudrate
;
1096 if (yi
.cfg
.mask
& YAM_MODE
) {
1097 if (yi
.cfg
.mode
> YAM_MAXMODE
)
1099 yp
->dupmode
= yi
.cfg
.mode
;
1101 if (yi
.cfg
.mask
& YAM_HOLDDLY
) {
1102 if (yi
.cfg
.holddly
> YAM_MAXHOLDDLY
)
1104 yp
->holdd
= yi
.cfg
.holddly
;
1106 if (yi
.cfg
.mask
& YAM_TXDELAY
) {
1107 if (yi
.cfg
.txdelay
> YAM_MAXTXDELAY
)
1109 yp
->txd
= yi
.cfg
.txdelay
;
1111 if (yi
.cfg
.mask
& YAM_TXTAIL
) {
1112 if (yi
.cfg
.txtail
> YAM_MAXTXTAIL
)
1114 yp
->txtail
= yi
.cfg
.txtail
;
1116 if (yi
.cfg
.mask
& YAM_PERSIST
) {
1117 if (yi
.cfg
.persist
> YAM_MAXPERSIST
)
1119 yp
->pers
= yi
.cfg
.persist
;
1121 if (yi
.cfg
.mask
& YAM_SLOTTIME
) {
1122 if (yi
.cfg
.slottime
> YAM_MAXSLOTTIME
)
1124 yp
->slot
= yi
.cfg
.slottime
;
1125 yp
->slotcnt
= yp
->slot
/ 10;
1130 yi
.cfg
.mask
= 0xffffffff;
1131 yi
.cfg
.iobase
= yp
->iobase
;
1132 yi
.cfg
.irq
= yp
->irq
;
1133 yi
.cfg
.bitrate
= yp
->bitrate
;
1134 yi
.cfg
.baudrate
= yp
->baudrate
;
1135 yi
.cfg
.mode
= yp
->dupmode
;
1136 yi
.cfg
.txdelay
= yp
->txd
;
1137 yi
.cfg
.holddly
= yp
->holdd
;
1138 yi
.cfg
.txtail
= yp
->txtail
;
1139 yi
.cfg
.persist
= yp
->pers
;
1140 yi
.cfg
.slottime
= yp
->slot
;
1141 if (copy_to_user(ifr
->ifr_data
, &yi
, sizeof(struct yamdrv_ioctl_cfg
)))
1153 /* --------------------------------------------------------------------- */
1155 static int yam_set_mac_address(struct net_device
*dev
, void *addr
)
1157 struct sockaddr
*sa
= (struct sockaddr
*) addr
;
1159 /* addr is an AX.25 shifted ASCII mac address */
1160 memcpy(dev
->dev_addr
, sa
->sa_data
, dev
->addr_len
);
1164 /* --------------------------------------------------------------------- */
1166 static int yam_probe(struct net_device
*dev
)
1168 struct yam_port
*yp
;
1173 yp
= (struct yam_port
*) dev
->priv
;
1175 dev
->open
= yam_open
;
1176 dev
->stop
= yam_close
;
1177 dev
->do_ioctl
= yam_ioctl
;
1178 dev
->hard_start_xmit
= yam_send_packet
;
1179 dev
->get_stats
= yam_get_stats
;
1181 dev_init_buffers(dev
);
1182 skb_queue_head_init(&yp
->send_queue
);
1184 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
1185 dev
->hard_header
= ax25_encapsulate
;
1186 dev
->rebuild_header
= ax25_rebuild_header
;
1187 #else /* CONFIG_AX25 || CONFIG_AX25_MODULE */
1188 dev
->hard_header
= NULL
;
1189 dev
->rebuild_header
= NULL
;
1190 #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
1192 dev
->set_mac_address
= yam_set_mac_address
;
1194 dev
->type
= ARPHRD_AX25
; /* AF_AX25 device */
1195 dev
->hard_header_len
= 73; /* We do digipeaters now */
1196 dev
->mtu
= 256; /* AX25 is the default */
1197 dev
->addr_len
= 7; /* sizeof an ax.25 address */
1198 memcpy(dev
->broadcast
, ax25_bcast
, 7);
1199 memcpy(dev
->dev_addr
, ax25_test
, 7);
1201 /* New style flags */
1207 /* --------------------------------------------------------------------- */
1209 int __init
yam_init(struct net_device
*dev
)
1213 printk(yam_drvinfo
);
1215 /* Clears the IRQ table */
1216 memset(irqs
, 0, sizeof(irqs
));
1217 memset(yam_ports
, 0, sizeof(yam_ports
));
1219 for (i
= 0; i
< NR_PORTS
; i
++) {
1220 sprintf(yam_ports
[i
].name
, "yam%d", i
);
1221 yam_ports
[i
].magic
= YAM_MAGIC
;
1222 yam_ports
[i
].bitrate
= DEFAULT_BITRATE
;
1223 yam_ports
[i
].baudrate
= DEFAULT_BITRATE
* 2;
1224 yam_ports
[i
].iobase
= 0;
1225 yam_ports
[i
].irq
= 0;
1226 yam_ports
[i
].dupmode
= 0;
1227 yam_ports
[i
].holdd
= DEFAULT_HOLDD
;
1228 yam_ports
[i
].txd
= DEFAULT_TXD
;
1229 yam_ports
[i
].txtail
= DEFAULT_TXTAIL
;
1230 yam_ports
[i
].slot
= DEFAULT_SLOT
;
1231 yam_ports
[i
].pers
= DEFAULT_PERS
;
1233 dev
= &yam_ports
[i
].dev
;
1235 dev
->priv
= &yam_ports
[i
];
1236 dev
->name
= yam_ports
[i
].name
;
1237 dev
->base_addr
= yam_ports
[i
].iobase
;
1238 dev
->irq
= yam_ports
[i
].irq
;
1239 dev
->init
= yam_probe
;
1244 if (register_netdev(dev
)) {
1245 printk(KERN_WARNING
"yam: cannot register net device %s\n", dev
->name
);
1250 yam_timer
.function
= yam_dotimer
;
1251 yam_timer
.expires
= jiffies
+ HZ
/ 100;
1252 add_timer(&yam_timer
);
1254 yam_net_procfs_init();
1256 /* do not keep this device */
1260 /* --------------------------------------------------------------------- */
1265 * command line settable parameters
1268 #if LINUX_VERSION_CODE >= 0x20115
1270 MODULE_AUTHOR("Frederic Rible F1OAT frible@teaser.fr");
1271 MODULE_DESCRIPTION("Yam amateur radio modem driver");
1275 int init_module(void)
1277 int ret
= yam_init(NULL
);
1279 return (ret
== 1) ? 0 : ret
;
1282 /* --------------------------------------------------------------------- */
1284 void cleanup_module(void)
1288 del_timer(&yam_timer
);
1289 for (i
= 0; i
< NR_PORTS
; i
++) {
1290 struct net_device
*dev
= &yam_ports
[i
].dev
;
1295 unregister_netdev(dev
);
1298 yam_net_procfs_remove();
1302 /* --------------------------------------------------------------------- */