static int e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; /* * When SoL/IDER sessions are active, autoneg/speed/duplex * cannot be changed */ if (e1000_check_reset_block(hw)) { e_err("Cannot change link characteristics when SoL/IDER is " "active.\n"); return -EINVAL; } while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) msleep(1); if (ecmd->autoneg == AUTONEG_ENABLE) { hw->mac.autoneg = 1; if (hw->phy.media_type == e1000_media_type_fiber) hw->phy.autoneg_advertised = ADVERTISED_1000baseT_Full | ADVERTISED_FIBRE | ADVERTISED_Autoneg; else hw->phy.autoneg_advertised = ecmd->advertising | ADVERTISED_TP | ADVERTISED_Autoneg; ecmd->advertising = hw->phy.autoneg_advertised; if (adapter->fc_autoneg) hw->fc.requested_mode = e1000_fc_default; } else { if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) { clear_bit(__E1000_RESETTING, &adapter->state); return -EINVAL; } } /* reset the link */ if (netif_running(adapter->netdev)) { e1000e_down(adapter); e1000e_up(adapter); } else { e1000e_reset(adapter); } clear_bit(__E1000_RESETTING, &adapter->state); return 0; }
/** * e1000_probe - Initial configuration of e1000 NIC * * @v pci PCI device * @v id PCI IDs * * @ret rc Return status code **/ int e1000_probe ( struct pci_device *pdev ) { int i, err; struct net_device *netdev; struct e1000_adapter *adapter; unsigned long mmio_start, mmio_len; DBG ( "e1000_probe\n" ); err = -ENOMEM; /* Allocate net device ( also allocates memory for netdev->priv and makes netdev-priv point to it ) */ netdev = alloc_etherdev ( sizeof ( struct e1000_adapter ) ); if ( ! netdev ) goto err_alloc_etherdev; /* Associate e1000-specific network operations operations with * generic network device layer */ netdev_init ( netdev, &e1000_operations ); /* Associate this network device with given PCI device */ pci_set_drvdata ( pdev, netdev ); netdev->dev = &pdev->dev; /* Initialize driver private storage */ adapter = netdev_priv ( netdev ); memset ( adapter, 0, ( sizeof ( *adapter ) ) ); adapter->pdev = pdev; adapter->ioaddr = pdev->ioaddr; adapter->hw.io_base = pdev->ioaddr; adapter->irqno = pdev->irq; adapter->netdev = netdev; adapter->hw.back = adapter; adapter->tx_ring_size = sizeof ( *adapter->tx_base ) * NUM_TX_DESC; adapter->rx_ring_size = sizeof ( *adapter->rx_base ) * NUM_RX_DESC; mmio_start = pci_bar_start ( pdev, PCI_BASE_ADDRESS_0 ); mmio_len = pci_bar_size ( pdev, PCI_BASE_ADDRESS_0 ); DBG ( "mmio_start: %#08lx\n", mmio_start ); DBG ( "mmio_len: %#08lx\n", mmio_len ); /* Fix up PCI device */ adjust_pci_device ( pdev ); err = -EIO; adapter->hw.hw_addr = ioremap ( mmio_start, mmio_len ); DBG ( "adapter->hw.hw_addr: %p\n", adapter->hw.hw_addr ); if ( ! adapter->hw.hw_addr ) goto err_ioremap; /* Hardware features, flags and workarounds */ if (adapter->hw.mac.type >= e1000_82540) { adapter->flags |= E1000_FLAG_HAS_SMBUS; adapter->flags |= E1000_FLAG_HAS_INTR_MODERATION; } if (adapter->hw.mac.type == e1000_82543) adapter->flags |= E1000_FLAG_BAD_TX_CARRIER_STATS_FD; adapter->hw.phy.autoneg_wait_to_complete = true; adapter->hw.mac.adaptive_ifs = true; /* setup the private structure */ if ( ( err = e1000_sw_init ( adapter ) ) ) goto err_sw_init; if ((err = e1000_init_mac_params(&adapter->hw))) goto err_hw_init; if ((err = e1000_init_nvm_params(&adapter->hw))) goto err_hw_init; /* Force auto-negotiated speed and duplex */ adapter->hw.mac.autoneg = 1; if ((err = e1000_init_phy_params(&adapter->hw))) goto err_hw_init; DBG ( "adapter->hw.mac.type: %#08x\n", adapter->hw.mac.type ); /* before reading the EEPROM, reset the controller to * put the device in a known good starting state */ err = e1000_reset_hw ( &adapter->hw ); if ( err < 0 ) { DBG ( "Hardware Initialization Failed\n" ); goto err_reset; } /* make sure the NVM is good */ if ( e1000_validate_nvm_checksum(&adapter->hw) < 0 ) { DBG ( "The NVM Checksum Is Not Valid\n" ); err = -EIO; goto err_eeprom; } /* copy the MAC address out of the EEPROM */ if ( e1000_read_mac_addr ( &adapter->hw ) ) DBG ( "EEPROM Read Error\n" ); memcpy ( netdev->hw_addr, adapter->hw.mac.perm_addr, ETH_ALEN ); /* reset the hardware with the new settings */ e1000_reset ( adapter ); if ( ( err = register_netdev ( netdev ) ) != 0) goto err_register; /* Mark as link up; we don't yet handle link state */ netdev_link_up ( netdev ); for (i = 0; i < 6; i++) DBG ("%02x%s", netdev->ll_addr[i], i == 5 ? "\n" : ":"); DBG ( "e1000_probe succeeded!\n" ); /* No errors, return success */ return 0; /* Error return paths */ err_reset: err_register: err_hw_init: err_eeprom: if (!e1000_check_reset_block(&adapter->hw)) e1000_phy_hw_reset(&adapter->hw); if (adapter->hw.flash_address) iounmap(adapter->hw.flash_address); err_sw_init: iounmap ( adapter->hw.hw_addr ); err_ioremap: netdev_put ( netdev ); err_alloc_etherdev: return err; }