***************************************************************************************************************************************/
#ifdef CONFIG_DM9000_FORCE_SIMPLE_PHY_POLLdb->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;