static inline void hscx_interrupt(struct IsdnCardState *cs, u8 val, u8 hscx) { u8 r; struct BCState *bcs = cs->bcs + hscx; int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32; int count; if (!test_bit(BC_FLG_INIT, &bcs->Flag)) return; if (val & 0x80) { /* RME */ r = hscx_read(bcs, HSCX_RSTA); if ((r & 0xf0) != 0xa0) { if (!(r & 0x80)) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX invalid frame"); #ifdef ERROR_STATISTIC bcs->err_inv++; #endif } if ((r & 0x40) && bcs->mode) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX RDO mode=%d", bcs->mode); #ifdef ERROR_STATISTIC bcs->err_rdo++; #endif } if (!(r & 0x20)) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX CRC error"); #ifdef ERROR_STATISTIC bcs->err_crc++; #endif } WriteHSCXCMDR(bcs, 0x80); bcs->rcvidx = 0; } else { count = hscx_read(bcs, HSCX_RBCL) & (fifo_size-1); if (count == 0) count = fifo_size; hscx_empty_fifo(bcs, count); recv_rme_b(bcs); } } if (val & 0x40) { /* RPF */ hscx_empty_fifo(bcs, fifo_size); recv_rpf_b(bcs); } if (val & 0x10) { xmit_xpr_b(bcs); } }
static void hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx) { u_char r; struct BCState *bcs = cs->bcs + hscx; struct sk_buff *skb; int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32; int count; if (!test_bit(BC_FLG_INIT, &bcs->Flag)) return; if (val & 0x80) { /* RME */ r = READHSCX(cs, hscx, HSCX_RSTA); if ((r & 0xf0) != 0xa0) { if (!(r & 0x80)) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX invalid frame"); #ifdef ERROR_STATISTIC bcs->err_inv++; #endif } if ((r & 0x40) && bcs->mode) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX RDO mode=%d", bcs->mode); #ifdef ERROR_STATISTIC bcs->err_rdo++; #endif } if (!(r & 0x20)) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX CRC error"); #ifdef ERROR_STATISTIC bcs->err_crc++; #endif } WriteHSCXCMDR(cs, hscx, 0x80); } else { count = READHSCX(cs, hscx, HSCX_RBCL) & ( test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f); if (count == 0) count = fifo_size; hscx_empty_fifo(bcs, count); if ((count = bcs->hw.hscx.rcvidx - 1) > 0) { if (cs->debug & L1_DEB_HSCX_FIFO) debugl1(cs, "HX Frame %d", count); if (!(skb = dev_alloc_skb(count))) #ifdef CONFIG_DEBUG_PRINTK printk(KERN_WARNING "HSCX: receive out of memory\n"); #else ; #endif else { memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count); skb_queue_tail(&bcs->rqueue, skb); } } }
static inline void mixcom_receive_frame(struct net_device *dev) { struct comx_channel *ch=dev->priv; struct mixcom_privdata *hw=ch->HW_privdata; register byte rsta; register word length; rsta = rd_hscx(dev, HSCX_RSTA) & (HSCX_VFR | HSCX_RDO | HSCX_CRC | HSCX_RAB); length = ((rd_hscx(dev, HSCX_RBCH) & 0x0f) << 8) | rd_hscx(dev, HSCX_RBCL); if ( length > hw->rx_ptr ) { hscx_empty_fifo(dev, length - hw->rx_ptr); } if (!(rsta & HSCX_VFR)) { ch->stats.rx_length_errors++; } if (rsta & HSCX_RDO) { ch->stats.rx_over_errors++; } if (!(rsta & HSCX_CRC)) { ch->stats.rx_crc_errors++; } if (rsta & HSCX_RAB) { ch->stats.rx_frame_errors++; } ch->stats.rx_packets++; ch->stats.rx_bytes += length; if (rsta == (HSCX_VFR | HSCX_CRC) && hw->recving) { skb_trim(hw->recving, hw->rx_ptr - 1); if (ch->debug_flags & DEBUG_HW_RX) { comx_debug_skb(dev, hw->recving, "MIXCOM_interrupt receiving"); } hw->recving->dev = dev; if (ch->LINE_rx) { ch->LINE_rx(dev, hw->recving); } } else if(hw->recving) { kfree_skb(hw->recving); } hw->recving = NULL; hw->rx_ptr = 0; }
static inline void hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx) { u_char r; struct BCState *bcs = cs->bcs + hscx; struct sk_buff *skb; int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32; int count; if (!test_bit(BC_FLG_INIT, &bcs->Flag)) return; if (val & 0x80) { /* RME */ r = READHSCX(cs, hscx, HSCX_RSTA); if ((r & 0xf0) != 0xa0) { if (!(r & 0x80)) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX invalid frame"); #ifdef ERROR_STATISTIC bcs->err_inv++; #endif } if ((r & 0x40) && bcs->mode) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX RDO mode=%d", bcs->mode); #ifdef ERROR_STATISTIC bcs->err_rdo++; #endif } if (!(r & 0x20)) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX CRC error"); #ifdef ERROR_STATISTIC bcs->err_crc++; #endif } WriteHSCXCMDR(cs, hscx, 0x80); } else { count = READHSCX(cs, hscx, HSCX_RBCL) & ( test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f); if (count == 0) count = fifo_size; hscx_empty_fifo(bcs, count); if ((count = bcs->hw.hscx.rcvidx - 1) > 0) { if (cs->debug & L1_DEB_HSCX_FIFO) debugl1(cs, "HX Frame %d", count); if (!(skb = dev_alloc_skb(count))) printk(KERN_WARNING "HSCX: receive out of memory\n"); else { memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count); skb_queue_tail(&bcs->rqueue, skb); } } } bcs->hw.hscx.rcvidx = 0; hscx_sched_event(bcs, B_RCVBUFREADY); } if (val & 0x40) { /* RPF */ hscx_empty_fifo(bcs, fifo_size); if (bcs->mode == L1_MODE_TRANS) { /* receive audio data */ if (!(skb = dev_alloc_skb(fifo_size))) printk(KERN_WARNING "HiSax: receive out of memory\n"); else { memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size); skb_queue_tail(&bcs->rqueue, skb); } bcs->hw.hscx.rcvidx = 0; hscx_sched_event(bcs, B_RCVBUFREADY); } } if (val & 0x10) { /* XPR */ if (bcs->tx_skb) { if (bcs->tx_skb->len) { hscx_fill_fifo(bcs); return; } else { if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count); dev_kfree_skb_irq(bcs->tx_skb); bcs->hw.hscx.count = 0; bcs->tx_skb = NULL; } } if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { bcs->hw.hscx.count = 0; test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); hscx_fill_fifo(bcs); } else { test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); hscx_sched_event(bcs, B_XMTBUFREADY); } } }
static inline void hscx_interrupt(struct IsdnCardState *sp, u_char val, u_char hscx) { u_char r; struct HscxState *hsp = sp->hs + hscx; struct sk_buff *skb; int count; char tmp[32]; if (!hsp->init) return; if (val & 0x80) { /* RME */ r = HscxReadReg(sp->hscx[hsp->hscx], hscx, HSCX_RSTA); if ((r & 0xf0) != 0xa0) { if (!(r & 0x80)) if (sp->debug & L1_DEB_WARN) debugl1(sp, "HSCX invalid frame"); if ((r & 0x40) && hsp->mode) if (sp->debug & L1_DEB_WARN) { sprintf(tmp, "HSCX RDO mode=%d", hsp->mode); debugl1(sp, tmp); } if (!(r & 0x20)) if (sp->debug & L1_DEB_WARN) debugl1(sp, "HSCX CRC error"); writehscxCMDR(sp->hscx[hsp->hscx], hsp->hscx, 0x80); } else { count = HscxReadReg(sp->hscx[hsp->hscx], hscx, HSCX_RBCL) & 0x1f; if (count == 0) count = 32; hscx_empty_fifo(hsp, count); if ((count = hsp->rcvidx - 1) > 0) { if (sp->debug & L1_DEB_HSCX_FIFO) { sprintf(tmp, "HX Frame %d", count); debugl1(sp, tmp); } if (!(skb = dev_alloc_skb(count))) printk(KERN_WARNING "IX1: receive out of memory\n"); else { memcpy(skb_put(skb, count), hsp->rcvbuf, count); skb_queue_tail(&hsp->rqueue, skb); } } } hsp->rcvidx = 0; hscx_sched_event(hsp, HSCX_RCVBUFREADY); } if (val & 0x40) { /* RPF */ hscx_empty_fifo(hsp, 32); if (hsp->mode == 1) { /* receive audio data */ if (!(skb = dev_alloc_skb(32))) printk(KERN_WARNING "IX1: receive out of memory\n"); else { memcpy(skb_put(skb, 32), hsp->rcvbuf, 32); skb_queue_tail(&hsp->rqueue, skb); } hsp->rcvidx = 0; hscx_sched_event(hsp, HSCX_RCVBUFREADY); } } if (val & 0x10) { /* XPR */ if (hsp->tx_skb) if (hsp->tx_skb->len) { hscx_fill_fifo(hsp); return; } else { dev_kfree_skb(hsp->tx_skb, FREE_WRITE); hsp->count = 0; if (hsp->st->l4.l1writewakeup) hsp->st->l4.l1writewakeup(hsp->st); hsp->tx_skb = NULL; } if ((hsp->tx_skb = skb_dequeue(&hsp->squeue))) { hsp->count = 0; hscx_fill_fifo(hsp); } else hscx_sched_event(hsp, HSCX_XMTBUFREADY); } }
static void MIXCOM_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; struct net_device *dev = (struct net_device *)dev_id; struct comx_channel *ch, *twin_ch; struct mixcom_privdata *hw, *twin_hw; register unsigned char ista; if (dev==NULL) { printk(KERN_ERR "comx_interrupt: irq %d for unknown device\n",irq); return; } ch = dev->priv; hw = ch->HW_privdata; save_flags(flags); cli(); while((ista = (rd_hscx(dev, HSCX_ISTA) & (HSCX_RME | HSCX_RPF | HSCX_XPR | HSCX_EXB | HSCX_EXA | HSCX_ICA)))) { register byte ista2 = 0; if (ista & HSCX_RME) { mixcom_receive_frame(dev); } if (ista & HSCX_RPF) { hscx_empty_fifo(dev, 32); } if (ista & HSCX_XPR) { if (hw->tx_ptr) { hscx_fill_fifo(dev); } else { clear_bit(0, &hw->txbusy); ch->LINE_tx(dev); } } if (ista & HSCX_EXB) { mixcom_extended_interrupt(dev); } if ((ista & HSCX_EXA) && ch->twin) { mixcom_extended_interrupt(ch->twin); } if ((ista & HSCX_ICA) && ch->twin && (ista2 = rd_hscx(ch->twin, HSCX_ISTA) & (HSCX_RME | HSCX_RPF | HSCX_XPR ))) { if (ista2 & HSCX_RME) { mixcom_receive_frame(ch->twin); } if (ista2 & HSCX_RPF) { hscx_empty_fifo(ch->twin, 32); } if (ista2 & HSCX_XPR) { twin_ch=ch->twin->priv; twin_hw=twin_ch->HW_privdata; if (twin_hw->tx_ptr) { hscx_fill_fifo(ch->twin); } else { clear_bit(0, &twin_hw->txbusy); ch->LINE_tx(ch->twin); } } } } restore_flags(flags); return; }