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

📄 velocity_main.c

📁 VIA千兆网卡芯片VT6122的linux驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        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 + -