📄 velocity_main.c
字号:
if (!(pInfo->hw.mii_status & VELOCITY_LINK_FAIL)) netif_wake_queue(dev); break; case VELOCITY_INIT_COLD: default: mac_eeprom_reload(&pInfo->hw); // write dev->dev_addr to MAC address field for MAC address override for (i = 0; i < 6; i++) CSR_WRITE_1(&pInfo->hw, dev->dev_addr[i], MAC_REG_PAR+i); // clear Pre_ACPI bit. BYTE_REG_BITS_OFF(&pInfo->hw, CFGA_PACPI, MAC_REG_CFGA); // set packet filter // receive directed and broadcast address velocity_set_multi(dev); netif_stop_queue(dev); velocity_init_register_cold(&pInfo->hw); if (!(pInfo->hw.mii_status & VELOCITY_LINK_FAIL)) netif_wake_queue(dev); break; } // switch (InitType)}static voidvelocity_init_pci(PVELOCITY_INFO pInfo) { // turn this on to avoid retry forever PCI_BYTE_REG_BITS_ON(MODE2_PCEROPT, PCI_REG_MODE2, pInfo->pcid); // for some legacy BIOS and OS don't open BusM // bit in PCI configuration space. So, turn it on. PCI_BYTE_REG_BITS_ON(COMMAND_BUSM, PCI_REG_COMMAND, pInfo->pcid); // turn this on to detect MII coding error PCI_BYTE_REG_BITS_ON(MODE3_MIION, PCI_REG_MODE3, pInfo->pcid);}static intvelocity_found1( struct pci_dev *pcid, const struct pci_device_id *ent ){ static BOOL bFirst = TRUE; struct net_device* dev = NULL; int i, rc; PCHIP_INFO pChip_info = (PCHIP_INFO)ent->driver_data; PVELOCITY_INFO pInfo, p; long ioaddr, memaddr; PU8 hw_addr; if (velocity_nics++ >= MAX_UINTS) { printk(KERN_NOTICE VELOCITY_NAME ": already found %d NICs\n", velocity_nics); return -ENODEV; } rc = pci_enable_device(pcid); if (rc) goto err_out; rc = pci_set_dma_mask(pcid, 0xffffffffL); if (rc) { printk(KERN_ERR VELOCITY_NAME "PCI DMA not supported!\n"); goto err_out; } ioaddr = pci_resource_start(pcid, 0); memaddr = pci_resource_start(pcid, 1); pci_set_master(pcid);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) dev = alloc_etherdev(sizeof(VELOCITY_INFO));#else dev = init_etherdev(NULL, sizeof(VELOCITY_INFO));#endif if (dev == NULL) { rc = -ENOMEM; printk(KERN_ERR VELOCITY_NAME ": allocate net device failed!\n"); goto err_out; }#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) /* Chain it all together */ SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pcid->dev);#endif pInfo = netdev_priv(dev); if (bFirst) { printk(KERN_INFO "%s Ver. %s\n",VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION); printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n"); bFirst=FALSE; } // init pVelocity3_Infos information if (pVelocity3_Infos == NULL) { pVelocity3_Infos = pInfo; } else { for (p=pVelocity3_Infos; p->next!=NULL; p=p->next) do {} while (0); p->next = pInfo; pInfo->prev = p; } // init pInfo information pci_read_config_word(pcid, PCI_SUBSYSTEM_ID, &pInfo->hw.SubSystemID); pci_read_config_word(pcid, PCI_SUBSYSTEM_VENDOR_ID, &pInfo->hw.SubVendorID); pci_read_config_byte(pcid, PCI_REVISION_ID, &pInfo->hw.byRevId); pInfo->chip_id = pChip_info->chip_id; pInfo->hw.nTxQueues = 1; pInfo->hw.multicast_limit = MCAM_SIZE; pInfo->pcid = pcid; spin_lock_init(&(pInfo->lock)); spin_lock_init(&(pInfo->xmit_lock)); /* init velocity_hw */ pInfo->hw.io_size = 256; pInfo->hw.ioaddr = ioaddr; pInfo->hw.memaddr = memaddr;#ifdef CONFIG_PROC_FS velocity_init_proc_fs(pInfo);#endif /* assign message level */ pInfo->hw.msglevel = msglevel; pInfo->dev = dev; pInfo->osdep.dev = dev; pInfo->hw.back = &pInfo->osdep;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) rc = pci_request_regions(pcid, VELOCITY_NAME); if (rc) { printk(KERN_ERR VELOCITY_NAME ": Failed to find PCI device\n"); goto err_out_free_dev; }#else if (check_region(pInfo->hw.ioaddr, pInfo->hw.io_size)) { printk(KERN_ERR VELOCITY_NAME ": Failed to find PCI device\n"); goto err_out_free_dev; } request_region(pInfo->hw.ioaddr, pInfo->hw.io_size, VELOCITY_NAME);#endif hw_addr = ioremap(pInfo->hw.memaddr & PCI_BASE_ADDRESS_MEM_MASK, pInfo->hw.io_size); if (!hw_addr) { rc = -EIO; printk(KERN_ERR VELOCITY_NAME ": ioremap failed for region 0x%lx\n", pInfo->hw.memaddr); goto err_out_free_res; } pInfo->hw.hw_addr = hw_addr; velocity_create_proc_entry(pInfo); mac_wol_reset(&pInfo->hw); // get MII PHY Id velocity_mii_read(&pInfo->hw, MII_REG_PHYID2, (PU16)&pInfo->hw.dwPHYId); velocity_mii_read(&pInfo->hw, MII_REG_PHYID1, ((PU16)&pInfo->hw.dwPHYId)+1); // software reset velocity_soft_reset(&pInfo->hw); mdelay(5); // EEPROM reload mac_eeprom_reload(&pInfo->hw); // set net_device related stuffs dev->base_addr = pInfo->hw.ioaddr; for (i=0; i<6; i++) dev->dev_addr[i] = CSR_READ_1(&pInfo->hw, MAC_REG_PAR+i); dev->irq = pcid->irq; dev->open = velocity_open; dev->hard_start_xmit = velocity_xmit; dev->stop = velocity_close; dev->get_stats = velocity_get_stats; dev->set_multicast_list = velocity_set_multi; dev->do_ioctl = velocity_ioctl; dev->change_mtu = velocity_change_mtu; velocity_get_options(&pInfo->hw.sOpts, velocity_nics-1); // Mask out the options cannot be set to the chip pInfo->hw.sOpts.flags &= pChip_info->flags; // Enable the chip specified capbilities pInfo->hw.flags = pInfo->hw.sOpts.flags | (pChip_info->flags & 0xFF000000L); pInfo->wol_opts = pInfo->hw.sOpts.wol_opts; pInfo->hw.flags |= VELOCITY_FLAGS_WOL_ENABLED;#ifdef VELOCITY_TX_CSUM_SUPPORT if (pInfo->hw.flags & VELOCITY_FLAGS_TX_CSUM) { dev->features |= NETIF_F_HW_CSUM;#ifdef VELOCITY_ZERO_COPY_SUPPORT // Checksum function must be enabled, or SG will be dropped dev->features |= NETIF_F_SG;#endif }#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) rc = register_netdev(dev); if (rc) { printk(KERN_ERR VELOCITY_NAME ": Failed to register netdev\n"); goto err_out_unmap; }#endif velocity_print_info(pInfo); pci_set_drvdata(pcid, pInfo); return 0;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)err_out_unmap: iounmap(pInfo->hw.hw_addr);err_out_free_res: pci_release_regions(pcid);err_out_free_dev: free_netdev(dev);#elseerr_out_free_res: if (pInfo->hw.ioaddr) release_region(pInfo->hw.ioaddr, pInfo->hw.io_size);err_out_free_dev: kfree(dev);#endiferr_out: return rc;}static void velocity_print_info(PVELOCITY_INFO pInfo){ struct net_device* dev = pInfo->dev; printk(KERN_INFO "%s: %s\n", dev->name, get_product_name(pInfo->chip_id)); printk(KERN_INFO "%s: MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", dev->name, dev->dev_addr[0],dev->dev_addr[1],dev->dev_addr[2], dev->dev_addr[3],dev->dev_addr[4],dev->dev_addr[5]); printk(" IO=0x%lx Mem=0x%lx ", pInfo->hw.ioaddr, pInfo->hw.memaddr); printk(" IRQ=%d \n", dev->irq);}static BOOL velocity_init_rings(PVELOCITY_INFO pInfo){ int i; struct net_device* dev = pInfo->dev; /*allocate all RD/TD rings a single pool*/ pInfo->pool = pci_alloc_consistent(pInfo->pcid, pInfo->hw.sOpts.nRxDescs * sizeof(RX_DESC) + 64 + pInfo->hw.sOpts.nTxDescs * sizeof(TX_DESC)*pInfo->hw.nTxQueues, &pInfo->hw.pool_dma); if (pInfo->pool == NULL) { printk(KERN_ERR "%s : allocate dma memory failed\n", dev->name); return FALSE; } memset(pInfo->pool,0, pInfo->hw.sOpts.nRxDescs * sizeof(RX_DESC) + pInfo->hw.sOpts.nTxDescs * sizeof(TX_DESC)*pInfo->hw.nTxQueues); pInfo->hw.aRDRing = (PRX_DESC)(((unsigned long)(((PU8) pInfo->pool) + 63)) & ~63); pInfo->hw.rd_pool_dma = pInfo->hw.pool_dma; pInfo->tx_bufs=pci_alloc_consistent(pInfo->pcid, pInfo->hw.sOpts.nTxDescs * PKT_BUF_SZ*pInfo->hw.nTxQueues, &pInfo->hw.tx_bufs_dma); if (pInfo->tx_bufs == NULL) { printk(KERN_ERR "%s: allocate dma memory failed\n", dev->name); pci_free_consistent(pInfo->pcid, pInfo->hw.sOpts.nRxDescs * sizeof(RX_DESC) + 64 + pInfo->hw.sOpts.nTxDescs * sizeof(TX_DESC)*pInfo->hw.nTxQueues, pInfo->pool, pInfo->hw.pool_dma); return FALSE; } memset(pInfo->tx_bufs, 0, pInfo->hw.sOpts.nTxDescs * PKT_BUF_SZ * pInfo->hw.nTxQueues); for (i=0;i<pInfo->hw.nTxQueues;i++) { pInfo->hw.td_pool_dma[i]=pInfo->hw.rd_pool_dma+ pInfo->hw.sOpts.nRxDescs*sizeof(RX_DESC)+ pInfo->hw.sOpts.nTxDescs*sizeof(TX_DESC)*i; pInfo->hw.apTDRings[i]=(PTX_DESC) (((PU8) pInfo->hw.aRDRing)+ pInfo->hw.sOpts.nRxDescs*sizeof(RX_DESC)+ pInfo->hw.sOpts.nTxDescs*sizeof(TX_DESC)*i); } return TRUE;}static void velocity_free_rings(PVELOCITY_INFO pInfo) { pci_free_consistent(pInfo->pcid, pInfo->hw.sOpts.nRxDescs * sizeof(RX_DESC) + 64 + pInfo->hw.sOpts.nTxDescs * sizeof(TX_DESC)*pInfo->hw.nTxQueues, pInfo->pool, pInfo->hw.pool_dma); if (pInfo->tx_bufs) pci_free_consistent(pInfo->pcid, pInfo->hw.sOpts.nTxDescs * PKT_BUF_SZ*pInfo->hw.nTxQueues, pInfo->tx_bufs, pInfo->hw.tx_bufs_dma);}static BOOL velocity_init_rd_ring(PVELOCITY_INFO pInfo){ int i; PRX_DESC pDesc; PVELOCITY_RD_INFO pRDInfo; struct net_device* dev = pInfo->dev; pInfo->aRDInfo=MALLOC(sizeof(VELOCITY_RD_INFO)*pInfo->hw.sOpts.nRxDescs, GFP_KERNEL); memset(pInfo->aRDInfo,0,sizeof(VELOCITY_RD_INFO)*pInfo->hw.sOpts.nRxDescs); /* Init the RD ring entries */ for (i = 0; i < pInfo->hw.sOpts.nRxDescs; i++) { pDesc=&(pInfo->hw.aRDRing[i]); pRDInfo=&(pInfo->aRDInfo[i]); if (!velocity_alloc_rx_buf(pInfo, i)) { VELOCITY_PRT(msglevel, MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc rx bufs\n", dev->name); return FALSE; } pDesc->rdesc0 |= cpu_to_le32(RDESC0_OWN); } pInfo->hw.iCurrRDIdx = 0; return TRUE;}static void velocity_free_rd_ring(PVELOCITY_INFO pInfo) { int i; PVELOCITY_RD_INFO pRDInfo; if (pInfo->aRDInfo == NULL) return; for (i = 0; i < pInfo->hw.sOpts.nRxDescs; i++) { pRDInfo = &(pInfo->aRDInfo[i]); if (pRDInfo->skb_dma) { pci_unmap_single(pInfo->pcid,pRDInfo->skb_dma, pInfo->hw.rx_buf_sz, PCI_DMA_FROMDEVICE); pRDInfo->skb_dma=(dma_addr_t)NULL; } if (pRDInfo->skb) { dev_kfree_skb(pRDInfo->skb); pRDInfo->skb=NULL; } } if (pInfo->aRDInfo) kfree(pInfo->aRDInfo); pInfo->aRDInfo = NULL;}static BOOL velocity_init_td_ring(PVELOCITY_INFO pInfo) { int i,j; dma_addr_t curr; PTX_DESC pDesc; PVELOCITY_TD_INFO pTDInfo; /* Init the TD ring entries */ for (j=0;j<pInfo->hw.nTxQueues;j++) { curr=pInfo->hw.td_pool_dma[j]; pInfo->apTDInfos[j]=MALLOC(sizeof(VELOCITY_TD_INFO)*pInfo->hw.sOpts.nTxDescs, GFP_KERNEL); memset(pInfo->apTDInfos[j],0, sizeof(VELOCITY_TD_INFO)*pInfo->hw.sOpts.nTxDescs); for (i = 0; i < pInfo->hw.sOpts.nTxDescs; i++, curr+=sizeof(TX_DESC)) { pDesc=&(pInfo->hw.apTDRings[j][i]); pTDInfo=&(pInfo->apTDInfos[j][i]); pTDInfo->buf=pInfo->tx_bufs+(i+j)*PKT_BUF_SZ; pTDInfo->buf_dma=pInfo->hw.tx_bufs_dma+(i+j)*PKT_BUF_SZ; } pInfo->hw.aiTailTDIdx[j]=pInfo->hw.aiCurrTDIdx[j]=pInfo->hw.iTDUsed[j]=0; } return TRUE;}static void velocity_free_td_ring(PVELOCITY_INFO pInfo) { int i, j, k; PVELOCITY_TD_INFO pTDInfo; for (j=0; j<pInfo->hw.nTxQueues; j++) { if (pInfo->apTDInfos[j] == NULL) continue; for (i = 0; i < pInfo->hw.sOpts.nTxDescs; i++) { pTDInfo = &(pInfo->apTDInfos[j][i]); if (pTDInfo == NULL) continue; for (k=0; k<pTDInfo->nskb_dma; k++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -