?? dw4002.c
字號(hào):
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++; }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -