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

📄 dw4002.c

📁 linux下DVB/IP驱动原代码 DVBWorld 公司产品 www.worlddvb.com
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct net_device *dev = pci_get_drvdata (pdev);	struct dm1105_private *np;		assert (dev != NULL);	np = dev->priv;	assert (np != NULL);		unregister_netdev (dev);		__dm1105_cleanup_dev (dev);}void InitSoftwareVariable (struct net_device *dev){	struct dm1105_private *tp = dev->priv;		tp->RxBufDataStart = (unsigned long)tp->RxVirtualSAD;	//tp->NicCurCBA = (unsigned long)tp->RxVirtualSAD;	tp->RxBufDataPtr = tp->RxBufDataStart;	tp->RxBufDataEnd = tp->RxBufDataStart + RX_BUF_SIZE;		tp->bedoing = FALSE;		tp->bFilterPIDFlag = FALSE;	memset (&tp->FilterPID, 0, sizeof (tp->FilterPID));		tp->bDecIPFlag = FALSE;	memset (tp->DecodeIP, 0, sizeof (tp->DecodeIP));		tp->bScanMpePIDFlag = FALSE;	tp->MpePIDNum = 0;///////////////////////	//////////// Kully 01-10-2007	tp->ReceivePacketCount = 0;	tp->RecDataLength = 0;	tp->LostIPTotal = 0;////////////////////////////////////	tp->IPPacketTotalNum = 0;	tp->FramesXmitGood = 0;	tp->FramesRcvGood = 0;	stop_tasklet = 0;	need_reception = 0;	need_reception_count = 0;	local_dev = NULL;	DMARSTFLAG = 0;}int dm1105_open (struct net_device *dev){	struct dm1105_private *tp = dev->priv;	void *ioaddr = tp->base_addr;//Added by Kully 11-3-2006	int retval;		retval = request_irq (dev->irq, dm1105_interrupt, SA_SHIRQ, dev->name, dev); //SA_SHIRQ, Fixed by Kully 10-31-2006		if (retval)	{//		printk("\n Can not register IRQ %d\n", dev->irq);		return retval;	}			tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN, &tp->tx_bufs_dma);	//Send	tp->rx_ring = pci_alloc_consistent(tp->pci_dev, RX_BUF_SIZE, &tp->rx_ring_dma);		//Receive	tp->RxVirtualSAD = tp->rx_ring;		if (tp->tx_bufs == NULL || tp->rx_ring == NULL) 	{		free_irq(dev->irq, dev);				if (tp->tx_bufs)			pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN, tp->tx_bufs, tp->tx_bufs_dma);				if (tp->rx_ring)			pci_free_consistent(tp->pci_dev, RX_BUF_SIZE, tp->rx_ring, tp->rx_ring_dma);//		printk("\n RX Buffer alloc fail.\n");		return -ENOMEM;	}		tp->time_to_die = 0;		dm1105_init_ring( dev );		////////////////////////////// Added by Kully 11-3-2006,Disable DMA and IRQ first!	ANY_W8 (NIC_CR, 0);	//reset device	ANY_W8(NIC_RST,0x01);	ANY_W8 (NIC_INTMAK, 0);	ANY_W8 (NIC_CR, 0);		ANY_W32 (NIC_GPIOCTR, 0xffffffff);	ANY_W32 (NIC_POWER, 0x3ffff);	////////////////////////////////	dm1105_hw_start( dev ); 	//Deleted by Kully 11-3-2006//	InitSoftwareVariable( dev ); 	//Deleted by Kully 11-3-2006	tasklet_schedule (&my_tasklet);//	printk("\n Tasklet init!!!\n");	return 0;}void start_dev(struct net_device *dev){	struct dm1105_private *tp = dev->priv;	void *ioaddr = tp->base_addr;//	printk("\n Start Dev");	ANY_W8 (NIC_INTMAK, INTMAK_ALLMASK);	//	netif_start_queue (dev);	dm1105_hw_start( dev ); 	//Added by Kully 11-3-2006	InitSoftwareVariable (dev);}void sync_stop_dev(struct net_device *dev){	struct dm1105_private *tp = dev->priv;	void *ioaddr = tp->base_addr;//	netif_stop_queue (dev);//	printk("\n Stop Dev!\n");	disable_irq(dev->irq);	//Added by Kully 11-3-2006	ANY_W8 (NIC_INTMAK, 0);		ANY_W8 (NIC_CR, 0);	//Added by Kully 11-3-2006		need_reception = 0;//Added by Kully 11-3-2006	need_reception_count =0;//Added by Kully 11-3-2006	local_dev = NULL;//Added by Kully 11-3-2006	enable_irq(dev->irq);	//Added by Kully 11-3-2006}// Start the hardware at open or resume. void dm1105_hw_start (struct net_device *dev){	struct dm1105_private *tp = dev->priv;	void *ioaddr = tp->base_addr;		//u8 tmp;		assert (dev != NULL);	assert (tp != NULL);	assert (ioaddr != NULL);			//stop DMA	ANY_W8 (NIC_CR, 0);		//reset device	ANY_W8(NIC_RST,0x01);		//NIC_DATALEN	ANY_W8(NIC_DATALEN, 0xBC);		ANY_W16(NIC_TSCTR, 0xc12a);			ANY_W32 (NIC_GPIOCTR, 0xfffcffff);	ANY_W32 (NIC_POWER, 0x1ffff);	//LNB ON-13V by default!		//init Rx ring buffer DMA address	ANY_W32 (NIC_STADR, tp->rx_ring_dma);	ANY_W32 (NIC_RLEN, RX_BUF_SIZE );	ANY_W8 (NIC_INTCNT, 47);		// Enable all known interrupts and DMA	ANY_W8 (NIC_INTMAK, INTMAK_ALLMASK);	ANY_W8 (NIC_CR, 0x01);		//NdisRawWritePortUlong(Adapter->IoAddr+NIC_GPIOCTR, 0xfffffffe);  // 0: Out -- Tuner lock LED 	//NdisRawWritePortUlong(Adapter->IoAddr+NIC_GPIOVAL, 0x3ffff);     // Disable Lock LED	//	dm1105_set_rx_mode (dev);//Deleted by Kully for China Standard Linux OS 12112006//	netif_start_queue (dev);//Deleted by Kully for China Standard Linux OS 12112006}/* Initialize the Rx and Tx rings, along with various 'dev' bits. */void dm1105_init_ring (struct net_device *dev){	struct dm1105_private *tp = dev->priv;	int i;		tp->cur_rx = 0;	tp->cur_tx = 0;	tp->dirty_tx = 0;		for (i = 0; i < NUM_TX_DESC; i++)	//NUM_TX_DESC == 4		tp->tx_buf[i] = &tp->tx_bufs[i * TX_BUF_SIZE];}void dm1105_tx_clear (struct dm1105_private *tp){	tp->cur_tx = 0;	tp->dirty_tx = 0;		/* XXX account for unsent Tx packets in tp->stats.tx_dropped */}void dm1105_tx_timeout (struct net_device *dev)	//Fixed by Kully 11-3-2006, this function has been disabled!{//	struct dm1105_private *tp = dev->priv;//	void *ioaddr = tp->base_addr;//	unsigned long flags;//	static unsigned int TimeOutCount = 0;//	tp->xstats.tx_timeouts++;//	netif_stop_queue (dev);//	TimeOutCount ++;//	printk("\n DW4002 TX Time out  ----------  %d\n",TimeOutCount);/*	ANY_W8 (NIC_INTMAK, 0);//	printk("\n DW4002 TX Time out!");	//Stop a shared interrupt from scavenging while we are. 	spin_lock_irqsave (&tp->lock, flags);	dm1105_tx_clear (tp);	spin_unlock_irqrestore (&tp->lock, flags);		//...and finally, reset everything	dm1105_hw_start (dev);		netif_wake_queue (dev);*/}int dm1105_start_xmit (struct sk_buff *skb, struct net_device *dev){	struct dm1105_private *tp = dev->priv;	unsigned int len = skb->len;	unsigned short proto;	unsigned char packet[TX_BUF_SIZE];		if (likely(len < TX_BUF_SIZE)) 	{		struct sk_buff *skbb;				memcpy (packet, skb->data, len);		dev_kfree_skb(skb);				////////////////////////////////////// Kully 10-31-2006, disable to send any thing to the dummy hardware!		skbb = NULL;////////dev_alloc_skb (len + 2);//		printk ("\n DW4002 TX one time!\n");//		netif_stop_queue (dev);		//////////////////////////////////////		if (skbb) 		{			//exchange source and dest			unsigned char tmpbuf[10];			proto = (packet[12] << 8) | packet[13];			if (proto == 0x0806) 			{  // ARP				const unsigned char MAC[6] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};				if (packet[21] == 0x01 || packet[22] == 0x03) // request					packet[21] += 1;				else 				{					dev_kfree_skb(skbb);					tp->stats.tx_dropped++;					return 0;				}								memcpy (packet, packet+6, 6);  // MAC address				memcpy (packet+6, MAC, 6);								memcpy (tmpbuf, packet+22, 10);  // source -> tmp				memcpy (packet+22, packet+32, 10);  // dest -> source				memcpy (packet+32, tmpbuf, 10);  // tmp -> dest				memcpy (packet+22, MAC, 6);			} 			else 			{				if (packet[23] != 0x01 || packet[34] != 0x08)  // not ICMP requestion packet				{					dev_kfree_skb (skbb);										tp->stats.tx_dropped++;					return 0;				}								// ICMP request ack(for ping)				// exchange source address and dest address				packet[34] = 0x00;  // ack				memcpy (tmpbuf, packet, 6);  // MAC address				memcpy (packet, packet+6, 6);  // MAC address				memcpy (packet+6, tmpbuf, 6);				memcpy (tmpbuf, packet+26, 4);  // IP address				memcpy (packet+26, packet+30, 4);  // IP address				memcpy (packet+30, tmpbuf, 4);			}						skbb->dev = dev;			skb_reserve (skbb, 2);	/* 16 byte align the IP fields. */						eth_copy_and_sum (skbb, packet, len, 0);			skb_put (skbb, len);						skb->protocol = eth_type_trans (skbb, dev);						netif_rx (skbb);			dev->last_rx = jiffies;			tp->stats.tx_bytes += len;			tp->stats.tx_packets++;		} 		else 		{//			printk (KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);			tp->stats.rx_dropped++;		}	} 	else 	{		dev_kfree_skb(skb);		tp->stats.tx_dropped++;		return 0;	}		return 0;}void dm1105_tx_interrupt (struct net_device *dev){	struct dm1105_private *tp = dev->priv;	void *ioaddr = tp->base_addr;		assert (dev != NULL);	assert (tp != NULL);	assert (ioaddr != NULL);		// do nothing, none to send}BOOL PacketOK (struct net_device *dev){	struct dm1105_private *tp = dev->priv;	unsigned char* pBuf = (unsigned char*)tp->RxBufDataPtr;		if ((tp->RxBufDataPtr + DM1105_IRQ_DATA_LENGTH) > tp->RxBufDataEnd)	{		//	printk ("ERROR: There is a memory MOVE\n");		memmove((unsigned char*)tp->RxBufDataEnd, (unsigned char*)tp->RxBufDataStart, DM1105_IRQ_DATA_LENGTH - (tp->RxBufDataEnd-tp->RxBufDataPtr));	}		if ((pBuf[0] == 0x47 ) && (pBuf[188]== 0x47 ) && (pBuf[188*2] == 0x47)) 	{		return TRUE;	}		return FALSE;}  // end of PacketOK (struct net_device *dev)BOOL CheckSum (unsigned char* buf, int length){	int i;	unsigned int check_sum = 0;	unsigned short *ptr;	ptr = (unsigned short *) buf;		for (i = length; i > 1; ) 	{		check_sum += *ptr++;		i -= sizeof (unsigned short);	}		if (i == 1)		check_sum += *(unsigned char*) ptr;		check_sum = (check_sum >> 16) + (check_sum & 0xffff);	check_sum = (unsigned short)~check_sum;		if (check_sum == 0)		return TRUE;	else		return FALSE;}void TxIpPacket (struct net_device *dev, PDECODE_IP pDecIP){	struct dm1105_private *tp = dev->priv;	struct sk_buff *skb;	int pkt_size = pDecIP->IPPacketLen + 14;  // MAC head		skb = dev_alloc_skb (pkt_size + 2);	if (skb) 	{		skb->dev = dev;		skb_reserve (skb, 2);	// 16 byte align the IP fields.				//eth_copy_and_sum (skb, pDecIP->IPBuf, pDecIP->IPPacketLen, 0);		memcpy (skb->data, pDecIP->MACHead, 14);		memcpy (skb->data+14, pDecIP->IPBuf, pDecIP->IPPacketLen);		skb_put (skb, pkt_size);				skb->protocol = eth_type_trans (skb, dev);		netif_rx (skb);		dev->last_rx = jiffies;		tp->stats.rx_bytes += pkt_size;		tp->stats.rx_packets++;				tp->RecDataLength += pDecIP->IPPacketLen;				//----------------- added by Hong Fei --------------------		pDecIP->IPTotalLen += pDecIP->IPPacketLen;		tp->IPPacketTotalNum++;			} 	else 	{//		printk (KERN_WARNING//			"%s: Memory squeeze, dropping packet.\n",dev->name);		tp->stats.rx_dropped++;	}		pDecIP->TotalSectionLen = 0;	pDecIP->CurSectionLen = 0;	pDecIP->SectionDone = 1;}void DecodeIP (struct net_device *dev, unsigned char* TsBuf){	struct dm1105_private *tp = dev->priv;	PTS_PACKET_HEAD pTsHead = (PTS_PACKET_HEAD) TsBuf;	unsigned short wPID;	PDECODE_IP pDecIP;	int i;		wPID = (pTsHead->pid1 << 8) | pTsHead->pid2;}#define SCANMPETIME    3000	//Fiexed by Kully 11-3-2006, the old definition data is 800 void ScanMpePID (struct net_device *dev, unsigned char* TsBuf){	struct dm1105_private *tp = dev->priv;	PTS_PACKET_HEAD pTsHead = (PTS_PACKET_HEAD) TsBuf;	int i;	unsigned char pointer_field;	unsigned short wPID;	unsigned char* bufptr;		if (jiffies > tp->ScanTime) 	{		tp->bScanMpePIDFlag = FALSE;//		printk("\n IP PID Scanning time out! ");		return;	}		if (pTsHead->start_indicator) 	{		PMPE_SECTION_HEAD pMpeHead;		PIP_HEAD pIPHead;		PUDP_HEAD pUdpHead;		wPID = (pTsHead->pid1 << 8) | pTsHead->pid2;		bufptr = TsBuf + sizeof(PTS_PACKET_HEAD);		pointer_field = *bufptr++;		bufptr += pointer_field;				pMpeHead = (PMPE_SECTION_HEAD) bufptr;				if (pMpeHead->table_id != 0x3e)			return;				if (pMpeHead->LLC_SNAP_flag)			return;				bufptr += sizeof (MPE_SECTION_HEAD);		pIPHead = (PIP_HEAD) bufptr;				if (pIPHead->protocol != IPPROTO_UDP || pIPHead->version != 4 || 			pIPHead->slice_offset1 != 0 || pIPHead->slice_offset2 != 0)  // not the first part			return;				for (i = 0; i < tp->MpePIDNum; i++) 		{			if (tp->MpePID[i].wPID == wPID)  // found				break;		}				if (i >= tp->MpePIDNum) 		{ 			// keep it			bufptr += sizeof (IP_HEAD);			pUdpHead = (PUDP_HEAD) bufptr;						tp->MpePID[tp->MpePIDNum].wPID = wPID;			tp->MpePID[tp->MpePIDNum].MAC_address[0] = pMpeHead->MAC_address1;			tp->MpePID[tp->MpePIDNum].MAC_address[1] = pMpeHead->MAC_address2;			tp->MpePID[tp->MpePIDNum].MAC_address[2] = pMpeHead->MAC_address3;			tp->MpePID[tp->MpePIDNum].MAC_address[3] = pMpeHead->MAC_address4;			tp->MpePID[tp->MpePIDNum].MAC_address[4] = pMpeHead->MAC_address5;			tp->MpePID[tp->MpePIDNum].MAC_address[5] = pMpeHead->MAC_address6;						tp->MpePID[tp->MpePIDNum].IP_address[0] = pIPHead->destIP1;			tp->MpePID[tp->MpePIDNum].IP_address[1] = pIPHead->destIP2;			tp->MpePID[tp->MpePIDNum].IP_address[2] = pIPHead->destIP3;			tp->MpePID[tp->MpePIDNum].IP_address[3] = pIPHead->destIP4;						tp->MpePID[tp->MpePIDNum].wPort = (pUdpHead->dest_port[0] << 8) | pUdpHead->dest_port[1];						if (++tp->MpePIDNum > MaxMpePID) 			{  // too many pid, stop scan				tp->bScanMpePIDFlag = FALSE;//				printk("\n IP PID Scanning, too many pids! ");			}		}	}}void FilterPacket (struct net_device *dev, unsigned char* TsBuf){	struct dm1105_private *tp = dev->priv;	PTS_PACKET_HEAD pTsHead = (PTS_PACKET_HEAD) TsBuf;	int i, j;	unsigned short wPID;		wPID = (pTsHead->pid1 << 8) | pTsHead->pid2;		for (i = 0; i < MaxIRPQueue; i++) 	{		if (tp->FilterPID[i].status == FILTERPID_RUN) 		{  // if run filter						for (j = 0; j < tp->FilterPID[i].pid_num; j++) 			{				if (wPID == tp->FilterPID[i].wPID[j]) 				{					if (tp->FilterPID[i].mode == 1) 					{  // pass this PID packets						if (tp->FilterPID[i].bmove_flag) 						{							memcpy (tp->FilterPID[i].PacketBuf, 								tp->FilterPID[i].PacketBuf + 188 * tp->FilterPID[i].move_num,								(tp->FilterPID[i].packet_num - tp->FilterPID[i].move_num) * 188);							tp->FilterPID[i].packet_num -= tp->FilterPID[i].move_num;							tp->FilterPID[i].bmove_flag = FALSE;						}												if (tp->FilterPID[i].packet_num >= FILTERPID_PACKNUM) 						{							tp->FilterPID[i].lost_num++;						}

⌨️ 快捷键说明

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