2410平臺上dm9000a網(wǎng)卡驅(qū)動分析

    該驅(qū)動基于linux-2.6.24.4內(nèi)核。

        首先,需要在arch/arm/mach-s3c2410/mach-smdk2410.c文件中添加如下代碼:

    static struct resource s3c_dm9000_resource [] = {

        [0] = {

            .start = 0x10000000,

            .end = 0x10000040,

            .flags = IORESOURCE_MEM

        },

        [1] = {

            .start = IRQ_EINT2,

            .end = IRQ_EINT2,

            .flags = IORESOURCE_IRQ,

        }

    };
     

    注意上面的start、end等地址是指的網(wǎng)卡的物理地址。然后,還要在該文件中加入如下代碼:

    struct platform_device s3c_device_dm9000 = {

        .name = "dm9000",

        .id = -1,

        .num_resources = ARRAY_SIZE(s3c_dm9000_resource),

        .resource = s3c_dm9000_resource,

    };
     
    需要特別注意上面的name字段,當(dāng)設(shè)備驅(qū)動程序?qū)ふ以O(shè)別資源時,會根據(jù)該字段對設(shè)備進(jìn)行匹配。另外,該文件中的smdk2410_devices[]數(shù)組中,還需要加入s3c_device_dm9000,不然系統(tǒng)啟動時沒有找

    到該資源就不會調(diào)用相應(yīng)的probe函數(shù)。

        下面分析驅(qū)動程序的probe函數(shù)。若驅(qū)動被編譯進(jìn)內(nèi)核,則在系統(tǒng)啟動的時候,該函數(shù)會被調(diào)用。該函數(shù)的源代碼如下:

    static int dm9k_drv_probe(struct platform_device *pdev)
    {
            struct net_device *ndev;
            unsigned long base;
            unsigned int *addr = NULL;
            int ret = -ENODEV;
            ndev = alloc_etherdev(sizeof(struct board_info));
            if (!ndev) {
                    printk("%s: could not allocate device.\n", CARDNAME);
                    return -ENOMEM;
            }
           
            ndev->dma = (unsigned char)-1;
            if (pdev->num_resources < 2 || pdev->num_resources > 3) {
                    printk("DM9000: Wrong num of resources %d\n", pdev->num_resources);
                    ret = -ENODEV;
                    goto out;
            }
            base = pdev->resource[0].start;
            ndev->irq = pdev->resource[1].start;
            /*
             * Request the regions.
             */
            if (!request_mem_region(base, 4, ndev->name)) {
                    ret = -EBUSY;
                    goto out;
            }

            addr = ioremap(base, 4);
            if (!addr) {
                    ret = -ENOMEM;
                    goto release_mem;
            }
            ret = dm9k_probe(ndev, (unsigned long)addr);
            if (ret != 0) {
             iounmap(addr);
     release_mem:
                    release_mem_region(base, 4);
     out:
                    printk("%s: not found (%d).\n", CARDNAME, ret);
                    kfree(ndev);
            }
            return ret;
    }
     

    函數(shù)首先調(diào)用alloc_etherdev,該函數(shù)在include/linux/etherdevice.h中聲明,其中有如下語句:

    #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1)
     

    而alloc_etherdev_mq函數(shù)又定義在net/ethernet/eth.c中,如下:

    struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count)
    {
        return alloc_netdev_mq(sizeof_priv, "eth%d", ether_setup, queue_count);
    }
     

    可見,該函數(shù)只是用自己的參數(shù)來調(diào)用alloc_netdev_mq函數(shù)。alloc_netdev_mq函數(shù)定義在net/core/dev.c中,原型如下:

    struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
            void (*setup)(struct net_device *), unsigned int queue_count)

    關(guān)于該函數(shù)的說明:
    /**
     * alloc_netdev_mq - allocate network device
     * @sizeof_priv: size of private data to allocate space for
     * @name:  device name format string
     * @setup:  callback to initialize device
     * @queue_count: the number of subqueues to allocate
     *
     * Allocates a struct net_device with private data area for driver use
     * and performs basic initialization.  Also allocates subquue structs
     * for each queue on the device at the end of the netdevice.
     */
    可見,alloc_etherdev為設(shè)備驅(qū)動分配了私有數(shù)據(jù)空間,并對設(shè)備驅(qū)動做了一些初始化工作。
     
    接下來,設(shè)備驅(qū)動將要檢查設(shè)備的resources的數(shù)量,如果數(shù)量小于2或者大于3,則初始化函數(shù)自動返回,初始化失敗。我們的設(shè)備驅(qū)動中,resources的數(shù)量為2:一個表示設(shè)備的IO地址,另一個是設(shè)備
    的中斷號。
     
    代碼
            base = pdev->resource[0].start;
            ndev->irq = pdev->resource[1].start;
     
    分別得到設(shè)備的端口地址和中斷號。
    接下來,驅(qū)動程序?qū)⑾蛳到y(tǒng)申請io內(nèi)存,從地址base開始,大小為4個字節(jié)。如果申請成功,接下來需要做的就是將地址重新映射,從地址base開始,長度為4個字節(jié)。這樣做的原因主要是驅(qū)動程序一般
    不直接訪問物理地址,而訪問虛擬地址。地址重新映射成功后,就調(diào)用dm9k_probe函數(shù)進(jìn)行設(shè)備初始化。
    dm9k_probe函數(shù)的全部代碼如下
    int __init dm9k_probe(struct net_device *dev, unsigned long addr)
    {
            struct board_info *db; /* Point a board information structure */
            u32 id_val;
            u16 i, j;
            int retval;
              /* Search for DM9000 serial NIC */
            PUTB(DM9KS_VID_L, addr);
            id_val = GETB(addr + 2); /* Change offset to 2 ^^^^^ */
            PUTB(DM9KS_VID_H, addr);
            id_val |= GETB(addr + 2) << 8;
            PUTB(DM9KS_PID_L, addr);
            id_val |= GETB(addr + 2) << 16;
            PUTB(DM9KS_PID_H, addr);
            id_val |= GETB(addr + 2) << 24;
            if (id_val != DM9KS_ID && id_val != DM9010_ID) {
                    /* Dm9k chip not found */
                    printk("dmfe_probe(): DM9000 not found. ID=%08X\n", id_val);
                    return -ENODEV;
                    }
                   
            printk("<DM9KS> I/O: %lx, VID: %x \n",addr, id_val);
            /* Allocated board information structure */
            memset(dev->priv, 0, sizeof(struct board_info));
            db = (board_info_t *)dev->priv;
            dmfe_dev = dev;
            db->io_addr = addr;
            db->io_data = addr + 2; /* Change offset to 2 ^^^^^ */
            /* driver system function */
                                   
            dev->base_addr = addr;
            dev->irq = IRQ_EINT2;
            dev->open = &dmfe_open;
            dev->hard_start_xmit = &dmfe_start_xmit;
            dev->watchdog_timeo = HZ;
            dev->tx_timeout = dmfe_timeout;
            dev->stop = &dmfe_stop;
            dev->get_stats = &dmfe_get_stats;
            dev->set_multicast_list = &dm9000_hash_table;
            dev->do_ioctl = &dmfe_do_ioctl;
            for(i=0,j=0x10; i<6; i++,j++)
              {
                    db->srom[i] = ior(db, j);
                  
              }
          
            /* Set Node Address */
            for (i=0; i<6; i++)
                    dev->dev_addr[i] = db->srom[i];
            retval = register_netdev(dev);
            if (retval == 0) {
                    /* now, print out the card info, in a short format.. */
                    printk("%s: at %#lx IRQ %d\n",
                            dev->name, dev->base_addr, dev->irq);
                    if (dev->dma != (unsigned char)-1)
                            printk(" DMA %d\n", dev->dma);
                    if (!is_valid_ether_addr(dev->dev_addr)) {
                            printk("%s: Invalid ethernet MAC address. Please "
                                   "set using ifconfig\n", dev->name);
                    } else {
                            /* Print the Ethernet address */
                            printk("%s: Ethernet addr: ", dev->name);
                            for (i = 0; i < 5; i++)
                                    printk("%2.2x:", dev->dev_addr[i]);
                            printk("%2.2x\n", dev->dev_addr[5]);
                    }
            }
            return 0;
    }
     
    函數(shù)首先調(diào)用PUTB來寫dm9000a芯片,來看看PUTB的實現(xiàn)
    #define PUTB(d,a) *((volatile unsigned char *) (a)) = d
     
    可見,PUTB是直接使用的指針,而沒有使用內(nèi)核提供的write等函數(shù),同樣,GETB函數(shù)如下
    #define GETB(a) *((volatile unsigned char *) (a))
     
    注意,這里的地址都是虛擬地址,因為**調(diào)用函數(shù)dm9k_probe時傳遞的addr時重新映射后的,而不是直接傳送的物理地址。

     


    深圳市愛欣文科技有限公司專注于網(wǎng)絡(luò)芯片,davicom,magcom,DM9000等

  • 詞條

    詞條說明

  • 較新DAVICOM各種產(chǎn)品配套方案

    .應(yīng)用案例: 1) IPSTB(機頂盒):ST系列(5516、5100、5514、5517、7100、7109)+網(wǎng)卡芯片 (DM9000AE/DM9161AE)+HS12369; ????NEC(61110/6114)+網(wǎng)卡芯片(DM9000AE)+HS12369; 2) VOD ; EM8511+DM9000E/DM9000AE+HS12369; 3)

  • 公司結(jié)構(gòu)

    A.X.W 愛欣文科技有限公司 ? 1、武漢華美特電子工程有限責(zé)任公司(愛欣文公司武漢辦事處) 武漢辦事處地址:武漢市東湖開發(fā)區(qū)珞瑜路727號光谷銀座1305室 電話:027-87207595;027-87207596;027-87880506 傳真:027-87653172? 聯(lián)系人:李經(jīng)理 Mobile:13469977252 E-mail:baron_li@axwdra

  • 企業(yè)宗旨

    愛欣文科技有限公司長期從事**較新集成電路(IC)代理銷售業(yè)務(wù).總公司下設(shè)中國香港公司、深圳公司、武漢公司及在內(nèi)地各有關(guān)地區(qū)業(yè)務(wù)辦事處等機構(gòu),構(gòu)成了**國內(nèi)IC 市場營銷業(yè)務(wù)立體網(wǎng)絡(luò),是集研發(fā)方案提供商和IC **代理商于一體的科貿(mào)公司. 公司接受榮譽授權(quán),全面代理閩臺DAVICOM 聯(lián)杰**,RMI,MAGCOM磁威,TMC,GIGASTORAGE等****品牌集成電路(IC)及其相關(guān)的全線產(chǎn)品。

  • davicom,magcom代理

    深圳市愛欣文科技有限公司是閩臺聯(lián)杰**(DAVICOM) 股份有限公司﹑閩臺磁威(MAGCOM)公司在中國大陸的授權(quán)代理商。 供應(yīng)DAVICOM全系列產(chǎn)品DM9000EP DM9161AEP DM9000AEP DM9601EP DM9161EP DM9620 DM9006EP DM8806AFP ... 及MAGCOM全系列產(chǎn)品HS12369 HS12361 HS9001 HS9016&nbs

