Linux2.6.39下DM9K驱动源码分析(5)

***************************************************************************************************************************************/

#ifdef CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL
    db->flags |= DM9000_PLATF_SIMPLE_PHY;
#endif
    //复位芯片
    dm9000_reset(db);
    //读取芯片ID号并判断是否为0x90000A46**/
    /* try multiple times, DM9000 sometimes gets the read wrong */
    for (i = 0; i < 8; i++) {
        id_val  = ior(db, DM9000_VIDL);//供应商ID低8位
        id_val |= (u32)ior(db, DM9000_VIDH) << 8;//供应商ID高8位
        id_val |= (u32)ior(db, DM9000_PIDL) << 16;//产品ID低8位
        id_val |= (u32)ior(db, DM9000_PIDH) << 24;//产品ID高8位

        if (id_val == DM9000_ID)//芯片ID
            break;
        dev_err(db->dev, "read wrong id 0x%08x\n", id_val);
    }

    if (id_val != DM9000_ID) {
        dev_err(db->dev, "wrong id: 0x%08x\n", id_val);
        ret = -ENODEV;
        goto out;
    }

    /* Identify what type of DM9000 we are working on */
    //读DM9000_CHIPR寄存器判断网卡类型
    id_val = ior(db, DM9000_CHIPR);//读chip revision寄存器
    dev_dbg(db->dev, "dm9000 revision 0x%02x\n", id_val);

    switch (id_val) {
    case CHIPR_DM9000A:
        db->type = TYPE_DM9000A;
        break;
    case CHIPR_DM9000B:
        db->type = TYPE_DM9000B;
        break;
    default:
        dev_dbg(db->dev, "ID %02x => defaulting to DM9000E\n", id_val);
        db->type = TYPE_DM9000E;
    }

    /* dm9000a/b are capable of hardware checksum offload */
    if (db->type == TYPE_DM9000A || db->type == TYPE_DM9000B) {
        db->can_csum = 1;
        db->rx_csum = 1;
        ndev->features |= NETIF_F_IP_CSUM;
    }

    /* from this point we assume that we have found a DM9000 */
    //初始化以太网ndev的部分成员
    /* driver system function */
    /**
    *以太网设置
    **/
    ether_setup(ndev);

 //手动初始化ndev的ops和db的mii部分。
    ndev->netdev_ops    = &dm9000_netdev_ops;//网络设备操作函数指针集
    ndev->watchdog_timeo    = msecs_to_jiffies(watchdog);
    ndev->ethtool_ops    = &dm9000_ethtool_ops;//用于设置网络

    db->msg_enable       = NETIF_MSG_LINK;
    db->mii.phy_id_mask  = 0x1f;
    db->mii.reg_num_mask = 0x1f;
    db->mii.force_media  = 0;
    db->mii.full_duplex  = 0;
    db->mii.dev         = ndev;
    db->mii.mdio_read    = dm9000_phy_read;
    db->mii.mdio_write   = dm9000_phy_write;
//读取网卡MAC地址,
    mac_src = "eeprom";
    //从EEPROM中读取MAC
    /* try reading the node address from the attached EEPROM */
    for (i = 0; i < 6; i += 2)
        dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
    //判断MAC是否合法
    if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {
        mac_src = "platform data";
        memcpy(ndev->dev_addr, pdata->dev_addr, 6);
    }

    if (!is_valid_ether_addr(ndev->dev_addr)) {
        /* try reading from mac */
        
        mac_src = "chip";
        for (i = 0; i < 6; i++)
            ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
    }

    if (!is_valid_ether_addr(ndev->dev_addr)) {
        dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
             "set using ifconfig\n", ndev->name);

        random_ether_addr(ndev->dev_addr);
        mac_src = "random";
    }


    platform_set_drvdata(pdev, ndev);
    //注册网卡驱动
    ret = register_netdev(ndev);

    if (ret == 0)
        printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %pM (%s)\n",
               ndev->name, dm9000_type_to_char(db->type),
               db->io_addr, db->io_data, ndev->irq,
               ndev->dev_addr, mac_src);

return 0;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyxjyy.html