/* some arch define END as assembly function ending, just undef it */ #undef END /* SLIP/KISS protocol characters. */ #define END 0300 /* indicates end of frame */ #define ESC 0333 /* indicates byte stuffing */ #define ESC_END 0334 /* ESC ESC_END means END 'data' */ #define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
/* These are pointers to the malloc()ed frame buffers. */
spinlock_t buflock;/* lock for rbuf and xbuf */ unsignedchar *rbuff; /* receiver buffer */ int rcount; /* received chars counter */ unsignedchar *xbuff; /* transmitter buffer */ unsignedchar *xhead; /* pointer to next byte to XMIT */ int xleft; /* bytes left in XMIT queue */
/* Detailed SLIP statistics. */ int mtu; /* Our mtu (to spot changes!) */ int buffsize; /* Max buffers sizes */
unsignedlong flags; /* Flag values/ mode etc */ /* long req'd: used by set_bit --RR */ #define AXF_INUSE 0 /* Channel in use */ #define AXF_ESCAPE 1 /* ESC received */ #define AXF_ERROR 2 /* Parity, etc. error */ #define AXF_KEEPTEST 3 /* Keepalive test flag */ #define AXF_OUTWAIT 4 /* is outpacket was flag */
int mode; int crcmode; /* MW: for FlexNet, SMACK etc. */ int crcauto; /* CRC auto mode */
/* * MW: * OK its ugly, but tell me a better solution without copying the * packet to a temporary buffer :-)
*/ staticint kiss_esc_crc(unsignedchar *s, unsignedchar *d, unsignedshort crc, int len)
{ unsignedchar *ptr = d; unsignedchar c=0;
*ptr++ = END; while (len > 0) { if (len > 2)
c = *s++; elseif (len > 1)
c = crc >> 8; else
c = crc & 0xff;
/* * dl9sau bugfix: the trailling two bytes flexnet crc * will not be passed to the kernel. thus we have to * correct the kissparm signature, because it indicates * a crc but there's none
*/
*ax->rbuff &= ~0x20;
}
}
staticvoid kiss_unesc(struct mkiss *ax, unsignedchar s)
{ switch (s) { case END: /* drop keeptest bit = VSV */ if (test_bit(AXF_KEEPTEST, &ax->flags))
clear_bit(AXF_KEEPTEST, &ax->flags);
if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2))
ax_bump(ax);
case ESC:
set_bit(AXF_ESCAPE, &ax->flags); return; case ESC_ESC: if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
s = ESC; break; case ESC_END: if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
s = END; break;
}
spin_lock_bh(&ax->buflock); if (!test_bit(AXF_ERROR, &ax->flags)) { if (ax->rcount < ax->buffsize) {
ax->rbuff[ax->rcount++] = s;
spin_unlock_bh(&ax->buflock); return;
}
/* * allow for arrival of larger UDP packets, even if we say not to * also fixes a bug in which SunOS sends 512-byte packets even with * an MSS of 128
*/ if (len < 576 * 2)
len = 576 * 2;
spin_lock_bh(&ax->buflock); if ((*p & 0x0f) != 0) { /* Configuration Command (kissparms(1). * Protocol spec says: never append CRC. * This fixes a very old bug in the linux
* kiss driver. -- dl9sau */ switch (*p & 0xff) { case 0x85: /* command from userspace especially for us,
* not for delivery to the tnc */ if (len > 1) { int cmd = (p[1] & 0xff); switch(cmd) { case 3:
ax->crcmode = CRC_MODE_SMACK; break; case 2:
ax->crcmode = CRC_MODE_FLEX; break; case 1:
ax->crcmode = CRC_MODE_NONE; break; case 0: default:
ax->crcmode = CRC_MODE_SMACK_TEST;
cmd = 0;
}
ax->crcauto = (cmd ? 0 : 1);
printk(KERN_INFO "mkiss: %s: crc mode set to %d\n",
ax->dev->name, cmd);
}
spin_unlock_bh(&ax->buflock);
netif_start_queue(dev);
/* Encapsulate an AX.25 packet and kick it into a TTY queue. */ static netdev_tx_t ax_xmit(struct sk_buff *skb, struct net_device *dev)
{ struct mkiss *ax = netdev_priv(dev);
if (skb->protocol == htons(ETH_P_IP)) return ax25_ip_xmit(skb);
if (!netif_running(dev)) {
printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); return NETDEV_TX_BUSY;
}
if (netif_queue_stopped(dev)) { /* * May be we must check transmitter timeout here ? * 14 Oct 1994 Dmitry Gorodchanin.
*/ if (time_before(jiffies, dev_trans_start(dev) + 20 * HZ)) { /* 20 sec timeout not reached */ return NETDEV_TX_BUSY;
}
/* Open the low-level part of the AX25 channel. Easy! */ staticint ax_open(struct net_device *dev)
{ struct mkiss *ax = netdev_priv(dev); unsignedlong len;
/* * allow for arrival of larger UDP packets, even if we say not to * also fixes a bug in which SunOS sends 512-byte packets even with * an MSS of 128
*/ if (len < 576 * 2)
len = 576 * 2;
/* * We have a potential race on dereferencing tty->disc_data, because the tty * layer provides no locking at all - thus one cpu could be running * sixpack_receive_buf while another calls sixpack_close, which zeroes * tty->disc_data and frees the memory that sixpack_receive_buf is using. The * best way to fix this is to use a rwlock in the tty struct, but for now we * use a single global rwlock for all ttys in ppp line discipline.
*/ static DEFINE_RWLOCK(disc_data_lock);
/* * We have now ensured that nobody can start using ap from now on, but * we have to wait for all existing users to finish.
*/ if (!refcount_dec_and_test(&ax->refcnt))
wait_for_completion(&ax->dead); /* * Halt the transmit queue so that a new transmit cannot scribble * on our buffers
*/
netif_stop_queue(ax->dev);
unregister_netdev(ax->dev);
/* Free all AX25 frame buffers after unreg. */
kfree(ax->rbuff);
kfree(ax->xbuff);
ax->tty = NULL;
free_netdev(ax->dev);
}
/* Perform I/O control on an active ax25 channel. */ staticint mkiss_ioctl(struct tty_struct *tty, unsignedint cmd, unsignedlong arg)
{ struct mkiss *ax = mkiss_get(tty); struct net_device *dev; unsignedint tmp, err;
/* First make sure we're connected. */ if (ax == NULL) return -ENXIO;
dev = ax->dev;
/* * Handle the 'receiver data ready' interrupt. * This function is called by the 'tty_io' module in the kernel when * a block of data has been received, which can now be decapsulated * and sent on to the AX.25 layer for further processing.
*/ staticvoid mkiss_receive_buf(struct tty_struct *tty, const u8 *cp, const u8 *fp, size_t count)
{ struct mkiss *ax = mkiss_get(tty);
if (!ax) return;
/* * Argh! mtu change time! - costs us the packet part received * at the change
*/ if (ax->mtu != ax->dev->mtu + 73)
ax_changedmtu(ax);
/* Read the characters out of the buffer */ while (count--) { if (fp != NULL && *fp++) { if (!test_and_set_bit(AXF_ERROR, &ax->flags))
ax->dev->stats.rx_errors++;
cp++; continue;
}
kiss_unesc(ax, *cp++);
}
mkiss_put(ax);
tty_unthrottle(tty);
}
/* * Called by the driver when there's room for more data. If we have * more packets to send, we send them here.
*/ staticvoid mkiss_write_wakeup(struct tty_struct *tty)
{ struct mkiss *ax = mkiss_get(tty); int actual;
if (!ax) return;
if (ax->xleft <= 0) { /* Now serial buffer is almost free & we can start * transmission of another packet
*/
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.