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

📄 idt77252.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
			         "(CDC: %08x)\n",			         card->name, len, rpp->len, readl(SAR_REG_CDC));			recycle_rx_pool_skb(card, rpp);			atomic_inc(&vcc->stats->rx_err);			return;		}		if (stat & SAR_RSQE_CRC) {			RXPRINTK("%s: AAL5 CRC error.\n", card->name);			recycle_rx_pool_skb(card, rpp);			atomic_inc(&vcc->stats->rx_err);			return;		}		if (rpp->count > 1) {			struct sk_buff *sb;			skb = dev_alloc_skb(rpp->len);			if (!skb) {				RXPRINTK("%s: Can't alloc RX skb.\n",					 card->name);				recycle_rx_pool_skb(card, rpp);				atomic_inc(&vcc->stats->rx_err);				return;			}			if (!atm_charge(vcc, skb->truesize)) {				recycle_rx_pool_skb(card, rpp);				dev_kfree_skb(skb);				return;			}			sb = rpp->first;			for (i = 0; i < rpp->count; i++) {				memcpy(skb_put(skb, sb->len),				       sb->data, sb->len);				sb = sb->next;			}			recycle_rx_pool_skb(card, rpp);			skb_trim(skb, len);			ATM_SKB(skb)->vcc = vcc;			skb->stamp = xtime;			vcc->push(vcc, skb);			atomic_inc(&vcc->stats->rx);			return;		}		skb->next = NULL;		flush_rx_pool(card, rpp);		if (!atm_charge(vcc, skb->truesize)) {			recycle_rx_skb(card, skb);			return;		}		pci_unmap_single(card->pcidev, IDT77252_PRV_PADDR(skb),				 skb->end - skb->data, PCI_DMA_FROMDEVICE);		sb_pool_remove(card, skb);		skb_trim(skb, len);		ATM_SKB(skb)->vcc = vcc;		skb->stamp = xtime;		vcc->push(vcc, skb);		atomic_inc(&vcc->stats->rx);		if (skb->truesize > SAR_FB_SIZE_3)			add_rx_skb(card, 3, SAR_FB_SIZE_3, 1);		else if (skb->truesize > SAR_FB_SIZE_2)			add_rx_skb(card, 2, SAR_FB_SIZE_2, 1);		else if (skb->truesize > SAR_FB_SIZE_1)			add_rx_skb(card, 1, SAR_FB_SIZE_1, 1);		else			add_rx_skb(card, 0, SAR_FB_SIZE_0, 1);		return;	}}static voididt77252_rx(struct idt77252_dev *card){	struct rsq_entry *rsqe;	if (card->rsq.next == card->rsq.last)		rsqe = card->rsq.base;	else		rsqe = card->rsq.next + 1;	if (!(le32_to_cpu(rsqe->word_4) & SAR_RSQE_VALID)) {		RXPRINTK("%s: no entry in RSQ.\n", card->name);		return;	}	do {		dequeue_rx(card, rsqe);		rsqe->word_4 = 0;		card->rsq.next = rsqe;		if (card->rsq.next == card->rsq.last)			rsqe = card->rsq.base;		else			rsqe = card->rsq.next + 1;	} while (le32_to_cpu(rsqe->word_4) & SAR_RSQE_VALID);	writel((unsigned long) card->rsq.next - (unsigned long) card->rsq.base,	       SAR_REG_RSQH);}static voididt77252_rx_raw(struct idt77252_dev *card){	struct sk_buff	*queue;	u32		head, tail;	struct atm_vcc	*vcc;	struct vc_map	*vc;	struct sk_buff	*sb;	if (card->raw_cell_head == NULL) {		u32 handle = le32_to_cpu(*(card->raw_cell_hnd + 1));		card->raw_cell_head = sb_pool_skb(card, handle);	}	queue = card->raw_cell_head;	if (!queue)		return;	head = IDT77252_PRV_PADDR(queue) + (queue->data - queue->head - 16);	tail = readl(SAR_REG_RAWCT);	pci_dma_sync_single(card->pcidev, IDT77252_PRV_PADDR(queue),			    queue->end - queue->head - 16, PCI_DMA_FROMDEVICE);	while (head != tail) {		unsigned int vpi, vci, pti;		u32 header;		header = le32_to_cpu(*(u32 *) &queue->data[0]);		vpi = (header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;		vci = (header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;		pti = (header & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT;#ifdef CONFIG_ATM_IDT77252_DEBUG		if (debug & DBG_RAW_CELL) {			int i;			printk("%s: raw cell %x.%02x.%04x.%x.%x\n",			       card->name, (header >> 28) & 0x000f,			       (header >> 20) & 0x00ff,			       (header >>  4) & 0xffff,			       (header >>  1) & 0x0007,			       (header >>  0) & 0x0001);			for (i = 16; i < 64; i++)				printk(" %02x", queue->data[i]);			printk("\n");		}#endif		if (vpi >= (1<<card->vpibits) || vci >= (1<<card->vcibits)) {			RPRINTK("%s: SDU received for out-of-range vc %u.%u\n",				card->name, vpi, vci);			goto drop;		}		vc = card->vcs[VPCI2VC(card, vpi, vci)];		if (!vc || !test_bit(VCF_RX, &vc->flags)) {			RPRINTK("%s: SDU received on non RX vc %u.%u\n",				card->name, vpi, vci);			goto drop;		}		vcc = vc->rx_vcc;		if (vcc->qos.aal != ATM_AAL0) {			RPRINTK("%s: raw cell for non AAL0 vc %u.%u\n",				card->name, vpi, vci);			atomic_inc(&vcc->stats->rx_drop);			goto drop;		}			if ((sb = dev_alloc_skb(64)) == NULL) {			printk("%s: Can't allocate buffers for AAL0.\n",			       card->name);			atomic_inc(&vcc->stats->rx_err);			goto drop;		}		if ((vcc->sk != NULL) && !atm_charge(vcc, sb->truesize)) {			RXPRINTK("%s: atm_charge() dropped AAL0 packets.\n",				 card->name);			dev_kfree_skb(sb);			goto drop;		}		*((u32 *) sb->data) = header;		skb_put(sb, sizeof(u32));		memcpy(skb_put(sb, ATM_CELL_PAYLOAD), &(queue->data[16]),		       ATM_CELL_PAYLOAD);		ATM_SKB(sb)->vcc = vcc;		sb->stamp = xtime;		vcc->push(vcc, sb);		atomic_inc(&vcc->stats->rx);drop:		skb_pull(queue, 64);		head = IDT77252_PRV_PADDR(queue)					+ (queue->data - queue->head - 16);		if (queue->len < 128) {			struct sk_buff *next;			u32 handle;			head = le32_to_cpu(*(u32 *) &queue->data[0]);			handle = le32_to_cpu(*(u32 *) &queue->data[4]);			next = sb_pool_skb(card, handle);			recycle_rx_skb(card, queue);			if (next) {				card->raw_cell_head = next;				queue = card->raw_cell_head;				pci_dma_sync_single(card->pcidev,						    IDT77252_PRV_PADDR(queue),						    queue->end - queue->data,						    PCI_DMA_FROMDEVICE);			} else {				card->raw_cell_head = NULL;				printk("%s: raw cell queue overrun\n",				       card->name);				break;			}		}	}}/*****************************************************************************//*                                                                           *//* TSQ Handling                                                              *//*                                                                           *//*****************************************************************************/static intinit_tsq(struct idt77252_dev *card){	struct tsq_entry *tsqe;	card->tsq.base = pci_alloc_consistent(card->pcidev, RSQSIZE,					      &card->tsq.paddr);	if (card->tsq.base == NULL) {		printk("%s: can't allocate TSQ.\n", card->name);		return -1;	}	memset(card->tsq.base, 0, TSQSIZE);	card->tsq.last = card->tsq.base + TSQ_NUM_ENTRIES - 1;	card->tsq.next = card->tsq.last;	for (tsqe = card->tsq.base; tsqe <= card->tsq.last; tsqe++)		tsqe->word_2 = cpu_to_le32(SAR_TSQE_INVALID);	writel(card->tsq.paddr, SAR_REG_TSQB);	writel((unsigned long) card->tsq.next - (unsigned long) card->tsq.base,	       SAR_REG_TSQH);	return 0;}static voiddeinit_tsq(struct idt77252_dev *card){	pci_free_consistent(card->pcidev, TSQSIZE,			    card->tsq.base, card->tsq.paddr);}static voididt77252_tx(struct idt77252_dev *card){	struct tsq_entry *tsqe;	unsigned int vpi, vci;	struct vc_map *vc;	u32 conn, stat;	if (card->tsq.next == card->tsq.last)		tsqe = card->tsq.base;	else		tsqe = card->tsq.next + 1;	TXPRINTK("idt77252_tx: tsq  %p: base %p, next %p, last %p\n", tsqe,		 card->tsq.base, card->tsq.next, card->tsq.last);	TXPRINTK("idt77252_tx: tsqb %08x, tsqt %08x, tsqh %08x, \n",		 readl(SAR_REG_TSQB),		 readl(SAR_REG_TSQT),		 readl(SAR_REG_TSQH));	stat = le32_to_cpu(tsqe->word_2);	if (stat & SAR_TSQE_INVALID)		return;	do {		TXPRINTK("tsqe: 0x%p [0x%08x 0x%08x]\n", tsqe,			 le32_to_cpu(tsqe->word_1),			 le32_to_cpu(tsqe->word_2));		switch (stat & SAR_TSQE_TYPE) {		case SAR_TSQE_TYPE_TIMER:			TXPRINTK("%s: Timer RollOver detected.\n", card->name);			break;		case SAR_TSQE_TYPE_IDLE:			conn = le32_to_cpu(tsqe->word_1);			if (SAR_TSQE_TAG(stat) == 0x10) {#ifdef	NOTDEF				printk("%s: Connection %d halted.\n",				       card->name,				       le32_to_cpu(tsqe->word_1) & 0x1fff);#endif				break;			}			vc = card->vcs[conn & 0x1fff];			if (!vc) {				printk("%s: could not find VC from conn %d\n",				       card->name, conn & 0x1fff);				break;			}			printk("%s: Connection %d IDLE.\n",			       card->name, vc->index);			set_bit(VCF_IDLE, &vc->flags);			break;		case SAR_TSQE_TYPE_TSR:			conn = le32_to_cpu(tsqe->word_1);			vc = card->vcs[conn & 0x1fff];			if (!vc) {				printk("%s: no VC at index %d\n",				       card->name,				       le32_to_cpu(tsqe->word_1) & 0x1fff);				break;			}			drain_scq(card, vc);			break;		case SAR_TSQE_TYPE_TBD_COMP:			conn = le32_to_cpu(tsqe->word_1);			vpi = (conn >> SAR_TBD_VPI_SHIFT) & 0x00ff;			vci = (conn >> SAR_TBD_VCI_SHIFT) & 0xffff;			if (vpi >= (1 << card->vpibits) ||			    vci >= (1 << card->vcibits)) {				printk("%s: TBD complete: "				       "out of range VPI.VCI %u.%u\n",				       card->name, vpi, vci);				break;			}			vc = card->vcs[VPCI2VC(card, vpi, vci)];			if (!vc) {				printk("%s: TBD complete: "				       "no VC at VPI.VCI %u.%u\n",				       card->name, vpi, vci);				break;			}			drain_scq(card, vc);			break;		}		tsqe->word_2 = cpu_to_le32(SAR_TSQE_INVALID);		card->tsq.next = tsqe;		if (card->tsq.next == card->tsq.last)			tsqe = card->tsq.base;		else			tsqe = card->tsq.next + 1;		TXPRINTK("tsqe: %p: base %p, next %p, last %p\n", tsqe,			 card->tsq.base, card->tsq.next, card->tsq.last);		stat = le32_to_cpu(tsqe->word_2);	} while (!(stat & SAR_TSQE_INVALID));	writel((unsigned long)card->tsq.next - (unsigned long)card->tsq.base,	       SAR_REG_TSQH);	XPRINTK("idt77252_tx-after writel%d: TSQ head = 0x%x, tail = 0x%x, next = 0x%p.\n",		card->index, readl(SAR_REG_TSQH),		readl(SAR_REG_TSQT), card->tsq.next);}static voidtst_timer(unsigned long data){	struct idt77252_dev *card = (struct idt77252_dev *)data;	unsigned long base, idle, jump;	unsigned long flags;	u32 pc;	int e;	spin_lock_irqsave(&card->tst_lock, flags);	base = card->tst[card->tst_index];	idle = card->tst[card->tst_index ^ 1];	if (test_bit(TST_SWITCH_WAIT, &card->tst_state)) {		jump = base + card->tst_size - 2;		pc = readl(SAR_REG_NOW) >> 2;		if ((pc ^ idle) & ~(card->tst_size - 1)) {			mod_timer(&card->tst_timer, jiffies + 1);			goto out;		}		clear_bit(TST_SWITCH_WAIT, &card->tst_state);		card->tst_index ^= 1;		write_sram(card, jump, TSTE_OPC_JMP | (base << 2));		base = card->tst[card->tst_index];		idle = card->tst[card->tst_index ^ 1];		for (e = 0; e < card->tst_size - 2; e++) {			if (card->soft_tst[e].tste & TSTE_PUSH_IDLE) {				write_sram(card, idle + e,					   card->soft_tst[e].tste & TSTE_MASK);				card->soft_tst[e].tste &= ~(TSTE_PUSH_IDLE);			}		}	}	if (test_and_clear_bit(TST_SWITCH_PENDING, &card->tst_state)) {		for (e = 0; e < card->tst_size - 2; e++) {			if (card->soft_tst[e].tste & TSTE_PUSH_ACTIVE) {				write_sram(card, idle + e,					   card->soft_tst[e].tste & TSTE_MASK);				card->soft_tst[e].tste &= ~(TSTE_PUSH_ACTIVE);				card->soft_tst[e].tste |= TSTE_PUSH_IDLE;			}		}		jump = base + card->tst_size - 2;		write_sram(card, jump, TSTE_OPC_NULL);		set_bit(TST_SWITCH_WAIT, &card->tst_state);		mod_timer(&card->tst_timer, jiffies + 1);	}out:	spin_unlock_irqrestore(&card->tst_lock, flags);}static int__fill_tst(struct idt77252_dev *card, struct vc_map *vc,	   int n, unsigned int opc){	unsigned long cl, avail;	unsigned long idle;	int e, r;	u32 data;	avail = card->tst_size - 2;	for (e = 0; e < avail; e++) {		if (card->soft_tst[e].vc == NULL)			break;	}	if (e >= avail) {		printk("%s: No free TST entries found\n", card->name);		return -1;	}	NPRINTK("%s: conn %d: first TST entry at %d.\n",		card->name, vc ? vc->index : -1, e);	r = n;	cl = avail;	data = opc & TSTE_OPC_MASK;	if (vc && (opc != TSTE_OPC_NULL))		data = opc | vc->index;	idle = card->tst[card->tst_index ^ 1];	/*	 * Fill Soft TST.	 */	while (r > 0) {		if ((cl >= avail) && (card->soft_tst[e].vc == NULL)) {			if (vc)				card->soft_tst[e].vc = vc;			else				card->soft_tst[e].vc = (void *)-1;			card->soft_tst[e].tste = data;			if (timer_pending(&card->tst_timer))				card->soft_tst[e].tste |= TSTE_PUSH_ACTIVE;			else {				write_sram(card, idle + e, data);				card->soft_tst[e].tste |= TSTE_PUSH_IDLE;			}			cl -= card->tst_size;			r--;		}		if (++e == avail)			e = 0;		cl += n;	}	return 0;}static intfill_tst(struct idt77252_dev *card, struct vc_map *vc, int n, unsigned int opc){	unsigned long flags;	int res;	spin_lock_irqsave(&card->tst_lock, flags);	res = __fill_tst(card, vc, n, opc);	set_bit(TST_SWITCH_PENDING, &card->tst_state);	if (!timer_pending(&card->tst_timer))		mod_timer(&card->tst_timer, jiffies + 1);	spin_unlock_irqrestore(&card->tst_lock, flags);	return res;}static int__clear_tst(struct idt77252_dev *card, struct vc_map *vc){	unsigned long idle;	int e;	idle = card->tst[card->tst_index ^ 1];	for (e = 0; e < card->tst_size - 2; e++) {		if (card->soft_tst[e].vc == vc) {			card->soft_tst[e].vc = NULL;			card->soft_tst[e].tste = TSTE_OPC_VAR;			if (timer_pending(&card->tst_timer))				card->soft_tst[e].tste |= TSTE_PUSH_ACTIVE;			else {				write_sram(card, idle + e, TSTE_OPC_VAR);				card->soft_tst[e].tste |= TSTE_PUSH_IDLE;			}		}	}	return 0;}static intclear_tst(struct idt77252_dev *card, struct vc_map *vc)

⌨️ 快捷键说明

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