1. 程式人生 > >網路裝置結構體net_device介紹

網路裝置結構體net_device介紹

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;
}