/* hard_xmit interface of irda device */ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct pxa_irda *si = netdev_priv(dev); int speed = irda_get_next_speed(skb); /* * Does this packet contain a request to change the interface * speed? If so, remember it until we complete the transmission * of this frame. */ if (speed != si->speed && speed != -1) si->newspeed = speed; /* * If this is an empty frame, we can bypass a lot. */ if (skb->len == 0) { if (si->newspeed) { si->newspeed = 0; pxa_irda_set_speed(si, speed); } dev_kfree_skb(skb); return 0; } netif_stop_queue(dev); if (!IS_FIR(si)) { si->tx_buff.data = si->tx_buff.head; si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, si->tx_buff.truesize); /* Disable STUART interrupts and switch to transmit mode. */ STIER = 0; STISR = IrSR_IR_TRANSMIT_ON | IrSR_XMODE_PULSE_1_6; /* enable STUART and transmit interrupts */ STIER = IER_UUE | IER_TIE; } else { unsigned long mtt = irda_get_mtt(skb); si->dma_tx_buff_len = skb->len; skb_copy_from_linear_data(skb, si->dma_tx_buff, skb->len); if (mtt) while ((unsigned)(OSCR - si->last_oscr)/4 < mtt) cpu_relax(); /* stop RX DMA, disable FICP */ DCSR(si->rxdma) &= ~DCSR_RUN; ICCR0 = 0; pxa_irda_fir_dma_tx_start(si); ICCR0 = ICCR0_ITR | ICCR0_TXE; } dev_kfree_skb(skb); dev->trans_start = jiffies; return 0; }
static int omap_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct omap_irda *omap_ir = netdev_priv(dev); int speed = irda_get_next_speed(skb); int mtt = irda_get_mtt(skb); int xbofs = irda_get_next_xbofs(skb); /* * Does this packet contain a request to change the interface * speed? If so, remember it until we complete the transmission * of this frame. */ if (speed != omap_ir->speed && speed != -1) omap_ir->newspeed = speed; if (xbofs) /* Set number of addtional BOFS */ uart_reg_out(UART3_EBLR, xbofs + 1); /* * If this is an empty frame, we can bypass a lot. */ if (skb->len == 0) { if (omap_ir->newspeed) { omap_ir->newspeed = 0; omap_irda_set_speed(dev, speed); } dev_kfree_skb(skb); return 0; } netif_stop_queue(dev); /* Copy skb data to DMA buffer */ skb_copy_from_linear_data(skb, omap_ir->tx_buf_dma_virt, skb->len); /* Copy skb data to DMA buffer */ omap_ir->stats.tx_bytes += skb->len; /* Set frame length */ uart_reg_out(UART3_TXFLL, (skb->len & 0xff)); uart_reg_out(UART3_TXFLH, (skb->len >> 8)); if (mtt > 1000) mdelay(mtt / 1000); else udelay(mtt); /* Start TX DMA transfer */ omap_start_tx_dma(omap_ir, skb->len); /* We can free skb now because it's already in DMA buffer */ dev_kfree_skb(skb); dev->trans_start = jiffies; return 0; }
static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct pxa_irda *si = netdev_priv(dev); int speed = irda_get_next_speed(skb); if (speed != si->speed && speed != -1) si->newspeed = speed; if (skb->len == 0) { if (si->newspeed) { si->newspeed = 0; pxa_irda_set_speed(si, speed); } dev_kfree_skb(skb); return NETDEV_TX_OK; } netif_stop_queue(dev); if (!IS_FIR(si)) { si->tx_buff.data = si->tx_buff.head; si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, si->tx_buff.truesize); STIER = 0; STISR = IrSR_IR_TRANSMIT_ON | IrSR_XMODE_PULSE_1_6; STIER = IER_UUE | IER_TIE; } else { unsigned long mtt = irda_get_mtt(skb); si->dma_tx_buff_len = skb->len; skb_copy_from_linear_data(skb, si->dma_tx_buff, skb->len); if (mtt) while ((unsigned)(OSCR - si->last_oscr)/4 < mtt) cpu_relax(); DCSR(si->rxdma) &= ~DCSR_RUN; ICCR0 = 0; pxa_irda_fir_dma_tx_start(si); ICCR0 = ICCR0_ITR | ICCR0_TXE; } dev_kfree_skb(skb); return NETDEV_TX_OK; }
static int bfin_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct bfin_sir_self *self = netdev_priv(dev); int speed = irda_get_next_speed(skb); netif_stop_queue(dev); self->mtt = irda_get_mtt(skb); if (speed != self->speed && speed != -1) self->newspeed = speed; self->tx_buff.data = self->tx_buff.head; if (skb->len == 0) self->tx_buff.len = 0; else self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, self->tx_buff.truesize); schedule_work(&self->work); dev_kfree_skb(skb); return 0; }
static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct sa1100_irda *si = dev->priv; int speed = irda_get_next_speed(skb); /* * Does this packet contain a request to change the interface * speed? If so, remember it until we complete the transmission * of this frame. */ if (speed != si->speed && speed != -1) si->newspeed = speed; /* * If this is an empty frame, we can bypass a lot. */ if (skb->len == 0) { if (si->newspeed) { si->newspeed = 0; sa1100_irda_set_speed(si, speed); } dev_kfree_skb(skb); return 0; } if (!IS_FIR(si)) { netif_stop_queue(dev); si->tx_buff.data = si->tx_buff.head; si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, si->tx_buff.truesize); /* * Set the transmit interrupt enable. This will fire * off an interrupt immediately. Note that we disable * the receiver so we won't get spurious characteres * received. */ Ser2UTCR3 = UTCR3_TIE | UTCR3_TXE; dev_kfree_skb(skb); } else { int mtt = irda_get_mtt(skb); /* * We must not be transmitting... */ if (si->txskb) BUG(); netif_stop_queue(dev); si->txskb = skb; si->txbuf_dma = dma_map_single(si->dev, skb->data, skb->len, DMA_TO_DEVICE); sa1100_start_dma(si->txdma, si->txbuf_dma, skb->len); /* * If we have a mean turn-around time, impose the specified * specified delay. We could shorten this by timing from * the point we received the packet. */ if (mtt) udelay(mtt); Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_TXE; } dev->trans_start = jiffies; return 0; }
static int omap1610_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct omap1610_irda *si = dev->priv; int speed = irda_get_next_speed(skb); int mtt = irda_get_mtt(skb); int xbofs = irda_get_next_xbofs(skb); __ECHO_IN; /* * Does this packet contain a request to change the interface * speed? If so, remember it until we complete the transmission * of this frame. */ if (speed != si->speed && speed != -1) si->newspeed = speed; if (xbofs) { /* Set number of addtional BOFS */ omap_writeb(xbofs + 1, UART3_EBLR); } /* * If this is an empty frame, we can bypass a lot. */ if (skb->len == 0) { if (si->newspeed) { si->newspeed = 0; omap1610_irda_set_speed(dev, speed); } dev_kfree_skb(skb); return 0; } netif_stop_queue(dev); /* Copy skb data to DMA buffer */ memcpy(si->tx_buf_dma_virt, skb->data, skb->len); si->stats.tx_bytes += skb->len; /* Set frame length */ omap_writeb((skb->len & 0xff), UART3_TXFLL); omap_writeb((skb->len >> 8), UART3_TXFLH); if (mtt > 1000) mdelay(mtt / 1000); else udelay(mtt); /* Start TX DMA transfer */ omap1610_start_tx_dma(si, skb->len); /* We can free skb now because it's already in DMA buffer */ dev_kfree_skb(skb); dev->trans_start = jiffies; __ECHO_OUT; return 0; }
static int pxa250_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct pxa250_irda *si = dev->priv; int speed = irda_get_next_speed(skb); int mtt; __ECHO_IN; /* * Does this packet contain a request to change the interface * speed? If so, remember it until we complete the transmission * of this frame. */ if (speed != si->speed && speed != -1) si->newspeed = speed; /* * If this is an empty frame, we can bypass a lot. */ if (skb->len == 0) { if (si->newspeed) { si->newspeed = 0; pxa250_irda_set_speed(dev, speed); } dev_kfree_skb(skb); return 0; } DBG("stop queue\n"); netif_stop_queue(dev); if(!IS_FIR(si)) { si->tx_buff.data = si->tx_buff.head; si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data, si->tx_buff.truesize); pxa250_sir_transmit(dev); dev_kfree_skb(skb); dev->trans_start = jiffies; return 0; } else /* FIR */ { DBG("Enter FIR transmit\n"); /* * We must not be transmitting... */ if (si->txskb) BUG(); disable_irq(si->fir_irq); netif_stop_queue(dev); DBG("queue stoped\n"); si->txskb = skb; /* we could not just map so we'll need some triks */ /* skb->data may be not DMA capable -Sed- */ if (skb->len > TXBUFF_MAX_SIZE) { printk (KERN_ERR "skb data too large\n"); printk (KERN_ERR "len=%d",skb->len); BUG(); } DBG("gonna copy %d bytes to txbuf\n",skb->len); memcpy (si->txbuf_dma_virt, skb->data , skb->len); /* Actual sending ;must not be receiving !!! */ /* Write data and source address */ DBG("ICSR1 & RNE =%d\n",(ICSR1 & ICSR1_RNE) ? 1 : 0 ); /*Disable receiver and enable transifer */ ICCR0 &= ~ICCR0_RXE; if (ICSR1 & ICSR1_TBY) BUG(); ICCR0 |= ICCR0_TXE; DBG("FICP status %x\n",ICSR0); if (0){ int i; DBG("sending packet\n"); for (i=0;i<skb->len;i++) (i % 64) ? printk ("%2x ",skb->data[i]) : printk ("%2x \n",skb->data[i]) ; DBG(" done\n"); } /* * If we have a mean turn-around time, impose the specified * specified delay. We could shorten this by timing from * the point we received the packet. */ mtt = irda_get_mtt(skb); if(mtt) udelay(mtt); DCSR(si->txdma_ch)=0; DCSR(si->txdma_ch)=DCSR_NODESC; DSADR(si->txdma_ch) = si->txbuf_dma; /* phisic address */ DTADR(si->txdma_ch) = __PREG(ICDR); DCMD(si->txdma_ch) = DCMD_ENDIRQEN| DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_BURST8 | DCMD_WIDTH1 | skb->len; DCSR(si->txdma_ch) = DCSR_ENDINTR | DCSR_BUSERR; DCSR(si->txdma_ch) = DCSR_RUN | DCSR_NODESC ; DBG("FICP status %x\n",ICSR0); return 0; } }