網路裝置結構體net_device介紹
阿新 • • 發佈:2019-01-04
static int __devinit e100_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *netdev; struct nic *nic; /*網路裝置私有空間*/ int err; if (!(netdev = alloc_etherdev(sizeof(struct nic)))) {/*申請網路裝置私有空間*/ if (((1 << debug) - 1) & NETIF_MSG_PROBE) pr_err("Etherdev alloc failed, aborting\n"); return -ENOMEM; } netdev->netdev_ops = &e100_netdev_ops;/*網路裝置操作函式初始化*/ SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops); netdev->watchdog_timeo = E100_WATCHDOG_PERIOD; strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); /*網路裝置名字*/ nic = netdev_priv(netdev); /*得到私有空間地址*/ netif_napi_add(netdev, &nic->napi, e100_poll, E100_NAPI_WEIGHT); /*poll初始化*/ nic->netdev = netdev; /*指向網路裝置結構體*/ nic->pdev = pdev; nic->msg_enable = (1 << debug) - 1; nic->mdio_ctrl = mdio_ctrl_hw; pci_set_drvdata(pdev, netdev); if ((err = pci_enable_device(pdev))) { netif_err(nic, probe, nic->netdev, "Cannot enable PCI device, aborting\n"); goto err_out_free_dev; } if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { netif_err(nic, probe, nic->netdev, "Cannot find proper PCI device base address, aborting\n"); err = -ENODEV; goto err_out_disable_pdev; } if ((err = pci_request_regions(pdev, DRV_NAME))) { netif_err(nic, probe, nic->netdev, "Cannot obtain PCI resources, aborting\n"); goto err_out_disable_pdev; } if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) { /*DMA通道初始化*/ netif_err(nic, probe, nic->netdev, "No usable DMA configuration, aborting\n"); goto err_out_free_res; } SET_NETDEV_DEV(netdev, &pdev->dev); if (use_io) netif_info(nic, probe, nic->netdev, "using i/o access mode\n"); nic->csr = pci_iomap(pdev, (use_io ? 1 : 0), sizeof(struct csr)); if (!nic->csr) { netif_err(nic, probe, nic->netdev, "Cannot map device registers, aborting\n"); err = -ENOMEM; goto err_out_free_res; } if (ent->driver_data) nic->flags |= ich; else nic->flags &= ~ich; e100_get_defaults(nic); /* locks must be initialized before calling hw_reset */ spin_lock_init(&nic->cb_lock); spin_lock_init(&nic->cmd_lock); spin_lock_init(&nic->mdio_lock); /* Reset the device before pci_set_master() in case device is in some * funky state and has an interrupt pending - hint: we don't have the * interrupt handler registered yet. */ e100_hw_reset(nic); pci_set_master(pdev); init_timer(&nic->watchdog); nic->watchdog.function = e100_watchdog; /*watchdog初始化*/ nic->watchdog.data = (unsigned long)nic; init_timer(&nic->blink_timer); nic->blink_timer.function = e100_blink_led; nic->blink_timer.data = (unsigned long)nic; INIT_WORK(&nic->tx_timeout_task, e100_tx_timeout_task); /*超時時間初始化*/ if ((err = e100_alloc(nic))) { netif_err(nic, probe, nic->netdev, "Cannot alloc driver memory, aborting\n"); goto err_out_iounmap; } if ((err = e100_eeprom_load(nic))) goto err_out_free; e100_phy_init(nic); memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN); memcpy(netdev->perm_addr, nic->eeprom, ETH_ALEN); if (!is_valid_ether_addr(netdev->perm_addr)) { if (!eeprom_bad_csum_allow) { netif_err(nic, probe, nic->netdev, "Invalid MAC address from EEPROM, aborting\n"); err = -EAGAIN; goto err_out_free; } else { netif_err(nic, probe, nic->netdev, "Invalid MAC address from EEPROM, you MUST configure one.\n"); } } /* Wol magic packet can be enabled from eeprom */ if ((nic->mac >= mac_82558_D101_A4) && (nic->eeprom[eeprom_id] & eeprom_id_wol)) { nic->flags |= wol_magic; device_set_wakeup_enable(&pdev->dev, true); } /* ack any pending wake events, disable PME */ pci_pme_active(pdev, false); strcpy(netdev->name, "eth%d"); if ((err = register_netdev(netdev))) { /*註冊網路裝置*/ netif_err(nic, probe, nic->netdev, "Cannot register net device, aborting\n"); goto err_out_free; } nic->cbs_pool = pci_pool_create(netdev->name, nic->pdev, nic->params.cbs.max * sizeof(struct cb), sizeof(u32), 0); netif_info(nic, probe, nic->netdev, "addr 0x%llx, irq %d, MAC addr %pM\n", (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), pdev->irq, netdev->dev_addr); /*向系統申請軟中斷*/ return 0; err_out_free: e100_free(nic); err_out_iounmap: pci_iounmap(pdev, nic->csr); err_out_free_res: pci_release_regions(pdev); err_out_disable_pdev: pci_disable_device(pdev); err_out_free_dev: pci_set_drvdata(pdev, NULL); free_netdev(netdev); return err; }