diff options
Diffstat (limited to 'drivers/net/e1000/e1000_main.c')
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 340e12d2e4a9..bfab14092d2c 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -28,6 +28,12 @@ #include "e1000.h" #include <net/ip6_checksum.h> +#include <linux/io.h> + +/* Intel Media SOC GbE MDIO physical base address */ +static unsigned long ce4100_gbe_mdio_base_phy; +/* Intel Media SOC GbE MDIO virtual base address */ +void __iomem *ce4100_gbe_mdio_base_virt; char e1000_driver_name[] = "e1000"; static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; @@ -79,6 +85,7 @@ static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = { INTEL_E1000_ETHERNET_DEVICE(0x108A), INTEL_E1000_ETHERNET_DEVICE(0x1099), INTEL_E1000_ETHERNET_DEVICE(0x10B5), + INTEL_E1000_ETHERNET_DEVICE(0x2E6E), /* required last entry */ {0,} }; @@ -459,6 +466,7 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter) case e1000_82545: case e1000_82545_rev_3: case e1000_82546: + case e1000_ce4100: case e1000_82546_rev_3: case e1000_82541: case e1000_82541_rev_2: @@ -573,6 +581,7 @@ void e1000_reset(struct e1000_adapter *adapter) case e1000_82545: case e1000_82545_rev_3: case e1000_82546: + case e1000_ce4100: case e1000_82546_rev_3: pba = E1000_PBA_48K; break; @@ -894,6 +903,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, static int global_quad_port_a = 0; /* global ksp3 port a indication */ int i, err, pci_using_dac; u16 eeprom_data = 0; + u16 tmp = 0; u16 eeprom_apme_mask = E1000_EEPROM_APME; int bars, need_ioport; @@ -996,6 +1006,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev, goto err_sw_init; err = -EIO; + if (hw->mac_type == e1000_ce4100) { + ce4100_gbe_mdio_base_phy = pci_resource_start(pdev, BAR_1); + ce4100_gbe_mdio_base_virt = ioremap(ce4100_gbe_mdio_base_phy, + pci_resource_len(pdev, BAR_1)); + + if (!ce4100_gbe_mdio_base_virt) + goto err_mdio_ioremap; + } if (hw->mac_type >= e1000_82543) { netdev->features = NETIF_F_SG | @@ -1135,6 +1153,20 @@ static int __devinit e1000_probe(struct pci_dev *pdev, adapter->wol = adapter->eeprom_wol; device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); + /* Auto detect PHY address */ + if (hw->mac_type == e1000_ce4100) { + for (i = 0; i < 32; i++) { + hw->phy_addr = i; + e1000_read_phy_reg(hw, PHY_ID2, &tmp); + if (tmp == 0 || tmp == 0xFF) { + if (i == 31) + goto err_eeprom; + continue; + } else + break; + } + } + /* reset the hardware with the new settings */ e1000_reset(adapter); @@ -1171,6 +1203,8 @@ err_eeprom: kfree(adapter->rx_ring); err_dma: err_sw_init: +err_mdio_ioremap: + iounmap(ce4100_gbe_mdio_base_virt); iounmap(hw->hw_addr); err_ioremap: free_netdev(netdev); @@ -1409,6 +1443,7 @@ static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start, /* First rev 82545 and 82546 need to not allow any memory * write location to cross 64k boundary due to errata 23 */ if (hw->mac_type == e1000_82545 || + hw->mac_type == e1000_ce4100 || hw->mac_type == e1000_82546) { return ((begin ^ (end - 1)) >> 16) != 0 ? false : true; } @@ -2198,7 +2233,7 @@ static void e1000_set_rx_mode(struct net_device *netdev) * addresses take precedence to avoid disabling unicast filtering * when possible. * - * RAR 0 is used for the station MAC adddress + * RAR 0 is used for the station MAC address * if there are not 14 addresses, go ahead and clear the filters */ i = 1; @@ -3443,9 +3478,17 @@ static irqreturn_t e1000_intr(int irq, void *data) struct e1000_hw *hw = &adapter->hw; u32 icr = er32(ICR); - if (unlikely((!icr) || test_bit(__E1000_DOWN, &adapter->flags))) + if (unlikely((!icr))) return IRQ_NONE; /* Not our interrupt */ + /* + * we might have caused the interrupt, but the above + * read cleared it, and just in case the driver is + * down there is nothing to do so return handled + */ + if (unlikely(test_bit(__E1000_DOWN, &adapter->flags))) + return IRQ_HANDLED; + if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) { hw->get_link_status = 1; /* guard against interrupt when we're going down */ |