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

📄 zatm.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
	zatm_dev->factor = (1000 << TIMER_SHIFT)/(zatm_dev->khz+1);	zatm_dev->timer_diffs = 0;	memset(zatm_dev->timer_history,0,sizeof(zatm_dev->timer_history));	zatm_dev->th_curr = 0;	save_flags(flags);	cli();	do_gettimeofday(&zatm_dev->last_time);	zatm_dev->last_clk = zpeekl(zatm_dev,uPD98401_TSR);	if (start_timer) {		start_timer = 0;		init_timer(&sync_timer);		sync_timer.expires = jiffies+POLL_INTERVAL*HZ;		sync_timer.function = zatm_clock_sync;		add_timer(&sync_timer);	}	restore_flags(flags);}#endif/*----------------------------------- RX ------------------------------------*/#if 0static void exception(struct atm_vcc *vcc){   static int count = 0;   struct zatm_dev *zatm_dev = ZATM_DEV(vcc->dev);   struct zatm_vcc *zatm_vcc = ZATM_VCC(vcc);   unsigned long *qrp;   int i;   if (count++ > 2) return;   for (i = 0; i < 8; i++)	printk("TX%d: 0x%08lx\n",i,	  zpeekl(zatm_dev,zatm_vcc->tx_chan*VC_SIZE/4+i));   for (i = 0; i < 5; i++)	printk("SH%d: 0x%08lx\n",i,	  zpeekl(zatm_dev,uPD98401_IM(zatm_vcc->shaper)+16*i));   qrp = (unsigned long *) zpeekl(zatm_dev,zatm_vcc->tx_chan*VC_SIZE/4+     uPD98401_TXVC_QRP);   printk("qrp=0x%08lx\n",(unsigned long) qrp);   for (i = 0; i < 4; i++) printk("QRP[%d]: 0x%08lx",i,qrp[i]);}#endifstatic const char *err_txt[] = {	"No error",	"RX buf underflow",	"RX FIFO overrun",	"Maximum len violation",	"CRC error",	"User abort",	"Length violation",	"T1 error",	"Deactivated",	"???",	"???",	"???",	"???",	"???",	"???",	"???"};static void poll_rx(struct atm_dev *dev,int mbx){	struct zatm_dev *zatm_dev;	unsigned long pos;	u32 x;	int error;	EVENT("poll_rx\n",0,0);	zatm_dev = ZATM_DEV(dev);	pos = (zatm_dev->mbx_start[mbx] & ~0xffffUL) | zin(MTA(mbx));	while (x = zin(MWA(mbx)), (pos & 0xffff) != x) {		u32 *here;		struct sk_buff *skb;		struct atm_vcc *vcc;		int cells,size,chan;		EVENT("MBX: host 0x%lx, nic 0x%x\n",pos,x);		here = (u32 *) pos;		if (((pos += 16) & 0xffff) == zatm_dev->mbx_end[mbx])			pos = zatm_dev->mbx_start[mbx];		cells = here[0] & uPD98401_AAL5_SIZE;#if 0printk("RX IND: 0x%x, 0x%x, 0x%x, 0x%x\n",here[0],here[1],here[2],here[3]);{unsigned long *x;		printk("POOL: 0x%08x, 0x%08x\n",zpeekl(zatm_dev,		      zatm_dev->pool_base),		      zpeekl(zatm_dev,zatm_dev->pool_base+1));		x = (unsigned long *) here[2];		printk("[0..3] = 0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx\n",		    x[0],x[1],x[2],x[3]);}#endif		error = 0;		if (here[3] & uPD98401_AAL5_ERR) {			error = (here[3] & uPD98401_AAL5_ES) >>			    uPD98401_AAL5_ES_SHIFT;			if (error == uPD98401_AAL5_ES_DEACT ||			    error == uPD98401_AAL5_ES_FREE) continue;		}EVENT("error code 0x%x/0x%x\n",(here[3] & uPD98401_AAL5_ES) >>  uPD98401_AAL5_ES_SHIFT,error);		skb = ((struct rx_buffer_head *) bus_to_virt(here[2]))->skb;#ifdef CONFIG_ATM_ZATM_EXACT_TS		skb->stamp = exact_time(zatm_dev,here[1]);#else		skb->stamp = xtime;#endif#if 0printk("[-3..0] 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",((unsigned *) skb->data)[-3],  ((unsigned *) skb->data)[-2],((unsigned *) skb->data)[-1],  ((unsigned *) skb->data)[0]);#endif		EVENT("skb 0x%lx, here 0x%lx\n",(unsigned long) skb,		    (unsigned long) here);#if 0printk("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);#endif		size = error ? 0 : ntohs(((u16 *) skb->data)[cells*		    ATM_CELL_PAYLOAD/sizeof(u16)-3]);		EVENT("got skb 0x%lx, size %d\n",(unsigned long) skb,size);		chan = (here[3] & uPD98401_AAL5_CHAN) >>		    uPD98401_AAL5_CHAN_SHIFT;		if (chan < zatm_dev->chans && zatm_dev->rx_map[chan]) {			vcc = zatm_dev->rx_map[chan];			if (skb == zatm_dev->last_free[ZATM_VCC(vcc)->pool])				zatm_dev->last_free[ZATM_VCC(vcc)->pool] = NULL;			skb_unlink(skb);		}		else {			printk(KERN_ERR DEV_LABEL "(itf %d): RX indication "			    "for non-existing channel\n",dev->number);			size = 0;			vcc = NULL;			event_dump();		}		if (error) {			static unsigned long silence = 0;			static int last_error = 0;			if (error != last_error ||			    time_after(jiffies, silence)  || silence == 0){				printk(KERN_WARNING DEV_LABEL "(itf %d): "				    "chan %d error %s\n",dev->number,chan,				    err_txt[error]);				last_error = error;				silence = (jiffies+2*HZ)|1;			}			size = 0;		}		if (size && (size > cells*ATM_CELL_PAYLOAD-ATM_AAL5_TRAILER ||		    size <= (cells-1)*ATM_CELL_PAYLOAD-ATM_AAL5_TRAILER)) {			printk(KERN_ERR DEV_LABEL "(itf %d): size %d with %d "			    "cells\n",dev->number,size,cells);			size = 0;			event_dump();		}		if (size > ATM_MAX_AAL5_PDU) {			printk(KERN_ERR DEV_LABEL "(itf %d): size too big "			    "(%d)\n",dev->number,size);			size = 0;			event_dump();		}		if (!size) {			dev_kfree_skb_irq(skb);			if (vcc) atomic_inc(&vcc->stats->rx_err);			continue;		}		if (!atm_charge(vcc,skb->truesize)) {			dev_kfree_skb_irq(skb);			continue;		}		skb->len = size;		ATM_SKB(skb)->vcc = vcc;		vcc->push(vcc,skb);		atomic_inc(&vcc->stats->rx);	}	zout(pos & 0xffff,MTA(mbx));#if 0 /* probably a stupid idea */	refill_pool(dev,zatm_vcc->pool);		/* maybe this saves us a few interrupts */#endif}static int open_rx_first(struct atm_vcc *vcc){	struct zatm_dev *zatm_dev;	struct zatm_vcc *zatm_vcc;	unsigned long flags;	unsigned short chan;	int cells;	DPRINTK("open_rx_first (0x%x)\n",inb_p(0xc053));	zatm_dev = ZATM_DEV(vcc->dev);	zatm_vcc = ZATM_VCC(vcc);	zatm_vcc->rx_chan = 0;	if (vcc->qos.rxtp.traffic_class == ATM_NONE) return 0;	if (vcc->qos.aal == ATM_AAL5) {		if (vcc->qos.rxtp.max_sdu > 65464)			vcc->qos.rxtp.max_sdu = 65464;			/* fix this - we may want to receive 64kB SDUs			   later */		cells = (vcc->qos.rxtp.max_sdu+ATM_AAL5_TRAILER+		    ATM_CELL_PAYLOAD-1)/ATM_CELL_PAYLOAD;		zatm_vcc->pool = pool_index(cells*ATM_CELL_PAYLOAD);	}	else {		cells = 1;		zatm_vcc->pool = ZATM_AAL0_POOL;	}	if (zatm_vcc->pool < 0) return -EMSGSIZE;	save_flags(flags);	cli();	zwait;	zout(uPD98401_OPEN_CHAN,CMR);	zwait;	DPRINTK("0x%x 0x%x\n",zin(CMR),zin(CER));	chan = (zin(CMR) & uPD98401_CHAN_ADDR) >> uPD98401_CHAN_ADDR_SHIFT;	restore_flags(flags);	DPRINTK("chan is %d\n",chan);	if (!chan) return -EAGAIN;	use_pool(vcc->dev,zatm_vcc->pool);	DPRINTK("pool %d\n",zatm_vcc->pool);	/* set up VC descriptor */	cli();	zpokel(zatm_dev,zatm_vcc->pool << uPD98401_RXVC_POOL_SHIFT,	    chan*VC_SIZE/4);	zpokel(zatm_dev,uPD98401_RXVC_OD | (vcc->qos.aal == ATM_AAL5 ?	    uPD98401_RXVC_AR : 0) | cells,chan*VC_SIZE/4+1);	zpokel(zatm_dev,0,chan*VC_SIZE/4+2);	zatm_vcc->rx_chan = chan;	zatm_dev->rx_map[chan] = vcc;	restore_flags(flags);	return 0;}static int open_rx_second(struct atm_vcc *vcc){	struct zatm_dev *zatm_dev;	struct zatm_vcc *zatm_vcc;	unsigned long flags;	int pos,shift;	DPRINTK("open_rx_second (0x%x)\n",inb_p(0xc053));	zatm_dev = ZATM_DEV(vcc->dev);	zatm_vcc = ZATM_VCC(vcc);	if (!zatm_vcc->rx_chan) return 0;	save_flags(flags);	cli();	/* should also handle VPI @@@ */	pos = vcc->vci >> 1;	shift = (1-(vcc->vci & 1)) << 4;	zpokel(zatm_dev,(zpeekl(zatm_dev,pos) & ~(0xffff << shift)) |	    ((zatm_vcc->rx_chan | uPD98401_RXLT_ENBL) << shift),pos);	restore_flags(flags);	return 0;}static void close_rx(struct atm_vcc *vcc){	struct zatm_dev *zatm_dev;	struct zatm_vcc *zatm_vcc;	unsigned long flags;	int pos,shift;	zatm_vcc = ZATM_VCC(vcc);	zatm_dev = ZATM_DEV(vcc->dev);	if (!zatm_vcc->rx_chan) return;	DPRINTK("close_rx\n");	/* disable receiver */	save_flags(flags);	if (vcc->vpi != ATM_VPI_UNSPEC && vcc->vci != ATM_VCI_UNSPEC) {		cli();		pos = vcc->vci >> 1;		shift = (1-(vcc->vci & 1)) << 4;		zpokel(zatm_dev,zpeekl(zatm_dev,pos) & ~(0xffff << shift),pos);		zwait;		zout(uPD98401_NOP,CMR);		zwait;		zout(uPD98401_NOP,CMR);		restore_flags(flags);	}	cli();	zwait;	zout(uPD98401_DEACT_CHAN | uPD98401_CHAN_RT | (zatm_vcc->rx_chan <<	    uPD98401_CHAN_ADDR_SHIFT),CMR);	zwait;	udelay(10); /* why oh why ... ? */	zout(uPD98401_CLOSE_CHAN | uPD98401_CHAN_RT | (zatm_vcc->rx_chan <<	    uPD98401_CHAN_ADDR_SHIFT),CMR);	zwait;	if (!(zin(CMR) & uPD98401_CHAN_ADDR))		printk(KERN_CRIT DEV_LABEL "(itf %d): can't close RX channel "		    "%d\n",vcc->dev->number,zatm_vcc->rx_chan);	restore_flags(flags);	zatm_dev->rx_map[zatm_vcc->rx_chan] = NULL;	zatm_vcc->rx_chan = 0;	unuse_pool(vcc->dev,zatm_vcc->pool);}static int start_rx(struct atm_dev *dev){	struct zatm_dev *zatm_dev;	int size,i;DPRINTK("start_rx\n");	zatm_dev = ZATM_DEV(dev);	size = sizeof(struct atm_vcc *)*zatm_dev->chans;	zatm_dev->rx_map = (struct atm_vcc **) kmalloc(size,GFP_KERNEL);	if (!zatm_dev->rx_map) return -ENOMEM;	memset(zatm_dev->rx_map,0,size);	/* set VPI/VCI split (use all VCIs and give what's left to VPIs) */	zpokel(zatm_dev,(1 << dev->ci_range.vci_bits)-1,uPD98401_VRR);	/* prepare free buffer pools */	for (i = 0; i <= ZATM_LAST_POOL; i++) {		zatm_dev->pool_info[i].ref_count = 0;		zatm_dev->pool_info[i].rqa_count = 0;		zatm_dev->pool_info[i].rqu_count = 0;		zatm_dev->pool_info[i].low_water = LOW_MARK;		zatm_dev->pool_info[i].high_water = HIGH_MARK;		zatm_dev->pool_info[i].offset = 0;		zatm_dev->pool_info[i].next_off = 0;		zatm_dev->pool_info[i].next_cnt = 0;		zatm_dev->pool_info[i].next_thres = OFF_CNG_THRES;	}	return 0;}/*----------------------------------- TX ------------------------------------*/static int do_tx(struct sk_buff *skb){	struct atm_vcc *vcc;	struct zatm_dev *zatm_dev;	struct zatm_vcc *zatm_vcc;	u32 *dsc;	unsigned long flags;	EVENT("do_tx\n",0,0);	DPRINTK("sending skb %p\n",skb);	vcc = ATM_SKB(skb)->vcc;	zatm_dev = ZATM_DEV(vcc->dev);	zatm_vcc = ZATM_VCC(vcc);	EVENT("iovcnt=%d\n",ATM_SKB(skb)->iovcnt,0);	save_flags(flags);	cli();	if (!ATM_SKB(skb)->iovcnt) {		if (zatm_vcc->txing == RING_ENTRIES-1) {			restore_flags(flags);			return RING_BUSY;		}		zatm_vcc->txing++;		dsc = zatm_vcc->ring+zatm_vcc->ring_curr;		zatm_vcc->ring_curr = (zatm_vcc->ring_curr+RING_WORDS) &		    (RING_ENTRIES*RING_WORDS-1);		dsc[1] = 0;		dsc[2] = skb->len;		dsc[3] = virt_to_bus(skb->data);		mb();		dsc[0] = uPD98401_TXPD_V | uPD98401_TXPD_DP | uPD98401_TXPD_SM		    | (vcc->qos.aal == ATM_AAL5 ? uPD98401_TXPD_AAL5 : 0 |		    (ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ?		    uPD98401_CLPM_1 : uPD98401_CLPM_0));		EVENT("dsc (0x%lx)\n",(unsigned long) dsc,0);	}	else {printk("NONONONOO!!!!\n");		dsc = NULL;#if 0		u32 *put;		int i;		dsc = (u32 *) kmalloc(uPD98401_TXPD_SIZE*2+		    uPD98401_TXBD_SIZE*ATM_SKB(skb)->iovcnt,GFP_ATOMIC);		if (!dsc) {			if (vcc->pop) vcc->pop(vcc,skb);			else dev_kfree_skb_irq(skb);			return -EAGAIN;		}		/* @@@ should check alignment */		put = dsc+8;		dsc[0] = uPD98401_TXPD_V | uPD98401_TXPD_DP |		    (vcc->aal == ATM_AAL5 ? uPD98401_TXPD_AAL5 : 0 |		    (ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ?		    uPD98401_CLPM_1 : uPD98401_CLPM_0));		dsc[1] = 0;		dsc[2] = ATM_SKB(skb)->iovcnt*uPD98401_TXBD_SIZE;		dsc[3] = virt_to_bus(put);		for (i = 0; i < ATM_SKB(skb)->iovcnt; i++) {			*put++ = ((struct iovec *) skb->data)[i].iov_len;			*put++ = virt_to_bus(((struct iovec *)			    skb->data)[i].iov_base);		}		put[-2] |= uPD98401_TXBD_LAST;#endif	}	ZATM_PRV_DSC(skb) = dsc;	skb_queue_tail(&zatm_vcc->tx_queue,skb);	DPRINTK("QRP=0x%08lx\n",zpeekl(zatm_dev,zatm_vcc->tx_chan*VC_SIZE/4+	  uPD98401_TXVC_QRP));	zwait;	zout(uPD98401_TX_READY | (zatm_vcc->tx_chan <<	    uPD98401_CHAN_ADDR_SHIFT),CMR);	restore_flags(flags);	EVENT("done\n",0,0);	return 0;}static inline void dequeue_tx(struct atm_vcc *vcc){	struct zatm_vcc *zatm_vcc;	struct sk_buff *skb;	EVENT("dequeue_tx\n",0,0);	zatm_vcc = ZATM_VCC(vcc);	skb = skb_dequeue(&zatm_vcc->tx_queue);	if (!skb) {		printk(KERN_CRIT DEV_LABEL "(itf %d): dequeue_tx but not "		    "txing\n",vcc->dev->number);		return;	}#if 0 /* @@@ would fail on CLP */if (*ZATM_PRV_DSC(skb) != (uPD98401_TXPD_V | uPD98401_TXPD_DP |  uPD98401_TXPD_SM | uPD98401_TXPD_AAL5)) printk("@#*$!!!!  (%08x)\n",  *ZATM_PRV_DSC(skb));#endif	*ZATM_PRV_DSC(skb) = 0; /* mark as invalid */	zatm_vcc->txing--;	if (vcc->pop) vcc->pop(vcc,skb);	else dev_kfree_skb_irq(skb);	while ((skb = skb_dequeue(&zatm_vcc->backlog)))		if (do_tx(skb) == RING_BUSY) {			skb_queue_head(&zatm_vcc->backlog,skb);			break;		}	atomic_inc(&vcc->stats->tx);	wake_up(&zatm_vcc->tx_wait);}static void poll_tx(struct atm_dev *dev,int mbx){	struct zatm_dev *zatm_dev;	unsigned long pos;	u32 x;	EVENT("poll_tx\n",0,0);	zatm_dev = ZATM_DEV(dev);	pos = (zatm_dev->mbx_start[mbx] & ~0xffffUL) | zin(MTA(mbx));	while (x = zin(MWA(mbx)), (pos & 0xffff) != x) {		int chan;#if 1

⌨️ 快捷键说明

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