/* * Function async_unwrap_other(dev, byte) * * Handle other characters received within a frame * */ static inline void async_unwrap_other(struct net_device *dev, struct net_device_stats *stats, iobuff_t *rx_buff, __u8 byte) { switch(rx_buff->state) { /* This is on the critical path, case are ordered by * probability (most frequent first) - Jean II */ case INSIDE_FRAME: /* Must be the next byte of the frame */ if (rx_buff->len < rx_buff->truesize) { rx_buff->data[rx_buff->len++] = byte; #ifndef POSTPONE_RX_CRC rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); #endif } else { IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n", __FUNCTION__); rx_buff->state = OUTSIDE_FRAME; } break; case LINK_ESCAPE: /* * Stuffed char, complement bit 5 of byte * following CE, IrLAP p.114 */ byte ^= IRDA_TRANS; if (rx_buff->len < rx_buff->truesize) { rx_buff->data[rx_buff->len++] = byte; #ifndef POSTPONE_RX_CRC rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); #endif rx_buff->state = INSIDE_FRAME; } else { IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n", __FUNCTION__); rx_buff->state = OUTSIDE_FRAME; } break; case OUTSIDE_FRAME: /* Activate carrier sense */ if(byte != XBOF) irda_device_set_media_busy(dev, TRUE); break; case BEGIN_FRAME: default: rx_buff->data[rx_buff->len++] = byte; #ifndef POSTPONE_RX_CRC rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); #endif rx_buff->state = INSIDE_FRAME; break; } }
/* * Function async_unwrap_other(dev, byte) * * Handle other characters received within a frame * */ static inline void async_unwrap_other(struct tty_struct *tty, iobuff_t *rx_buff, __u8 byte) { SHIRDA_DEBUGLOG("state=%d,byte=0x%x\n",rx_buff->state,byte); switch(rx_buff->state) { /* This is on the critical path, case are ordered by * probability (most frequent first) - Jean II */ case INSIDE_FRAME: /* Must be the next byte of the frame */ if (rx_buff->len < rx_buff->truesize) { rx_buff->data[rx_buff->len++] = byte; #ifndef POSTPONE_RX_CRC rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); #endif } else { SHIRDA_DEBUGLOG("Rx buffer overflow, aborting\n"); rx_buff->state = OUTSIDE_FRAME; } break; case LINK_ESCAPE: /* * Stuffed char, complement bit 5 of byte * following CE, IrLAP p.114 */ byte ^= IRDA_TRANS; if (rx_buff->len < rx_buff->truesize) { rx_buff->data[rx_buff->len++] = byte; #ifndef POSTPONE_RX_CRC rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); #endif rx_buff->state = INSIDE_FRAME; } else { SHIRDA_DEBUGLOG("Rx buffer overflow, aborting\n"); rx_buff->state = OUTSIDE_FRAME; } break; case OUTSIDE_FRAME: /* Activate carrier sense */ break; case BEGIN_FRAME: default: rx_buff->data[rx_buff->len++] = byte; #ifndef POSTPONE_RX_CRC rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); #endif rx_buff->state = INSIDE_FRAME; break; } }
/* * Function async_unwrap_eof(dev, byte) * * Handle End Of Frame character received within a frame * */ static inline void async_unwrap_eof(struct net_device *dev, struct net_device_stats *stats, iobuff_t *rx_buff, __u8 byte) { #ifdef POSTPONE_RX_CRC int i; #endif switch(rx_buff->state) { case OUTSIDE_FRAME: /* Probably missed the BOF */ stats->rx_errors++; stats->rx_missed_errors++; irda_device_set_media_busy(dev, TRUE); break; case BEGIN_FRAME: case LINK_ESCAPE: case INSIDE_FRAME: default: /* Note : in the case of BEGIN_FRAME and LINK_ESCAPE, * the fcs will most likely not match and generate an * error, as expected - Jean II */ rx_buff->state = OUTSIDE_FRAME; rx_buff->in_frame = FALSE; #ifdef POSTPONE_RX_CRC /* If we haven't done the CRC as we receive bytes, we * must do it now... Jean II */ for(i = 0; i < rx_buff->len; i++) rx_buff->fcs = irda_fcs(rx_buff->fcs, rx_buff->data[i]); #endif /* Test FCS and signal success if the frame is good */ if (rx_buff->fcs == GOOD_FCS) { /* Deliver frame */ async_bump(dev, stats, rx_buff); break; } else { /* Wrong CRC, discard frame! */ irda_device_set_media_busy(dev, TRUE); IRDA_DEBUG(1, "%s(), crc error\n", __FUNCTION__); stats->rx_errors++; stats->rx_crc_errors++; } break; } }
/* * Function async_unwrap_eof(dev, byte) * * Handle End Of Frame character received within a frame * */ static inline void async_unwrap_eof(struct tty_struct *tty, iobuff_t *rx_buff, __u8 byte) { #ifdef POSTPONE_RX_CRC int i; #endif SHIRDA_DEBUGLOG("state=%d,byte=0x%x\n",rx_buff->state,byte); switch(rx_buff->state) { case OUTSIDE_FRAME: /* Probably missed the BOF */ rx_buff->stats.rx_errors++; rx_buff->stats.rx_missed_errors++; break; case BEGIN_FRAME: case LINK_ESCAPE: case INSIDE_FRAME: default: /* Note : in the case of BEGIN_FRAME and LINK_ESCAPE, * the fcs will most likely not match and generate an * error, as expected - Jean II */ rx_buff->state = OUTSIDE_FRAME; rx_buff->in_frame = FALSE; #ifdef POSTPONE_RX_CRC /* If we haven't done the CRC as we receive bytes, we * must do it now... Jean II */ for(i = 0; i < rx_buff->len; i++) rx_buff->fcs = irda_fcs(rx_buff->fcs, rx_buff->data[i]); #endif /* Test FCS and signal success if the frame is good */ if (rx_buff->fcs == GOOD_FCS) { /* Deliver frame */ rx_buff->stats.rx_packets++; rx_buff->stats.rx_bytes += (rx_buff->len - 2); shirda_async_bump(tty, rx_buff); break; } else { /* Wrong CRC, discard frame! */ SHIRDA_DEBUGLOG("crc error\n"); rx_buff->stats.rx_errors++; rx_buff->stats.rx_crc_errors++; } break; } }
__u16 irda_calc_crc16( __u16 fcs, __u8 const *buf, size_t len) { while (len--) fcs = irda_fcs(fcs, *buf++); return fcs; }
/* * Function async_wrap (tty, *tx_buff, buffsize) */ int async_wrap_tty(struct tty_struct *tty, __u8 *tx_buff, int buffsize) { struct shirda_ldisc_admin_t *sp = tty->disc_data; int xbofs; int i; int n; union { __u16 value; __u8 bytes[2]; } fcs; /* Initialize variables */ fcs.value = INIT_FCS; n = 0; /* * Send XBOF's for required min. turn time and for the negotiated * additional XBOFS */ xbofs = sp->qos.add_bof; SHIRDA_DEBUGLOG("abofs=%d\n", xbofs); /* Check that we never use more than 115 + 48 xbofs */ if (xbofs > 163) { IRDALOG_WARNING("too many xbofs (%d)\n", xbofs); xbofs = 163; } memset(tx_buff + n, XBOF, xbofs); n += xbofs; /* Start of packet character BOF */ tx_buff[n++] = BOF; SHIRDA_DEBUGLOG("tx_payload length=%d\n", sp->nr_tx_payload); /* Insert frame and calc CRC */ for (i=0; i < sp->nr_tx_payload; i++) { /* * Check for the possibility of tx buffer overflow. We use * bufsize-5 since the maximum number of bytes that can be * transmitted after this point is 5. */ if(n >= (buffsize-5)) { IRDALOG_ERROR("tx buffer overflow (n=%d)\n", n); return -1; } n += stuff_byte(sp->tx_payload[i], tx_buff+n); fcs.value = irda_fcs(fcs.value, sp->tx_payload[i]); SHIRDA_DEBUGLOG("len=%04d:%04d, data=0x%02x, fcs=0x%04x\n", i, n, sp->tx_payload[i], fcs.value); } /* Insert CRC in little endian format (LSB first) */ fcs.value = ~fcs.value; #ifdef __LITTLE_ENDIAN n += stuff_byte(fcs.bytes[0], tx_buff+n); n += stuff_byte(fcs.bytes[1], tx_buff+n); #else /* ifdef __BIG_ENDIAN */ n += stuff_byte(fcs.bytes[1], tx_buff+n); n += stuff_byte(fcs.bytes[0], tx_buff+n); #endif tx_buff[n++] = EOF; SHIRDA_DEBUGLOG("tx_buff length=%d\n", n); return n; }
/* * Function async_wrap (skb, *tx_buff, buffsize) * * Makes a new buffer with wrapping and stuffing, should check that * we don't get tx buffer overflow. */ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize) { struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb; int xbofs; int i; int n; union { __u16 value; __u8 bytes[2]; } fcs; /* Initialize variables */ fcs.value = INIT_FCS; n = 0; /* * Send XBOF's for required min. turn time and for the negotiated * additional XBOFS */ if (cb->magic != LAP_MAGIC) { /* * This will happen for all frames sent from user-space. * Nothing to worry about, but we set the default number of * BOF's */ IRDA_DEBUG(1, "%s(), wrong magic in skb!\n", __FUNCTION__); xbofs = 10; } else xbofs = cb->xbofs + cb->xbofs_delay; IRDA_DEBUG(4, "%s(), xbofs=%d\n", __FUNCTION__, xbofs); /* Check that we never use more than 115 + 48 xbofs */ if (xbofs > 163) { IRDA_DEBUG(0, "%s(), too many xbofs (%d)\n", __FUNCTION__, xbofs); xbofs = 163; } memset(tx_buff + n, XBOF, xbofs); n += xbofs; /* Start of packet character BOF */ tx_buff[n++] = BOF; /* Insert frame and calc CRC */ for (i=0; i < skb->len; i++) { /* * Check for the possibility of tx buffer overflow. We use * bufsize-5 since the maximum number of bytes that can be * transmitted after this point is 5. */ if(n >= (buffsize-5)) { IRDA_ERROR("%s(), tx buffer overflow (n=%d)\n", __FUNCTION__, n); return n; } n += stuff_byte(skb->data[i], tx_buff+n); fcs.value = irda_fcs(fcs.value, skb->data[i]); } /* Insert CRC in little endian format (LSB first) */ fcs.value = ~fcs.value; #ifdef __LITTLE_ENDIAN n += stuff_byte(fcs.bytes[0], tx_buff+n); n += stuff_byte(fcs.bytes[1], tx_buff+n); #else /* ifdef __BIG_ENDIAN */ n += stuff_byte(fcs.bytes[1], tx_buff+n); n += stuff_byte(fcs.bytes[0], tx_buff+n); #endif tx_buff[n++] = EOF; return n; }