15 #include <linux/module.h>
16 #include <asm/uaccess.h>
17 #include <linux/bitops.h>
18 #include <linux/string.h>
22 #include <linux/tty.h>
23 #include <linux/errno.h>
24 #include <linux/netdevice.h>
26 #include <linux/slab.h>
30 #include <linux/rtnetlink.h>
32 #include <linux/if_arp.h>
35 #include <linux/tcp.h>
40 #define SIXPACK_VERSION "Revision: 0.3.0"
43 #define SIXP_SEOF 0x40
44 #define SIXP_TX_URUN 0x48
45 #define SIXP_RX_ORUN 0x50
46 #define SIXP_RX_BUF_OVL 0x58
48 #define SIXP_CHKSUM 0xFF
52 #define SIXP_CMD_MASK 0xC0
53 #define SIXP_CHN_MASK 0x07
54 #define SIXP_PRIO_CMD_MASK 0x80
55 #define SIXP_STD_CMD_MASK 0x40
56 #define SIXP_PRIO_DATA_MASK 0x38
57 #define SIXP_TX_MASK 0x20
58 #define SIXP_RX_MASK 0x10
59 #define SIXP_RX_DCD_MASK 0x18
60 #define SIXP_LEDS_ON 0x78
61 #define SIXP_LEDS_OFF 0x60
65 #define SIXP_FOUND_TNC 0xe9
66 #define SIXP_CON_ON 0x68
67 #define SIXP_DCD_MASK 0x08
68 #define SIXP_DAMA_OFF 0
71 #define SIXP_TXDELAY (HZ/4)
72 #define SIXP_PERSIST 50
73 #define SIXP_SLOTTIME (HZ/10)
74 #define SIXP_INIT_RESYNC_TIMEOUT (3*HZ/2)
75 #define SIXP_RESYNC_TIMEOUT 5*HZ
78 #define SIXP_NRUNIT 31
128 #define AX25_6PACK_HEADER_LEN 0
130 static void sixpack_decode(
struct sixpack *,
unsigned char[],
int);
131 static int encode_sixpack(
unsigned char *,
unsigned char *,
int,
unsigned char);
139 static void sp_xmit_on_air(
unsigned long channel)
143 static unsigned char random;
145 random = random * 17 + 41;
164 static void sp_encaps(
struct sixpack *sp,
unsigned char *icp,
int len)
166 unsigned char *
msg, *
p = icp;
170 msg =
"oversized transmit packet!";
175 msg =
"oversized transmit packet!";
180 msg =
"invalid KISS command";
184 if ((p[0] != 0) && (len > 2)) {
185 msg =
"KISS control packet too long";
189 if ((p[0] == 0) && (len < 15)) {
190 msg =
"bad AX.25 packet to transmit";
206 case 5: sp->
duplex = p[1];
223 actual = sp->
tty->ops->write(sp->
tty, sp->
xbuff, count);
224 sp->
xleft = count - actual;
232 sp_xmit_on_air((
unsigned long)sp);
238 sp->
dev->stats.tx_dropped++;
239 netif_start_queue(sp->
dev);
248 struct sixpack *sp = netdev_priv(dev);
250 spin_lock_bh(&sp->
lock);
252 netif_stop_queue(dev);
254 sp_encaps(sp, skb->
data, skb->
len);
255 spin_unlock_bh(&sp->
lock);
264 struct sixpack *sp = netdev_priv(dev);
274 struct sixpack *sp = netdev_priv(dev);
276 spin_lock_bh(&sp->
lock);
281 netif_stop_queue(dev);
282 spin_unlock_bh(&sp->
lock);
290 const void *
saddr,
unsigned len)
303 netif_tx_lock_bh(dev);
304 netif_addr_lock(dev);
306 netif_addr_unlock(dev);
307 netif_tx_unlock_bh(dev);
312 static int sp_rebuild_header(
struct sk_buff *skb)
321 static const struct header_ops sp_header_ops = {
323 .rebuild = sp_rebuild_header,
327 .ndo_open = sp_open_dev,
328 .ndo_stop = sp_close,
329 .ndo_start_xmit = sp_xmit,
330 .ndo_set_mac_address = sp_set_mac_address,
360 static void sp_bump(
struct sixpack *sp,
char cmd)
370 if ((skb = dev_alloc_skb(count)) ==
NULL)
379 sp->
dev->stats.rx_packets++;
384 sp->
dev->stats.rx_dropped++;
413 static void sp_put(
struct sixpack *sp)
423 static void sixpack_write_wakeup(
struct tty_struct *tty)
425 struct sixpack *sp = sp_get(tty);
430 if (sp->
xleft <= 0) {
433 sp->
dev->stats.tx_packets++;
436 netif_wake_queue(sp->
dev);
458 static void sixpack_receive_buf(
struct tty_struct *tty,
459 const unsigned char *
cp,
char *
fp,
int count)
462 unsigned char buf[512];
472 memcpy(buf, cp, count <
sizeof(buf) ? count :
sizeof(buf));
481 sp->
dev->stats.rx_errors++;
485 sixpack_decode(sp, buf, count1);
496 #define TNC_UNINITIALIZED 0
497 #define TNC_UNSYNC_STARTUP 1
498 #define TNC_UNSYNCED 2
499 #define TNC_IN_SYNC 3
501 static void __tnc_set_sync_state(
struct sixpack *sp,
int new_tnc_state)
505 switch (new_tnc_state) {
508 msg =
"Synchronizing with TNC";
511 msg =
"Lost synchronization with TNC\n";
522 static inline void tnc_set_sync_state(
struct sixpack *sp,
int new_tnc_state)
526 if (old_tnc_state != new_tnc_state)
527 __tnc_set_sync_state(sp, new_tnc_state);
530 static void resync_tnc(
unsigned long channel)
533 static char resync_cmd = 0xe8;
550 sp->
tty->ops->write(sp->
tty, &resync_cmd, 1);
562 static inline int tnc_init(
struct sixpack *sp)
564 unsigned char inbyte = 0xe8;
568 sp->
tty->ops->write(sp->
tty, &inbyte, 1);
586 static int sixpack_open(
struct tty_struct *tty)
605 sp = netdev_priv(dev);
619 if (rbuff ==
NULL || xbuff ==
NULL) {
624 spin_lock_bh(&sp->
lock);
650 netif_start_queue(dev);
653 sp->
tx_t.function = sp_xmit_on_air;
658 spin_unlock_bh(&sp->
lock);
690 static void sixpack_close(
struct tty_struct *tty)
720 unsigned int cmd,
unsigned long arg)
722 struct sixpack *sp = sp_get(tty);
737 err =
put_user(0, (
int __user *) arg);
741 if (
get_user(tmp, (
int __user *) arg)) {
764 netif_tx_lock_bh(dev);
766 netif_tx_unlock_bh(dev);
782 static long sixpack_compat_ioctl(
struct tty_struct * tty,
struct file * file,
783 unsigned int cmd,
unsigned long arg)
790 return sixpack_ioctl(tty, file, cmd,
791 (
unsigned long)compat_ptr(arg));
802 .open = sixpack_open,
803 .close = sixpack_close,
804 .ioctl = sixpack_ioctl,
806 .compat_ioctl = sixpack_compat_ioctl,
808 .receive_buf = sixpack_receive_buf,
809 .write_wakeup = sixpack_write_wakeup,
816 static const char msg_regfail[] __initconst =
KERN_ERR \
817 "6pack: can't register line discipline (err = %d)\n";
819 static int __init sixpack_init_driver(
void)
827 printk(msg_regfail, status);
832 static const char msg_unregfail[] =
KERN_ERR \
833 "6pack: can't unregister line discipline (err = %d)\n";
835 static void __exit sixpack_exit_driver(
void)
840 printk(msg_unregfail, ret);
845 static int encode_sixpack(
unsigned char *
tx_buf,
unsigned char *tx_buf_raw,
846 int length,
unsigned char tx_delay)
849 unsigned char checksum = 0, buf[400];
856 for (count = 1; count <
length; count++)
857 buf[count] = tx_buf[count];
859 for (count = 0; count <
length; count++)
860 checksum += buf[count];
861 buf[
length] = (
unsigned char) 0xff - checksum;
863 for (count = 0; count <=
length; count++) {
864 if ((count % 3) == 0) {
865 tx_buf_raw[raw_count++] = (buf[
count] & 0x3f);
866 tx_buf_raw[raw_count] = ((buf[
count] >> 2) & 0x30);
867 }
else if ((count % 3) == 1) {
868 tx_buf_raw[raw_count++] |= (buf[
count] & 0x0f);
869 tx_buf_raw[raw_count] = ((buf[
count] >> 2) & 0x3c);
871 tx_buf_raw[raw_count++] |= (buf[
count] & 0x03);
872 tx_buf_raw[raw_count++] = (buf[
count] >> 2);
875 if ((length % 3) != 2)
883 static void decode_data(
struct sixpack *sp,
unsigned char inbyte)
895 buf[0] | ((buf[1] << 2) & 0xc0);
897 (buf[1] & 0x0f) | ((buf[2] << 2) & 0xf0);
899 (buf[2] & 0x03) | (inbyte << 2);
905 static void decode_prio_command(
struct sixpack *sp,
unsigned char cmd)
926 cmd &= ~SIXP_RX_DCD_MASK;
962 static void decode_std_command(
struct sixpack *sp,
unsigned char cmd)
971 if ((sp->
status & SIXP_RX_DCD_MASK) ==
982 for (i =
rest; i <= 3; i++)
1011 sixpack_decode(
struct sixpack *sp,
unsigned char *pre_rbuff,
int count)
1013 unsigned char inbyte;
1016 for (count1 = 0; count1 <
count; count1++) {
1017 inbyte = pre_rbuff[
count1];
1023 decode_prio_command(sp, inbyte);
1025 decode_std_command(sp, inbyte);
1026 else if ((sp->
status & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)
1027 decode_data(sp, inbyte);