Beispiel #1
0
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);
	}
}
Beispiel #2
0
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);
				}
			}
		}
Beispiel #3
0
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;
}
Beispiel #4
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);
		}
	}
}
Beispiel #5
0
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);
	}
}
Beispiel #6
0
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;
}