/* * This is the SIR receive routine. * * @param si IrDA specific structure. * * @param dev pointer to the net_device structure * * @return The function returns 0 on success and a non-zero value on * failure. */ static int mxc_irda_sir_rxirq(struct mxc_irda *si, struct net_device *dev) { u16 data, status; volatile u16 sr2; sr2 = readl(si->uart_base + MXC_UARTUSR2); while ((sr2 & MXC_UARTUSR2_RDR) == 1) { data = readl(si->uart_base + MXC_UARTURXD); status = data & 0xf400; if (status & MXC_UARTURXD_ERR) { dev_err(si->dev, "Receive an incorrect data =0x%x.\n", data); si->stats.rx_errors++; if (status & MXC_UARTURXD_OVRRUN) { si->stats.rx_fifo_errors++; dev_err(si->dev, "Rx overrun.\n"); } if (status & MXC_UARTURXD_FRMERR) { si->stats.rx_frame_errors++; dev_err(si->dev, "Rx frame error.\n"); } if (status & MXC_UARTURXD_PRERR) { dev_err(si->dev, "Rx parity error.\n"); } /* Other: it is the Break char. * Do nothing for it. throw out the data. */ async_unwrap_char(dev, &si->stats, &si->rx_buff, (data & 0xFF)); } else { /* It is correct data. */ data &= 0xFF; async_unwrap_char(dev, &si->stats, &si->rx_buff, data); dev->last_rx = jiffies; } sr2 = readl(si->uart_base + MXC_UARTUSR2); writel(0xFFFF, si->uart_base + MXC_UARTUSR1); writel(0xFFFF, si->uart_base + MXC_UARTUSR2); } /* while */ return 0; }
/* Receive callback function */ static void ks959_rcv_irq(struct urb *urb) { struct ks959_cb *kingsun = urb->context; int ret; /* in process of stopping, just drop data */ if (!netif_running(kingsun->netdev)) { kingsun->receiving = 0; return; } /* unlink, shutdown, unplug, other nasties */ if (urb->status != 0) { err("kingsun_rcv_irq: urb asynchronously failed - %d", urb->status); kingsun->receiving = 0; return; } if (urb->actual_length > 0) { __u8 *bytes = urb->transfer_buffer; unsigned int i; for (i = 0; i < urb->actual_length; i++) { /* De-obfuscation implemented here: variable portion of xormask is incremented, and then used with the encoded byte for the XOR. The result of the operation is used to unwrap the SIR frame. */ kingsun->rx_variable_xormask++; bytes[i] = bytes[i] ^ kingsun->rx_variable_xormask ^ 0x55u; /* rx_variable_xormask doubles as an index counter so we can skip the byte at 0xff (wrapped around to 0). */ if (kingsun->rx_variable_xormask != 0) { async_unwrap_char(kingsun->netdev, &kingsun->netdev->stats, &kingsun->rx_unwrap_buff, bytes[i]); } } do_gettimeofday(&kingsun->rx_time); kingsun->receiving = (kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0; } /* This urb has already been filled in kingsun_net_open. Setup packet must be re-filled, but it is assumed that urb keeps the pointer to the initial setup packet, as well as the payload buffer. Setup packet is already pre-filled at ks959_probe. */ urb->status = 0; ret = usb_submit_urb(urb, GFP_ATOMIC); }
static void bfin_sir_dma_rx_chars(struct net_device *dev) { struct bfin_sir_self *self = netdev_priv(dev); struct bfin_sir_port *port = self->sir_port; int i; SIR_UART_CLEAR_LSR(port); for (i = port->rx_dma_buf.head; i < port->rx_dma_buf.tail; i++) async_unwrap_char(dev, &self->stats, &self->rx_buff, port->rx_dma_buf.buf[i]); }
static void bfin_sir_rx_chars(struct net_device *dev) { struct bfin_sir_self *self = netdev_priv(dev); struct bfin_sir_port *port = self->sir_port; unsigned char ch; SIR_UART_CLEAR_LSR(port); ch = SIR_UART_GET_CHAR(port); async_unwrap_char(dev, &self->stats, &self->rx_buff, ch); dev->last_rx = jiffies; }
/* Receive callback function */ static void kingsun_rcv_irq(struct urb *urb) { struct kingsun_cb *kingsun = urb->context; int ret; /* in process of stopping, just drop data */ if (!netif_running(kingsun->netdev)) { kingsun->receiving = 0; return; } /* unlink, shutdown, unplug, other nasties */ if (urb->status != 0) { dev_err(&kingsun->usbdev->dev, "kingsun_rcv_irq: urb asynchronously failed - %d\n", urb->status); kingsun->receiving = 0; return; } if (urb->actual_length == kingsun->max_rx) { __u8 *bytes = urb->transfer_buffer; int i; /* The very first byte in the buffer indicates the length of valid data in the read. This byte must be in the range 1..kingsun->max_rx -1 . Values outside this range indicate an uninitialized Rx buffer when the dongle has just been plugged in. */ if (bytes[0] >= 1 && bytes[0] < kingsun->max_rx) { for (i = 1; i <= bytes[0]; i++) { async_unwrap_char(kingsun->netdev, &kingsun->netdev->stats, &kingsun->rx_buff, bytes[i]); } do_gettimeofday(&kingsun->rx_time); kingsun->receiving = (kingsun->rx_buff.state != OUTSIDE_FRAME) ? 1 : 0; } } else if (urb->actual_length > 0) { dev_err(&kingsun->usbdev->dev, "%s(): Unexpected response length, expected %d got %d\n", __func__, kingsun->max_rx, urb->actual_length); } /* This urb has already been filled in kingsun_net_open */ ret = usb_submit_urb(urb, GFP_ATOMIC); }
int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count) { if (!dev || !dev->netdev) { IRDA_WARNING("%s(), not ready yet!\n", __func__); return -1; } if (!dev->irlap) { IRDA_WARNING("%s - too early: %p / %zd!\n", __func__, cp, count); return -1; } if (cp==NULL) { /* error already at lower level receive * just update stats and set media busy */ irda_device_set_media_busy(dev->netdev, TRUE); dev->netdev->stats.rx_dropped++; IRDA_DEBUG(0, "%s; rx-drop: %zd\n", __func__, count); return 0; } /* Read the characters into the buffer */ if (likely(atomic_read(&dev->enable_rx))) { while (count--) /* Unwrap and destuff one byte */ async_unwrap_char(dev->netdev, &dev->netdev->stats, &dev->rx_buff, *cp++); } else { while (count--) { /* rx not enabled: save the raw bytes and never * trigger any netif_rx. The received bytes are flushed * later when we re-enable rx but might be read meanwhile * by the dongle driver. */ dev->rx_buff.data[dev->rx_buff.len++] = *cp++; /* What should we do when the buffer is full? */ if (unlikely(dev->rx_buff.len == dev->rx_buff.truesize)) dev->rx_buff.len = 0; } } return 0; }
static void kingsun_rcv_irq(struct urb *urb) { struct kingsun_cb *kingsun = urb->context; int ret; if (!netif_running(kingsun->netdev)) { kingsun->receiving = 0; return; } if (urb->status != 0) { err("kingsun_rcv_irq: urb asynchronously failed - %d", urb->status); kingsun->receiving = 0; return; } if (urb->actual_length == kingsun->max_rx) { __u8 *bytes = urb->transfer_buffer; int i; if (bytes[0] >= 1 && bytes[0] < kingsun->max_rx) { for (i = 1; i <= bytes[0]; i++) { async_unwrap_char(kingsun->netdev, &kingsun->netdev->stats, &kingsun->rx_buff, bytes[i]); } do_gettimeofday(&kingsun->rx_time); kingsun->receiving = (kingsun->rx_buff.state != OUTSIDE_FRAME) ? 1 : 0; } } else if (urb->actual_length > 0) { err("%s(): Unexpected response length, expected %d got %d", __func__, kingsun->max_rx, urb->actual_length); } ret = usb_submit_urb(urb, GFP_ATOMIC); }
/* Receive callback function */ static void ksdazzle_rcv_irq(struct urb *urb) { struct ksdazzle_cb *kingsun = urb->context; struct net_device *netdev = kingsun->netdev; /* in process of stopping, just drop data */ if (!netif_running(netdev)) { kingsun->receiving = 0; return; } /* unlink, shutdown, unplug, other nasties */ if (urb->status != 0) { err("ksdazzle_rcv_irq: urb asynchronously failed - %d", urb->status); kingsun->receiving = 0; return; } if (urb->actual_length > 0) { __u8 *bytes = urb->transfer_buffer; unsigned int i; for (i = 0; i < urb->actual_length; i++) { async_unwrap_char(netdev, &netdev->stats, &kingsun->rx_unwrap_buff, bytes[i]); } kingsun->receiving = (kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0; } /* This urb has already been filled in ksdazzle_net_open. It is assumed that urb keeps the pointer to the payload buffer. */ urb->status = 0; usb_submit_urb(urb, GFP_ATOMIC); }
/* SIR interrupt service routine. */ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) { struct net_device *dev = dev_id; struct pxa_irda *si = netdev_priv(dev); int iir, lsr, data; iir = STIIR; switch (iir & 0x0F) { case 0x06: /* Receiver Line Status */ lsr = STLSR; while (lsr & LSR_FIFOE) { data = STRBR; if (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) { printk(KERN_DEBUG "pxa_ir: sir receiving error\n"); si->stats.rx_errors++; if (lsr & LSR_FE) si->stats.rx_frame_errors++; if (lsr & LSR_OE) si->stats.rx_fifo_errors++; } else { si->stats.rx_bytes++; async_unwrap_char(dev, &si->stats, &si->rx_buff, data); } lsr = STLSR; } dev->last_rx = jiffies; si->last_oscr = OSCR; break; case 0x04: /* Received Data Available */ /* forth through */ case 0x0C: /* Character Timeout Indication */ do { si->stats.rx_bytes++; async_unwrap_char(dev, &si->stats, &si->rx_buff, STRBR); } while (STLSR & LSR_DR); dev->last_rx = jiffies; si->last_oscr = OSCR; break; case 0x02: /* Transmit FIFO Data Request */ while ((si->tx_buff.len) && (STLSR & LSR_TDRQ)) { STTHR = *si->tx_buff.data++; si->tx_buff.len -= 1; } if (si->tx_buff.len == 0) { si->stats.tx_packets++; si->stats.tx_bytes += si->tx_buff.data - si->tx_buff.head; /* We need to ensure that the transmitter has finished. */ while ((STLSR & LSR_TEMT) == 0) cpu_relax(); si->last_oscr = OSCR; /* * Ok, we've finished transmitting. Now enable * the receiver. Sometimes we get a receive IRQ * immediately after a transmit... */ if (si->newspeed) { pxa_irda_set_speed(si, si->newspeed); si->newspeed = 0; } else { /* enable IR Receiver, disable IR Transmitter */ STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6; /* enable STUART and receive interrupts */ STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE; } /* I'm hungry! */ netif_wake_queue(dev); } break; } return IRQ_HANDLED; }
/* * HP-SIR format interrupt service routines. */ static void sa1100_irda_hpsir_irq(struct net_device *dev) { struct sa1100_irda *si = dev->priv; int status; status = Ser2UTSR0; /* * Deal with any receive errors first. The bytes in error may be * the only bytes in the receive FIFO, so we do this first. */ while (status & UTSR0_EIF) { int stat, data; stat = Ser2UTSR1; data = Ser2UTDR; if (stat & (UTSR1_FRE | UTSR1_ROR)) { si->stats.rx_errors++; if (stat & UTSR1_FRE) si->stats.rx_frame_errors++; if (stat & UTSR1_ROR) si->stats.rx_fifo_errors++; } else async_unwrap_char(dev, &si->stats, &si->rx_buff, data); status = Ser2UTSR0; } /* * We must clear certain bits. */ Ser2UTSR0 = status & (UTSR0_RID | UTSR0_RBB | UTSR0_REB); if (status & UTSR0_RFS) { /* * There are at least 4 bytes in the FIFO. Read 3 bytes * and leave the rest to the block below. */ async_unwrap_char(dev, &si->stats, &si->rx_buff, Ser2UTDR); async_unwrap_char(dev, &si->stats, &si->rx_buff, Ser2UTDR); async_unwrap_char(dev, &si->stats, &si->rx_buff, Ser2UTDR); } if (status & (UTSR0_RFS | UTSR0_RID)) { /* * Fifo contains more than 1 character. */ do { async_unwrap_char(dev, &si->stats, &si->rx_buff, Ser2UTDR); } while (Ser2UTSR1 & UTSR1_RNE); dev->last_rx = jiffies; } if (status & UTSR0_TFS && si->tx_buff.len) { /* * Transmitter FIFO is not full */ do { Ser2UTDR = *si->tx_buff.data++; si->tx_buff.len -= 1; } while (Ser2UTSR1 & UTSR1_TNF && si->tx_buff.len); if (si->tx_buff.len == 0) { si->stats.tx_packets++; si->stats.tx_bytes += si->tx_buff.data - si->tx_buff.head; /* * We need to ensure that the transmitter has * finished. */ do rmb(); while (Ser2UTSR1 & UTSR1_TBY); /* * Ok, we've finished transmitting. Now enable * the receiver. Sometimes we get a receive IRQ * immediately after a transmit... */ Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE; if (si->newspeed) { sa1100_irda_set_speed(si, si->newspeed); si->newspeed = 0; } /* I'm hungry! */ netif_wake_queue(dev); } } }
static void pxa250_irda_hpsir_irq(struct net_device *dev) { struct pxa250_irda *si = dev->priv; /* * Deal with any receive errors first. The bytes in error may be * the only bytes in the receive FIFO, so we do this first. */ __ECHO_IN; while (STLSR & LSR_FIFOE) { int stat, data; stat = STLSR; data = STRBR; if (stat & (LSR_FE | LSR_OE | LSR_PE)) { si->stats.rx_errors++; if (stat & LSR_FE) si->stats.rx_frame_errors++; if (stat & LSR_OE) si->stats.rx_fifo_errors++; } else { rx_count++; async_unwrap_char(dev, &si->stats, &si->rx_buff, data); } } /* * We must clear certain bits. */ if (STLSR & (LSR_DR)) { /* * Fifo contains at least 1 character. */ do { int data; data = STRBR; async_unwrap_char(dev, &si->stats, &si->rx_buff, data); /* was Ser2UTDR); Clo */ rx_count++; } while (STLSR & LSR_DR); dev->last_rx = jiffies; } __ECHO_OUT; }
int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count) { int i; unsigned char c[32]; unsigned char *eofp, *ebufp; int framelen; if (!dev || !dev->netdev) { IRDA_WARNING("%s(), not ready yet!\n", __func__); return -1; } if (!dev->irlap) { IRDA_WARNING("%s - too early: %p / %zd!\n", __func__, cp, count); return -1; } if (cp==NULL) { /* error already at lower level receive * just update stats and set media busy */ irda_device_set_media_busy(dev->netdev, TRUE); dev->netdev->stats.rx_dropped++; IRDA_DEBUG(0, "%s; rx-drop: %zd\n", __func__, count); return 0; } IRDA_DEBUG(3, "%s; get rx: %zd\n", __func__, count); /* Read the characters into the buffer */ if (likely(atomic_read(&dev->enable_rx))) { rx_count_log = count; if (count >0){ for(i= 0; i<32; i ++){ if (i<count){ c[i] = cp[i]; } else { c[i] = 0x00; } } IRDA_DEBUG(3, "RcvData= %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", c[0], c[1], c[2], c[3], c[4], c[5],c[6], c[7], c[8], c[9], c[10], c[11], c[12], c[13],c[14],c[15], c[16], c[17], c[18], c[19], c[20], c[21],c[22], c[23], c[24], c[25], c[26], c[27], c[28], c[29],c[30],c[31] ); } if (count >= 32){ for(i= 0; i<32; i ++){ if ( i < count-32){ c[i] = cp[i+32]; } else { c[i] = 0x00; } } IRDA_DEBUG(3, "RcvData= %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", c[0], c[1], c[2], c[3], c[4], c[5],c[6], c[7], c[8], c[9], c[10], c[11], c[12], c[13],c[14],c[15], c[16], c[17], c[18], c[19], c[20], c[21],c[22], c[23], c[24], c[25], c[26], c[27], c[28], c[29],c[30],c[31] ); } if (count >= 64){ for(i= 0; i< 32; i ++){ if ( i < count-64){ c[i] = cp[i+64]; } else { c[i] = 0x00; } } IRDA_DEBUG(3, "RcvData= %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", c[0], c[1], c[2], c[3], c[4], c[5],c[6], c[7], c[8], c[9], c[10], c[11], c[12], c[13],c[14],c[15], c[16], c[17], c[18], c[19], c[20], c[21],c[22], c[23], c[24], c[25], c[26], c[27], c[28], c[29],c[30],c[31] ); } if (count >=96){ for(i= 0; i<32; i ++){ if ( i < count-96){ c[i] = cp[i+96]; } else { c[i] = 0x00; } } IRDA_DEBUG(3, "RcvData= %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", c[0], c[1], c[2], c[3], c[4], c[5],c[6], c[7], c[8], c[9], c[10], c[11], c[12], c[13],c[14],c[15], c[16], c[17], c[18], c[19], c[20], c[21],c[22], c[23], c[24], c[25], c[26], c[27], c[28], c[29],c[30],c[31] ); } ebufp = localechobuf; if ( ( count < 20) && localechodata > 0 && dev->rx_buff.state == OUTSIDE_FRAME){ if ( count > localechodata){ if (!memcmp(localechobuf, cp + count - localechodata, localechodata)){ IRDA_DEBUG(4, "%s; data mutch trush %d byte!\n", __func__, count); localechodata = 0; cp += count; count = 0; } } else { if (!memcmp(localechobuf + localechodata - count, cp , count)){ IRDA_DEBUG(4, "%s; data mutch trush %d byte!\n", __func__, count); localechodata = 0; cp += count; count = 0; } } } while (count--){ if (localechodata > 0 && dev->rx_buff.state == OUTSIDE_FRAME){ switch(*cp) { case BOF: if ( count > 1 && *(cp + 1) == BOF){ ebufp ++; localechodata--; cp++; continue; break; } else { eofp = (unsigned char *)memchr( (void *)cp, (int)EOF, count); if ( eofp == NULL){ IRDA_DEBUG(4, "%s; not find eof, get start of next frame.\n", __func__); localechodata = 0; break; } else { framelen = eofp - cp +1 ; if ( framelen <= localechodata && !memcmp((void *)cp, ebufp + localechodata - framelen, framelen)){ IRDA_DEBUG(4, "%s; find one frame, skip it\n", __func__); cp += framelen; count -= framelen; localechodata = 0; break; } else { IRDA_DEBUG(4, "%s; frame line =%d, localechodata = %d.\n", __func__, framelen, localechodata); IRDA_DEBUG(4, "%s; find start of next frame.\n", __func__); localechodata = 0; break; } } } case EOF: IRDA_DEBUG(4, "%s; find end of trush data!\n", __func__); ebufp ++; localechodata = 0; cp++; continue; break; default: ebufp ++; localechodata--; cp++; continue; break; } } async_unwrap_char(dev->netdev, &dev->netdev->stats, &dev->rx_buff, *cp++); } } else { while (count--) { /* rx not enabled: save the raw bytes and never * trigger any netif_rx. The received bytes are flushed * later when we re-enable rx but might be read meanwhile * by the dongle driver. */ dev->rx_buff.data[dev->rx_buff.len++] = *cp++; /* What should we do when the buffer is full? */ if (unlikely(dev->rx_buff.len == dev->rx_buff.truesize)) dev->rx_buff.len = 0; } } return 0; }
static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) { struct net_device *dev = dev_id; struct pxa_irda *si = netdev_priv(dev); int iir, lsr, data; iir = STIIR; switch (iir & 0x0F) { case 0x06: lsr = STLSR; while (lsr & LSR_FIFOE) { data = STRBR; if (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) { printk(KERN_DEBUG "pxa_ir: sir receiving error\n"); dev->stats.rx_errors++; if (lsr & LSR_FE) dev->stats.rx_frame_errors++; if (lsr & LSR_OE) dev->stats.rx_fifo_errors++; } else { dev->stats.rx_bytes++; async_unwrap_char(dev, &dev->stats, &si->rx_buff, data); } lsr = STLSR; } si->last_oscr = OSCR; break; case 0x04: case 0x0C: do { dev->stats.rx_bytes++; async_unwrap_char(dev, &dev->stats, &si->rx_buff, STRBR); } while (STLSR & LSR_DR); si->last_oscr = OSCR; break; case 0x02: while ((si->tx_buff.len) && (STLSR & LSR_TDRQ)) { STTHR = *si->tx_buff.data++; si->tx_buff.len -= 1; } if (si->tx_buff.len == 0) { dev->stats.tx_packets++; dev->stats.tx_bytes += si->tx_buff.data - si->tx_buff.head; while ((STLSR & LSR_TEMT) == 0) cpu_relax(); si->last_oscr = OSCR; if (si->newspeed) { pxa_irda_set_speed(si, si->newspeed); si->newspeed = 0; } else { STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6; STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE; } netif_wake_queue(dev); } break; } return IRQ_HANDLED; }
/* * SIR format interrupt service routines. */ static irqreturn_t s3c_irda_sir_irq(int irq, void *dev_id) { struct net_device *dev = dev_id; struct s3c_irda *si = dev->priv; int err_status; u8 data; u32 ucon, ufcon, ufstat; err_status = sir_readreg(S3C_UERSTAT); if(err_status) { printk("Error : 0x%x\n", sir_readreg(S3C_UERSTAT)); data = sir_readreg(S3C_URXH); si->stats.rx_errors++; si->stats.rx_frame_errors++; } if(irq == si->sir_irq_rx){ DBG("Rx intr : 0x%1x\n", intpnd); while ((sir_readreg(S3C_UFSTAT) & 0X3F) > 0) { data = sir_readreg(S3C_URXH); async_unwrap_char(dev, &si->stats, &si->rx_buff, data); } dev->last_rx = jiffies; /* Clear FIFO */ ufcon = sir_readreg(S3C_UFCON); ufcon |= 3; sir_writereg(ufcon, S3C_UFCON); } if(irq == si->sir_irq_tx) { DBG("Tx intr : 0x%1x\n", intpnd); if(si->tx_buff.len > 0) { ufstat = sir_readreg(S3C_UFSTAT); /* Transmitter FIFO is not full */ while (!(ufstat & (1 << 14)) ) { while(!(sir_readreg(S3C_UTRSTAT) & 0x02)); sir_writereg(*si->tx_buff.data++, S3C_UTXH); if(si->tx_buff.len == 0) break; si->tx_buff.len -= 1; rmb(); ufstat = sir_readreg(S3C_UFSTAT); } if(si->tx_buff.len == 0) { si->stats.tx_packets++; si->stats.tx_bytes += si->tx_buff.data - si->tx_buff.head; /* We need to ensure that transmit has finished */ do { rmb(); ufstat = sir_readreg(S3C_UFSTAT); } while (((ufstat >> 8) & 0x3f) > 0); /* Transmission complete. Now enable the receiver. * Sometimes we get a receive IRQ immediately * after a transmit */ ufcon = sir_readreg(S3C_UFCON); ufcon |= 7; sir_writereg(ufcon, S3C_UFCON); ucon = sir_readreg(S3C_UCON); ucon &= ~( 3 << 2); sir_writereg(ucon, S3C_UCON); if(si->newspeed) { s3c_irda_set_speed(si, si->newspeed); si->newspeed = 0; } if(1) { ucon |= 1; sir_writereg(ucon, S3C_UCON); } netif_wake_queue(dev); }