聯(lián)系方式 聯(lián)系我時,請告知來自八方資源網(wǎng)!

公司名: 深圳市愛欣文科技有限公司

聯(lián)系人: 李先生

電 話: 027-87880506

手 機: 13469977252

微 信: 13469977252

地 址: 湖北武漢武漢市東湖開發(fā)區(qū)珞瑜路727號光谷銀座1305室

郵 編: 430074

網(wǎng) 址: davicom1.cn.b2b168.com

八方資源網(wǎng)提醒您:
1、本信息由八方資源網(wǎng)用戶發(fā)布,八方資源網(wǎng)不介入任何交易過程,請自行甄別其真實性及合法性;
2、跟進(jìn)信息之前,請仔細(xì)核驗對方資質(zhì),所有預(yù)付定金或付款至個人賬戶的行為,均存在詐騙風(fēng)險,請?zhí)岣呔瑁?
    聯(lián)系方式

公司名: 深圳市愛欣文科技有限公司

聯(lián)系人: 李先生

手 機: 13469977252

電 話: 027-87880506

地 址: 湖北武漢武漢市東湖開發(fā)區(qū)珞瑜路727號光谷銀座1305室

郵 編: 430074

網(wǎng) 址: davicom1.cn.b2b168.com

    相關(guān)企業(yè)
    商家產(chǎn)品系列
  • 產(chǎn)品推薦
  • 資訊推薦
關(guān)于八方 | 八方幣 | 招商合作 | 網(wǎng)站地圖 | 免費注冊 | 一元廣告 | 友情鏈接 | 聯(lián)系我們 | 八方業(yè)務(wù)| 匯款方式 | 商務(wù)洽談室 | 投訴舉報
粵ICP備10089450號-8 - 經(jīng)營許可證編號:粵B2-20130562 軟件企業(yè)認(rèn)定:深R-2013-2017 軟件產(chǎn)品登記:深DGY-2013-3594
著作權(quán)登記:2013SR134025
Copyright ? 2004 - 2025 b2b168.com All Rights Reserved