⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hfc_pci.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
		skb_queue_tail(&bcs->rqueue, skb);		hfcpci_sched_event(bcs, B_RCVBUFREADY);	}	*z2r = new_z2;		/* new position */	return (1);}				/* hfcpci_empty_fifo_trans *//**********************************//* B-channel main receive routine *//**********************************/static voidmain_rec_hfcpci(struct BCState *bcs){	struct IsdnCardState *cs = bcs->cs;	int rcnt, real_fifo;	int receive, count = 5;	struct sk_buff *skb;	bzfifo_type *bz;	u_char *bdata;	z_type *zp;	if ((bcs->channel) && (!cs->hw.hfcpci.bswapped)) {		bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2;		bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b2;		real_fifo = 1;	} else {		bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b1;		bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b1;		real_fifo = 0;	}      Begin:	count--;	if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {		debugl1(cs, "rec_data %d blocked", bcs->channel);		return;	}	if (bz->f1 != bz->f2) {		if (cs->debug & L1_DEB_HSCX)			debugl1(cs, "hfcpci rec %d f1(%d) f2(%d)",				bcs->channel, bz->f1, bz->f2);		zp = &bz->za[bz->f2];		rcnt = zp->z1 - zp->z2;		if (rcnt < 0)			rcnt += B_FIFO_SIZE;		rcnt++;		if (cs->debug & L1_DEB_HSCX)			debugl1(cs, "hfcpci rec %d z1(%x) z2(%x) cnt(%d)",				bcs->channel, zp->z1, zp->z2, rcnt);		if ((skb = hfcpci_empty_fifo(bcs, bz, bdata, rcnt))) {			skb_queue_tail(&bcs->rqueue, skb);			hfcpci_sched_event(bcs, B_RCVBUFREADY);		}		rcnt = bz->f1 - bz->f2;		if (rcnt < 0)			rcnt += MAX_B_FRAMES + 1;		if (cs->hw.hfcpci.last_bfifo_cnt[real_fifo] > rcnt + 1) {		        rcnt = 0;			hfcpci_clear_fifo_rx(cs, real_fifo);		}		cs->hw.hfcpci.last_bfifo_cnt[real_fifo] = rcnt;		if (rcnt > 1)			receive = 1;		else			receive = 0;	} else if (bcs->mode == L1_MODE_TRANS)		receive = hfcpci_empty_fifo_trans(bcs, bz, bdata);	else		receive = 0;	test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);	if (count && receive)		goto Begin;	return;}/**************************//* D-channel send routine *//**************************/static voidhfcpci_fill_dfifo(struct IsdnCardState *cs){	int fcnt;	int count, new_z1, maxlen;	dfifo_type *df;	u_char *src, *dst, new_f1;	if (!cs->tx_skb)		return;	if (cs->tx_skb->len <= 0)		return;	df = &((fifo_area *) (cs->hw.hfcpci.fifos))->d_chan.d_tx;	if (cs->debug & L1_DEB_ISAC)		debugl1(cs, "hfcpci_fill_Dfifo f1(%d) f2(%d) z1(f1)(%x)",			df->f1, df->f2,			df->za[df->f1 & D_FREG_MASK].z1);	fcnt = df->f1 - df->f2;	/* frame count actually buffered */	if (fcnt < 0)		fcnt += (MAX_D_FRAMES + 1);	/* if wrap around */	if (fcnt > (MAX_D_FRAMES - 1)) {		if (cs->debug & L1_DEB_ISAC)			debugl1(cs, "hfcpci_fill_Dfifo more as 14 frames");#ifdef ERROR_STATISTIC		cs->err_tx++;#endif		return;	}	/* now determine free bytes in FIFO buffer */	count = df->za[df->f2 & D_FREG_MASK].z2 - df->za[df->f1 & D_FREG_MASK].z1 - 1;	if (count <= 0)		count += D_FIFO_SIZE;	/* count now contains available bytes */	if (cs->debug & L1_DEB_ISAC)		debugl1(cs, "hfcpci_fill_Dfifo count(%ld/%d)",			cs->tx_skb->len, count);	if (count < cs->tx_skb->len) {		if (cs->debug & L1_DEB_ISAC)			debugl1(cs, "hfcpci_fill_Dfifo no fifo mem");		return;	}	count = cs->tx_skb->len;	/* get frame len */	new_z1 = (df->za[df->f1 & D_FREG_MASK].z1 + count) & (D_FIFO_SIZE - 1);	new_f1 = ((df->f1 + 1) & D_FREG_MASK) | (D_FREG_MASK + 1);	src = cs->tx_skb->data;	/* source pointer */	dst = df->data + df->za[df->f1 & D_FREG_MASK].z1;	maxlen = D_FIFO_SIZE - df->za[df->f1 & D_FREG_MASK].z1;		/* end fifo */	if (maxlen > count)		maxlen = count;	/* limit size */	memcpy(dst, src, maxlen);	/* first copy */	count -= maxlen;	/* remaining bytes */	if (count) {		dst = df->data;	/* start of buffer */		src += maxlen;	/* new position */		memcpy(dst, src, count);	}	df->za[new_f1 & D_FREG_MASK].z1 = new_z1;	/* for next buffer */	df->za[df->f1 & D_FREG_MASK].z1 = new_z1;	/* new pos actual buffer */	df->f1 = new_f1;	/* next frame */	dev_kfree_skb_any(cs->tx_skb);	cs->tx_skb = NULL;	return;}/**************************//* B-channel send routine *//**************************/static voidhfcpci_fill_fifo(struct BCState *bcs){	struct IsdnCardState *cs = bcs->cs;	int maxlen, fcnt;	int count, new_z1;	bzfifo_type *bz;	u_char *bdata;	u_char new_f1, *src, *dst;	unsigned short *z1t, *z2t;	if (!bcs->tx_skb)		return;	if (bcs->tx_skb->len <= 0)		return;	if ((bcs->channel) && (!cs->hw.hfcpci.bswapped)) {		bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b2;		bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txdat_b2;	} else {		bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b1;		bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txdat_b1;	}	if (bcs->mode == L1_MODE_TRANS) {		z1t = &bz->za[MAX_B_FRAMES].z1;		z2t = z1t + 1;		if (cs->debug & L1_DEB_HSCX)			debugl1(cs, "hfcpci_fill_fifo_trans %d z1(%x) z2(%x)",				bcs->channel, *z1t, *z2t);		fcnt = *z2t - *z1t;		if (fcnt <= 0)			fcnt += B_FIFO_SIZE;	/* fcnt contains available bytes in fifo */		fcnt = B_FIFO_SIZE - fcnt;	/* remaining bytes to send */		while ((fcnt < 2 * HFCPCI_BTRANS_THRESHOLD) && (bcs->tx_skb)) {			if (bcs->tx_skb->len < B_FIFO_SIZE - fcnt) {				/* data is suitable for fifo */				count = bcs->tx_skb->len;				new_z1 = *z1t + count;	/* new buffer Position */				if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))					new_z1 -= B_FIFO_SIZE;	/* buffer wrap */				src = bcs->tx_skb->data;	/* source pointer */				dst = bdata + (*z1t - B_SUB_VAL);				maxlen = (B_FIFO_SIZE + B_SUB_VAL) - *z1t;	/* end of fifo */				if (maxlen > count)					maxlen = count;		/* limit size */				memcpy(dst, src, maxlen);	/* first copy */				count -= maxlen;	/* remaining bytes */				if (count) {					dst = bdata;	/* start of buffer */					src += maxlen;	/* new position */					memcpy(dst, src, count);				}				bcs->tx_cnt -= bcs->tx_skb->len;				fcnt += bcs->tx_skb->len;				*z1t = new_z1;	/* now send data */			} else if (cs->debug & L1_DEB_HSCX)				debugl1(cs, "hfcpci_fill_fifo_trans %d frame length %d discarded",					bcs->channel, bcs->tx_skb->len);			if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&				(PACKET_NOACK != bcs->tx_skb->pkt_type)) {				u_long	flags;				spin_lock_irqsave(&bcs->aclock, flags);				bcs->ackcnt += bcs->tx_skb->len;				spin_unlock_irqrestore(&bcs->aclock, flags);				schedule_event(bcs, B_ACKPENDING);			}			dev_kfree_skb_any(bcs->tx_skb);			bcs->tx_skb = skb_dequeue(&bcs->squeue);	/* fetch next data */		}		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);		return;	}	if (cs->debug & L1_DEB_HSCX)		debugl1(cs, "hfcpci_fill_fifo_hdlc %d f1(%d) f2(%d) z1(f1)(%x)",			bcs->channel, bz->f1, bz->f2,			bz->za[bz->f1].z1);	fcnt = bz->f1 - bz->f2;	/* frame count actually buffered */	if (fcnt < 0)		fcnt += (MAX_B_FRAMES + 1);	/* if wrap around */	if (fcnt > (MAX_B_FRAMES - 1)) {		if (cs->debug & L1_DEB_HSCX)			debugl1(cs, "hfcpci_fill_Bfifo more as 14 frames");		return;	}	/* now determine free bytes in FIFO buffer */	count = bz->za[bz->f2].z2 - bz->za[bz->f1].z1 - 1;	if (count <= 0)		count += B_FIFO_SIZE;	/* count now contains available bytes */	if (cs->debug & L1_DEB_HSCX)		debugl1(cs, "hfcpci_fill_fifo %d count(%ld/%d),%lx",			bcs->channel, bcs->tx_skb->len,			count, current->state);	if (count < bcs->tx_skb->len) {		if (cs->debug & L1_DEB_HSCX)			debugl1(cs, "hfcpci_fill_fifo no fifo mem");		return;	}	count = bcs->tx_skb->len;	/* get frame len */	new_z1 = bz->za[bz->f1].z1 + count;	/* new buffer Position */	if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))		new_z1 -= B_FIFO_SIZE;	/* buffer wrap */	new_f1 = ((bz->f1 + 1) & MAX_B_FRAMES);	src = bcs->tx_skb->data;	/* source pointer */	dst = bdata + (bz->za[bz->f1].z1 - B_SUB_VAL);	maxlen = (B_FIFO_SIZE + B_SUB_VAL) - bz->za[bz->f1].z1;		/* end fifo */	if (maxlen > count)		maxlen = count;	/* limit size */	memcpy(dst, src, maxlen);	/* first copy */	count -= maxlen;	/* remaining bytes */	if (count) {		dst = bdata;	/* start of buffer */		src += maxlen;	/* new position */		memcpy(dst, src, count);	}	bcs->tx_cnt -= bcs->tx_skb->len;	if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&		(PACKET_NOACK != bcs->tx_skb->pkt_type)) {		u_long	flags;		spin_lock_irqsave(&bcs->aclock, flags);		bcs->ackcnt += bcs->tx_skb->len;		spin_unlock_irqrestore(&bcs->aclock, flags);		schedule_event(bcs, B_ACKPENDING);	}	bz->za[new_f1].z1 = new_z1;	/* for next buffer */	bz->f1 = new_f1;	/* next frame */	dev_kfree_skb_any(bcs->tx_skb);	bcs->tx_skb = NULL;	test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);	return;}/**********************************************//* D-channel l1 state call for leased NT-mode *//**********************************************/static voiddch_nt_l2l1(struct PStack *st, int pr, void *arg){	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;	switch (pr) {		case (PH_DATA | REQUEST):		case (PH_PULL | REQUEST):		case (PH_PULL | INDICATION):			st->l1.l1hw(st, pr, arg);			break;		case (PH_ACTIVATE | REQUEST):			st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);			break;		case (PH_TESTLOOP | REQUEST):			if (1 & (long) arg)				debugl1(cs, "PH_TEST_LOOP B1");			if (2 & (long) arg)				debugl1(cs, "PH_TEST_LOOP B2");			if (!(3 & (long) arg))				debugl1(cs, "PH_TEST_LOOP DISABLED");			st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg);			break;		default:			if (cs->debug)				debugl1(cs, "dch_nt_l2l1 msg %04X unhandled", pr);			break;	}}/***********************//* set/reset echo mode *//***********************/static inthfcpci_auxcmd(struct IsdnCardState *cs, isdn_ctrl * ic){	u_long	flags;	int	i = *(unsigned int *) ic->parm.num;	if ((ic->arg == 98) &&	    (!(cs->hw.hfcpci.int_m1 & (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC + HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC)))) {	    	spin_lock_irqsave(&cs->lock, flags);		Write_hfc(cs, HFCPCI_CLKDEL, CLKDEL_NT); /* ST-Bit delay for NT-Mode */		Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 0);	/* HFC ST G0 */		udelay(10);		cs->hw.hfcpci.sctrl |= SCTRL_MODE_NT;		Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl);	/* set NT-mode */		udelay(10);		Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 1);	/* HFC ST G1 */		udelay(10);		Write_hfc(cs, HFCPCI_STATES, 1 | HFCPCI_ACTIVATE | HFCPCI_DO_ACTION);		cs->dc.hfcpci.ph_state = 1;		cs->hw.hfcpci.nt_mode = 1;		cs->hw.hfcpci.nt_timer = 0;		cs->stlist->l2.l2l1 = dch_nt_l2l1;		spin_unlock_irqrestore(&cs->lock, flags);		debugl1(cs, "NT mode activated");		return (0);	}	if ((cs->chanlimit > 1) || (cs->hw.hfcpci.bswapped) ||	    (cs->hw.hfcpci.nt_mode) || (ic->arg != 12))		return (-EINVAL);	spin_lock_irqsave(&cs->lock, flags);	if (i) {		cs->logecho = 1;		cs->hw.hfcpci.trm |= 0x20;	/* enable echo chan */		cs->hw.hfcpci.int_m1 |= HFCPCI_INTS_B2REC;		cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2RX;	} else {		cs->logecho = 0;		cs->hw.hfcpci.trm &= ~0x20;	/* disable echo chan */		cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_B2REC;		cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2RX;	}	cs->hw.hfcpci.sctrl_r &= ~SCTRL_B2_ENA;	cs->hw.hfcpci.sctrl &= ~SCTRL_B2_ENA;	cs->hw.hfcpci.conn |= 0x10;	/* B2-IOM -> B2-ST */	cs->hw.hfcpci.ctmt &= ~2;	Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt);	Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r);	Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl);	Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn);	Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm);	Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en);	Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);	spin_unlock_irqrestore(&cs->lock, flags);	return (0);}				/* hfcpci_auxcmd *//*****************************//* E-channel receive routine *//*****************************/static voidreceive_emsg(struct IsdnCardState *cs){	int rcnt;	int receive, count = 5;	bzfifo_type *bz;	u_char *bdata;	z_type *zp;	u_char *ptr, *ptr1, new_f2;	int total, maxlen, new_z2;	u_char e_buffer[256];	bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2;	bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b2;      Begin:	count--;	if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {		debugl1(cs, "echo_rec_data blocked");		return;	}	if (bz->f1 != bz->f2) {		if (cs->debug & L1_DEB_ISAC)			debugl1(cs, "hfcpci e_rec f1(%d) f2(%d)",				bz->f1, bz->f2);		zp = &bz->za[bz->f2];		rcnt = zp->z1 - zp->z2;		if (rcnt < 0)			rcnt += B_FIFO_SIZE;		rcnt++;		if (cs->debug & L1_DEB_ISAC)			debugl1(cs, "hfcpci e_rec z1(%x) z2(%x) cnt(%d)",				zp->z1, zp->z2, rcnt);		new_z2 = zp->z2 + rcnt;		/* new position in fifo */		if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL))			new_z2 -= B_FIFO_SIZE;	/* buffer wrap */		new_f2 = (bz->f2 + 1) & MAX_B_FRAMES;		if ((rcnt > 256 + 3) || (count < 4) ||		    (*(bdata + (zp->z1 - B_SUB_VAL)))) {			if (cs->debug & L1_DEB_WARN)				debugl1(cs, "hfcpci_empty_echan: incoming packet invalid length %d or crc", rcnt);			bz->za[new_f2].z2 = new_z2;			bz->f2 = new_f2;	/* next buffer */		} else {			total = rcnt;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -