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

📄 netjet.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				}			} else if (state ==  HDLC_FRAME_FOUND) {				if (val & 1) {					r_one++;					if (r_one>6) {						state=HDLC_ZERO_SEARCH;						bitcnt=0;					} else {						r_val >>= 1;						r_val |= 0x80;						bitcnt++;					}				} else {					if (r_one==6) {						r_val=0; 						r_one=0;						bitcnt++;						if (bitcnt & 7) {							debugl1(bcs->cs, "tiger: frame not byte aligned");							state=HDLC_FLAG_SEARCH;							bcs->hw.tiger.r_err++;#ifdef ERROR_STATISTIC							bcs->err_inv++;#endif						} else {							if (bcs->cs->debug & L1_DEB_HSCX)								debugl1(bcs->cs,"tiger frame end(%d,%d): fcs(%x) i %x",									i,j,bcs->hw.tiger.r_fcs, bcs->cs->hw.njet.irqstat0);							if (bcs->hw.tiger.r_fcs == PPP_GOODFCS) {								got_frame(bcs, (bitcnt>>3)-3);							} else {								if (bcs->cs->debug) {									debugl1(bcs->cs, "tiger FCS error");									printframe(bcs->cs, bcs->hw.tiger.rcvbuf,										(bitcnt>>3)-1, "rec");									bcs->hw.tiger.r_err++;								}#ifdef ERROR_STATISTIC							bcs->err_crc++;#endif							}							state=HDLC_FLAG_FOUND;						}						bitcnt=0;					} else if (r_one==5) {						val >>= 1;						r_one=0;						continue;					} else {						r_val >>= 1;						r_val &= 0x7f;						bitcnt++;					}					r_one=0;					}				if ((state == HDLC_FRAME_FOUND) &&					!(bitcnt & 7)) {					if ((bitcnt>>3)>=HSCX_BUFMAX) {						debugl1(bcs->cs, "tiger: frame too big");						r_val=0; 						state=HDLC_FLAG_SEARCH;						bcs->hw.tiger.r_err++;#ifdef ERROR_STATISTIC						bcs->err_inv++;#endif					} else {						bcs->hw.tiger.rcvbuf[(bitcnt>>3)-1] = r_val;						bcs->hw.tiger.r_fcs = 							PPP_FCS (bcs->hw.tiger.r_fcs, r_val);					}				}			}			val >>= 1;		}		bcs->hw.tiger.r_tot++;	}	bcs->hw.tiger.r_state = state;	bcs->hw.tiger.r_one = r_one;	bcs->hw.tiger.r_val = r_val;	bcs->hw.tiger.r_bitcnt = bitcnt;}void read_tiger(struct IsdnCardState *cs) {	u_int *p;	int cnt = NETJET_DMA_RXSIZE/2;		if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_READ) {		debugl1(cs,"tiger warn read double dma %x/%x",			cs->hw.njet.irqstat0, cs->hw.njet.last_is0);#ifdef ERROR_STATISTIC		if (cs->bcs[0].mode)			cs->bcs[0].err_rdo++;		if (cs->bcs[1].mode)			cs->bcs[1].err_rdo++;#endif		return;	} else {		cs->hw.njet.last_is0 &= ~NETJET_IRQM0_READ;		cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ);	}		if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ_1)		p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1;	else		p = cs->bcs[0].hw.tiger.rec + cnt - 1;	if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K))		read_raw(cs->bcs, p, cnt);	if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K))		read_raw(cs->bcs + 1, p, cnt);	cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_READ;}static void write_raw(struct BCState *bcs, u_int *buf, int cnt);void netjet_fill_dma(struct BCState *bcs){	register u_int *p, *sp;	register int cnt;	if (!bcs->tx_skb)		return;	if (bcs->cs->debug & L1_DEB_HSCX)		debugl1(bcs->cs,"tiger fill_dma1: c%d %4x", bcs->channel,			bcs->Flag);	if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag))		return;	if (bcs->mode == L1_MODE_HDLC) { // it's 64k		if (make_raw_data(bcs))			return;			}	else { // it's 56k		if (make_raw_data_56k(bcs))			return;			};	if (bcs->cs->debug & L1_DEB_HSCX)		debugl1(bcs->cs,"tiger fill_dma2: c%d %4x", bcs->channel,			bcs->Flag);	if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) {		write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);	} else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) {		p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR));		sp = bcs->hw.tiger.sendp;		if (p == bcs->hw.tiger.s_end)			p = bcs->hw.tiger.send -1;		if (sp == bcs->hw.tiger.s_end)			sp = bcs->hw.tiger.send -1;		cnt = p - sp;		if (cnt <0) {			write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);		} else {			p++;			cnt++;			if (p > bcs->hw.tiger.s_end)				p = bcs->hw.tiger.send;			p++;			cnt++;			if (p > bcs->hw.tiger.s_end)				p = bcs->hw.tiger.send;			write_raw(bcs, p, bcs->hw.tiger.free - cnt);		}	} else if (test_and_clear_bit(BC_FLG_EMPTY, &bcs->Flag)) {		p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR));		cnt = bcs->hw.tiger.s_end - p;		if (cnt < 2) {			p = bcs->hw.tiger.send + 1;			cnt = NETJET_DMA_TXSIZE/2 - 2;		} else {			p++;			p++;			if (cnt <= (NETJET_DMA_TXSIZE/2))				cnt += NETJET_DMA_TXSIZE/2;			cnt--;			cnt--;		}		write_raw(bcs, p, cnt);	}	if (bcs->cs->debug & L1_DEB_HSCX)		debugl1(bcs->cs,"tiger fill_dma3: c%d %4x", bcs->channel,			bcs->Flag);}static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {	u_int mask, val, *p=buf;	u_int i, s_cnt;                if (cnt <= 0)        	return;	if (test_bit(BC_FLG_BUSY, &bcs->Flag)) {		if (bcs->hw.tiger.sendcnt> cnt) {			s_cnt = cnt;			bcs->hw.tiger.sendcnt -= cnt;		} else {			s_cnt = bcs->hw.tiger.sendcnt;			bcs->hw.tiger.sendcnt = 0;		}		if (bcs->channel)			mask = 0xffff00ff;		else			mask = 0xffffff00;		for (i=0; i<s_cnt; i++) {			val = bcs->channel ? ((bcs->hw.tiger.sp[i] <<8) & 0xff00) :				(bcs->hw.tiger.sp[i]);			*p   &= mask;			*p++ |= val;			if (p>bcs->hw.tiger.s_end)				p = bcs->hw.tiger.send;		}		bcs->hw.tiger.s_tot += s_cnt;		if (bcs->cs->debug & L1_DEB_HSCX)			debugl1(bcs->cs,"tiger write_raw: c%d %p-%p %d/%d %d %x", bcs->channel,				buf, p, s_cnt, cnt,				bcs->hw.tiger.sendcnt, bcs->cs->hw.njet.irqstat0);		if (bcs->cs->debug & L1_DEB_HSCX_FIFO)			printframe(bcs->cs, bcs->hw.tiger.sp, s_cnt, "snd");		bcs->hw.tiger.sp += s_cnt;		bcs->hw.tiger.sendp = p;		if (!bcs->hw.tiger.sendcnt) {			if (!bcs->tx_skb) {				debugl1(bcs->cs,"tiger write_raw: NULL skb s_cnt %d", s_cnt);			} else {				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 = NULL;			}			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);			bcs->hw.tiger.free = cnt - s_cnt;			if (bcs->hw.tiger.free > (NETJET_DMA_TXSIZE/2))				test_and_set_bit(BC_FLG_HALF, &bcs->Flag);			else {				test_and_clear_bit(BC_FLG_HALF, &bcs->Flag);				test_and_set_bit(BC_FLG_NOFRAME, &bcs->Flag);			}			if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {				netjet_fill_dma(bcs);			} else {				mask ^= 0xffffffff;				if (s_cnt < cnt) {					for (i=s_cnt; i<cnt;i++) {						*p++ |= mask;						if (p>bcs->hw.tiger.s_end)							p = bcs->hw.tiger.send;					}					if (bcs->cs->debug & L1_DEB_HSCX)						debugl1(bcs->cs, "tiger write_raw: fill rest %d",							cnt - s_cnt);				}				test_and_set_bit(B_XMTBUFREADY, &bcs->event);				schedule_work(&bcs->tqueue);			}		}	} else if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) {		test_and_set_bit(BC_FLG_HALF, &bcs->Flag);		fill_mem(bcs, buf, cnt, bcs->channel, 0xff);		bcs->hw.tiger.free += cnt;		if (bcs->cs->debug & L1_DEB_HSCX)			debugl1(bcs->cs,"tiger write_raw: fill half");	} else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) {		test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag);		fill_mem(bcs, buf, cnt, bcs->channel, 0xff);		if (bcs->cs->debug & L1_DEB_HSCX)			debugl1(bcs->cs,"tiger write_raw: fill full");	}}void write_tiger(struct IsdnCardState *cs) {	u_int *p, cnt = NETJET_DMA_TXSIZE/2;		if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_WRITE) {		debugl1(cs,"tiger warn write double dma %x/%x",			cs->hw.njet.irqstat0, cs->hw.njet.last_is0);#ifdef ERROR_STATISTIC		if (cs->bcs[0].mode)			cs->bcs[0].err_tx++;		if (cs->bcs[1].mode)			cs->bcs[1].err_tx++;#endif		return;	} else {		cs->hw.njet.last_is0 &= ~NETJET_IRQM0_WRITE;		cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE);	}		if (cs->hw.njet.irqstat0  & NETJET_IRQM0_WRITE_1)		p = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1;	else		p = cs->bcs[0].hw.tiger.send + cnt - 1;	if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K))		write_raw(cs->bcs, p, cnt);	if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K))		write_raw(cs->bcs + 1, p, cnt);	cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_WRITE;}static voidtiger_l2l1(struct PStack *st, int pr, void *arg){	struct BCState *bcs = st->l1.bcs;	struct sk_buff *skb = arg;	u_long flags;	switch (pr) {		case (PH_DATA | REQUEST):			spin_lock_irqsave(&bcs->cs->lock, flags);			if (bcs->tx_skb) {				skb_queue_tail(&bcs->squeue, skb);			} else {				bcs->tx_skb = skb;				bcs->cs->BC_Send_Data(bcs);			}			spin_unlock_irqrestore(&bcs->cs->lock, flags);			break;		case (PH_PULL | INDICATION):			spin_lock_irqsave(&bcs->cs->lock, flags);			if (bcs->tx_skb) {				printk(KERN_WARNING "tiger_l2l1: this shouldn't happen\n");			} else {				bcs->tx_skb = skb;				bcs->cs->BC_Send_Data(bcs);			}			spin_unlock_irqrestore(&bcs->cs->lock, flags);			break;		case (PH_PULL | REQUEST):			if (!bcs->tx_skb) {				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);			} else				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);			break;		case (PH_ACTIVATE | REQUEST):			spin_lock_irqsave(&bcs->cs->lock, flags);			test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);			mode_tiger(bcs, st->l1.mode, st->l1.bc);			/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */			spin_unlock_irqrestore(&bcs->cs->lock, flags);			bcs->cs->cardmsg(bcs->cs, MDL_BC_ASSIGN, (void *)(&st->l1.bc));			l1_msg_b(st, pr, arg);			break;		case (PH_DEACTIVATE | REQUEST):			/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */			bcs->cs->cardmsg(bcs->cs, MDL_BC_RELEASE, (void *)(&st->l1.bc));			l1_msg_b(st, pr, arg);			break;		case (PH_DEACTIVATE | CONFIRM):			spin_lock_irqsave(&bcs->cs->lock, flags);			test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);			mode_tiger(bcs, 0, st->l1.bc);			spin_unlock_irqrestore(&bcs->cs->lock, flags);			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);			break;	}}static voidclose_tigerstate(struct BCState *bcs){	mode_tiger(bcs, 0, bcs->channel);	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {		kfree(bcs->hw.tiger.rcvbuf);		bcs->hw.tiger.rcvbuf = NULL;		kfree(bcs->hw.tiger.sendbuf);		bcs->hw.tiger.sendbuf = NULL;		skb_queue_purge(&bcs->rqueue);		skb_queue_purge(&bcs->squeue);		if (bcs->tx_skb) {			dev_kfree_skb_any(bcs->tx_skb);			bcs->tx_skb = NULL;			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);		}	}}static intopen_tigerstate(struct IsdnCardState *cs, struct BCState *bcs){	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {		if (!(bcs->hw.tiger.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {			printk(KERN_WARNING			       "HiSax: No memory for tiger.rcvbuf\n");			return (1);		}		if (!(bcs->hw.tiger.sendbuf = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) {			printk(KERN_WARNING			       "HiSax: No memory for tiger.sendbuf\n");			return (1);		}		skb_queue_head_init(&bcs->rqueue);		skb_queue_head_init(&bcs->squeue);	}	bcs->tx_skb = NULL;	bcs->hw.tiger.sendcnt = 0;	test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);	bcs->event = 0;	bcs->tx_cnt = 0;	return (0);}static intsetstack_tiger(struct PStack *st, struct BCState *bcs){	bcs->channel = st->l1.bc;	if (open_tigerstate(st->l1.hardware, bcs))		return (-1);	st->l1.bcs = bcs;	st->l2.l2l1 = tiger_l2l1;	setstack_manager(st);	bcs->st = st;	setstack_l1_B(st);	return (0);} voidinittiger(struct IsdnCardState *cs){	if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_TXSIZE * sizeof(unsigned int),		GFP_KERNEL | GFP_DMA))) {		printk(KERN_WARNING		       "HiSax: No memory for tiger.send\n");		return;	}	cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE/2 - 1;	cs->bcs[0].hw.tiger.s_end = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1;	cs->bcs[1].hw.tiger.send = cs->bcs[0].hw.tiger.send;	cs->bcs[1].hw.tiger.s_irq = cs->bcs[0].hw.tiger.s_irq;	cs->bcs[1].hw.tiger.s_end = cs->bcs[0].hw.tiger.s_end;		memset(cs->bcs[0].hw.tiger.send, 0xff, NETJET_DMA_TXSIZE * sizeof(unsigned int));	debugl1(cs, "tiger: send buf %p - %p", cs->bcs[0].hw.tiger.send,		cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1);	outl(virt_to_bus(cs->bcs[0].hw.tiger.send),		cs->hw.njet.base + NETJET_DMA_READ_START);	outl(virt_to_bus(cs->bcs[0].hw.tiger.s_irq),		cs->hw.njet.base + NETJET_DMA_READ_IRQ);	outl(virt_to_bus(cs->bcs[0].hw.tiger.s_end),		cs->hw.njet.base + NETJET_DMA_READ_END);	if (!(cs->bcs[0].hw.tiger.rec = kmalloc(NETJET_DMA_RXSIZE * sizeof(unsigned int),		GFP_KERNEL | GFP_DMA))) {		printk(KERN_WARNING		       "HiSax: No memory for tiger.rec\n");		return;	}	debugl1(cs, "tiger: rec buf %p - %p", cs->bcs[0].hw.tiger.rec,		cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1);	cs->bcs[1].hw.tiger.rec = cs->bcs[0].hw.tiger.rec;	memset(cs->bcs[0].hw.tiger.rec, 0xff, NETJET_DMA_RXSIZE * sizeof(unsigned int));	outl(virt_to_bus(cs->bcs[0].hw.tiger.rec),		cs->hw.njet.base + NETJET_DMA_WRITE_START);	outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE/2 - 1),		cs->hw.njet.base + NETJET_DMA_WRITE_IRQ);	outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1),		cs->hw.njet.base + NETJET_DMA_WRITE_END);	debugl1(cs, "tiger: dmacfg  %x/%x  pulse=%d",		inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),		inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),		bytein(cs->hw.njet.base + NETJET_PULSE_CNT));	cs->hw.njet.last_is0 = 0;	cs->bcs[0].BC_SetStack = setstack_tiger;	cs->bcs[1].BC_SetStack = setstack_tiger;	cs->bcs[0].BC_Close = close_tigerstate;	cs->bcs[1].BC_Close = close_tigerstate;}static voidreleasetiger(struct IsdnCardState *cs){	kfree(cs->bcs[0].hw.tiger.send);	cs->bcs[0].hw.tiger.send = NULL;	cs->bcs[1].hw.tiger.send = NULL;	kfree(cs->bcs[0].hw.tiger.rec);	cs->bcs[0].hw.tiger.rec = NULL;	cs->bcs[1].hw.tiger.rec = NULL;}voidrelease_io_netjet(struct IsdnCardState *cs){	byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);	byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0);	releasetiger(cs);	release_region(cs->hw.njet.base, 256);}

⌨️ 快捷键说明

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