diff options
-rw-r--r-- | drivers/net/igb/igb_main.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 84dfd6c061d2..d2a55c4ba4d1 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -48,6 +48,7 @@ #endif /* CONFIG_PM_RUNTIME */ #include <linux/if_bridge.h> +#include <linux/ctype.h> #include "igb.h" #include "igb_vmdq.h" @@ -73,6 +74,9 @@ static const char igb_driver_string[] = static const char igb_copyright[] = "Copyright (c) 2007-2015 Intel Corporation."; +static char g_mac_addr[ETH_ALEN]; +static int g_usr_mac = 0; + static const struct pci_device_id igb_pci_tbl[] = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_BACKPLANE_1GBPS) }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_SGMII) }, @@ -291,6 +295,40 @@ MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); +/* Retrieve user set MAC address */ +static int __init setup_igb_mac(char *macstr) +{ + int i, j; + unsigned char result, value; + + for (i = 0; i < ETH_ALEN; i++) { + result = 0; + + if (i != 5 && *(macstr + 2) != ':') + return -1; + + for (j = 0; j < 2; j++) { + if (isxdigit(*macstr) + && (value = + isdigit(*macstr) ? *macstr - + '0' : toupper(*macstr) - 'A' + 10) < 16) { + result = result * 16 + value; + macstr++; + } else + return -1; + } + + macstr++; + g_mac_addr[i] = result; + } + + g_usr_mac = 1; + + return 0; +} + +__setup("igb_mac=", setup_igb_mac); + static void igb_vfta_set(struct igb_adapter *adapter, u32 vid, bool add) { struct e1000_hw *hw = &adapter->hw; @@ -2770,15 +2808,38 @@ static int igb_probe(struct pci_dev *pdev, /* make sure the NVM is good */ if (e1000_validate_nvm_checksum(hw) < 0) { +#ifdef CONFIG_MACH_APALIS_T30 + /* only warn on NVM validation failures */ + dev_warn(pci_dev_to_dev(pdev), + "The NVM Checksum Is Not Valid\n"); +#else /* CONFIG_MACH_APALIS_T30 */ dev_err(pci_dev_to_dev(pdev), "The NVM Checksum Is Not Valid\n"); err = -EIO; goto err_eeprom; +#endif /* CONFIG_MACH_APALIS_T30 */ } /* copy the MAC address out of the NVM */ if (e1000_read_mac_addr(hw)) dev_err(pci_dev_to_dev(pdev), "NVM Read Error\n"); + +#ifdef CONFIG_MACH_APALIS_T30 + if (g_usr_mac && (g_usr_mac < 3)) { + /* Get user set MAC address */ + if (g_usr_mac == 2) { + /* 0x100000 offset for 2nd Ethernet MAC */ + g_mac_addr[3] += 0x10; + if (g_mac_addr[3] < 0x10) + dev_warn(pci_dev_to_dev(pdev), "MAC address " + "byte 3 (0x%02x) wrap around", + g_mac_addr[3]); + } + memcpy(hw->mac.addr, g_mac_addr, ETH_ALEN); + g_usr_mac++; + } +#endif /* CONFIG_MACH_APALIS_T30 */ + memcpy(netdev->dev_addr, hw->mac.addr, netdev->addr_len); #ifdef ETHTOOL_GPERMADDR memcpy(netdev->perm_addr, hw->mac.addr, netdev->addr_len); @@ -2787,9 +2848,20 @@ static int igb_probe(struct pci_dev *pdev, #else if (!is_valid_ether_addr(netdev->dev_addr)) { #endif +#ifdef CONFIG_MACH_APALIS_T30 + /* Use Toradex OUI as default */ + char default_mac_addr[ETH_ALEN] = {0x0, 0x14, 0x2d, 0x0, 0x0, 0x0}; + dev_warn(&pdev->dev, "using Toradex OUI as default igb MAC"); + memcpy(hw->mac.addr, default_mac_addr, ETH_ALEN); + memcpy(netdev->dev_addr, hw->mac.addr, netdev->addr_len); +#ifdef ETHTOOL_GPERMADDR + memcpy(netdev->perm_addr, hw->mac.addr, netdev->addr_len); +#endif +#else /* CONFIG_MACH_APALIS_T30 */ dev_err(pci_dev_to_dev(pdev), "Invalid MAC Address\n"); err = -EIO; goto err_eeprom; +#endif /* CONFIG_MACH_APALIS_T30 */ } memcpy(&adapter->mac_table[0].addr, hw->mac.addr, netdev->addr_len); @@ -3037,7 +3109,9 @@ err_register: #ifdef HAVE_I2C_SUPPORT memset(&adapter->i2c_adap, 0, sizeof(adapter->i2c_adap)); #endif /* HAVE_I2C_SUPPORT */ +#ifndef CONFIG_MACH_APALIS_T30 err_eeprom: +#endif if (!e1000_check_reset_block(hw)) e1000_phy_hw_reset(hw); |