From 5793ed8a010d40d8a6de825144fedf03ebbd1913 Mon Sep 17 00:00:00 2001 From: intel-ethernet Date: Wed, 13 Mar 2013 11:09:46 -0700 Subject: [PATCH] Update igb-basedline to published 4.1.2 version (adds support for 3.7+ kernels) --- kmod/igb/Makefile | 7 +- kmod/igb/e1000_82575.c | 41 ++++-- kmod/igb/e1000_api.c | 2 +- kmod/igb/e1000_api.h | 2 +- kmod/igb/e1000_defines.h | 11 +- kmod/igb/e1000_hw.h | 3 +- kmod/igb/e1000_i210.c | 69 +++++---- kmod/igb/e1000_i210.h | 4 +- kmod/igb/e1000_mac.c | 2 +- kmod/igb/e1000_mac.h | 2 +- kmod/igb/e1000_manage.c | 2 +- kmod/igb/e1000_manage.h | 2 +- kmod/igb/e1000_mbx.c | 2 +- kmod/igb/e1000_mbx.h | 2 +- kmod/igb/e1000_nvm.c | 22 +-- kmod/igb/e1000_nvm.h | 2 +- kmod/igb/e1000_osdep.h | 2 +- kmod/igb/e1000_phy.c | 2 +- kmod/igb/e1000_phy.h | 2 +- kmod/igb/igb.h | 20 +-- kmod/igb/igb_ethtool.c | 303 ++++++++++++++++++++++++++++++++++++--- kmod/igb/igb_main.c | 135 ++++++++++-------- kmod/igb/igb_param.c | 6 +- kmod/igb/igb_procfs.c | 2 +- kmod/igb/igb_ptp.c | 14 +- kmod/igb/igb_regtest.h | 2 +- kmod/igb/igb_sysfs.c | 6 +- kmod/igb/igb_vmdq.c | 2 +- kmod/igb/igb_vmdq.h | 2 +- kmod/igb/kcompat.c | 271 ++++++++++++++++++++++++++++++----- kmod/igb/kcompat.h | 346 +++++++++++++++++++++++++++++++++++++++++---- kmod/igb/kcompat_ethtool.c | 2 +- 32 files changed, 1041 insertions(+), 251 deletions(-) diff --git a/kmod/igb/Makefile b/kmod/igb/Makefile index a7fe0f4..00d919a 100644 --- a/kmod/igb/Makefile +++ b/kmod/igb/Makefile @@ -81,6 +81,7 @@ endif # Version file Search Path VSP := $(KOBJ)/include/generated/utsrelease.h \ + $(KOBJ)/include/generated/uapi/linux/version.h \ $(KOBJ)/include/linux/utsrelease.h \ $(KOBJ)/include/linux/version.h \ /boot/vmlinuz.version.h @@ -147,9 +148,9 @@ EXTRA_CFLAGS += -DDRIVER_NAME=$(DRIVER_NAME) EXTRA_CFLAGS += -DDRIVER_NAME_CAPS=$(shell echo $(DRIVER_NAME) | tr '[a-z]' '[A-Z]') # standard flags for module builds EXTRA_CFLAGS += -DLINUX -D__KERNEL__ -DMODULE -O2 -pipe -Wall +EXTRA_CFLAGS += -DHAVE_PTP_1588_CLOCK EXTRA_CFLAGS += -UCONFIG_NETDEVICES_MULTIQUEUE -EXTRA_CFLAGS += -DCONFIG_PTP -EXTRA_CFLAGS += -I$(KSRC)/include -I. +EXTRA_CFLAGS += -I$(KSRC)/generated/uapi -I/include -I. EXTRA_CFLAGS += $(shell [ -f $(KSRC)/include/linux/modversions.h ] && \ echo "-DMODVERSIONS -DEXPORT_SYMTAB \ -include $(KSRC)/include/linux/modversions.h") @@ -181,7 +182,7 @@ KVER_CODE := $(shell $(CC) $(EXTRA_CFLAGS) -E -dM $(VSP) 2>/dev/null |\ # abort the build on kernels older than 2.4.21 ifneq (1,$(shell [ $(KVER_CODE) -ge 132117 ] && echo 1 || echo 0)) $(error *** Aborting the build. \ - *** This driver is not supported on kernel versions older than 2.4.21, \ + *** This driver '$(KVER_CODE)' is not supported on kernel versions older than 2.4.21, \ because this driver requires NAPI support.) endif diff --git a/kmod/igb/e1000_82575.c b/kmod/igb/e1000_82575.c index cbb4bab..775e9ab 100644 --- a/kmod/igb/e1000_82575.c +++ b/kmod/igb/e1000_82575.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -137,6 +137,8 @@ static bool e1000_sgmii_uses_mdio_82575(struct e1000_hw *hw) break; case e1000_82580: case e1000_i350: + case e1000_i210: + case e1000_i211: reg = E1000_READ_REG(hw, E1000_MDICNFG); ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO); break; @@ -378,11 +380,14 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) mac->rar_entry_count = E1000_RAR_ENTRIES_82576; if (mac->type == e1000_82580) mac->rar_entry_count = E1000_RAR_ENTRIES_82580; - if (mac->type == e1000_i350) { + if (mac->type == e1000_i350) mac->rar_entry_count = E1000_RAR_ENTRIES_I350; - /* Enable EEE default settings for i350 */ + /* Enable EEE default settings for EEE supported devices */ + if (mac->type >= e1000_i350) dev_spec->eee_disable = false; - } + /* Allow a single clear of the SW semaphore on I210 and newer */ + if (mac->type >= e1000_i210) + dev_spec->clear_semaphore_once = true; /* Set if part includes ASF firmware */ mac->asf_firmware_present = true; @@ -636,6 +641,8 @@ static s32 e1000_get_phy_id_82575(struct e1000_hw *hw) break; case e1000_82580: case e1000_i350: + case e1000_i210: + case e1000_i211: mdic = E1000_READ_REG(hw, E1000_MDICNFG); mdic &= E1000_MDICNFG_PHY_MASK; phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT; @@ -1441,12 +1448,16 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw) switch (hw->phy.type) { case e1000_phy_i210: case e1000_phy_m88: - if (hw->phy.id == I347AT4_E_PHY_ID || - hw->phy.id == M88E1112_E_PHY_ID || - hw->phy.id == M88E1340M_E_PHY_ID) + switch (hw->phy.id) { + case I347AT4_E_PHY_ID: + case M88E1112_E_PHY_ID: + case M88E1340M_E_PHY_ID: ret_val = e1000_copper_link_setup_m88_gen2(hw); - else + break; + default: ret_val = e1000_copper_link_setup_m88(hw); + break; + } break; case e1000_phy_igp_3: ret_val = e1000_copper_link_setup_igp(hw); @@ -2383,6 +2394,9 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw) hw->dev_spec._82575.global_device_reset = false; + /* 82580 does not reliably do global_device_reset due to hw errata */ + if (hw->mac.type == e1000_82580) + global_device_reset = false; /* Get current control state. */ ctrl = E1000_READ_REG(hw, E1000_CTRL); @@ -2709,17 +2723,14 @@ s32 e1000_set_eee_i350(struct e1000_hw *hw) /* enable or disable per user setting */ if (!(hw->dev_spec._82575.eee_disable)) { + u32 eee_su = E1000_READ_REG(hw, E1000_EEE_SU); ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN); eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | E1000_EEER_LPI_FC); - /* keep the LPI clock running before EEE is enabled */ - if (hw->mac.type == e1000_i210 || hw->mac.type == e1000_i211) { - u32 eee_su; - eee_su = E1000_READ_REG(hw, E1000_EEE_SU); - eee_su &= ~E1000_EEE_SU_LPI_CLK_STP; - E1000_WRITE_REG(hw, E1000_EEE_SU, eee_su); - } + /* This bit should not be set in normal operation. */ + if (eee_su & E1000_EEE_SU_LPI_CLK_STP) + DEBUGOUT("LPI Clock Stop Bit should not be set!\n"); } else { ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN); eeer &= ~(E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | diff --git a/kmod/igb/e1000_api.c b/kmod/igb/e1000_api.c index 1c0af57..abc7b99 100644 --- a/kmod/igb/e1000_api.c +++ b/kmod/igb/e1000_api.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/e1000_api.h b/kmod/igb/e1000_api.h index ba9fea5..b330bdb 100644 --- a/kmod/igb/e1000_api.h +++ b/kmod/igb/e1000_api.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/e1000_defines.h b/kmod/igb/e1000_defines.h index dec83a7..0b15738 100644 --- a/kmod/igb/e1000_defines.h +++ b/kmod/igb/e1000_defines.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -1272,6 +1272,7 @@ #define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */ #define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done*/ #define E1000_EECD_FLASH_DETECTED_I210 0x00080000 /* FLASH detected */ +#define E1000_EECD_SEC1VAL_I210 0x02000000 /* Sector One Valid */ #define E1000_FLUDONE_ATTEMPTS 20000 #define E1000_EERD_EEWR_MAX_COUNT 512 /* buffered EEPROM words rw */ #define E1000_I210_FIFO_SEL_RX 0x00 @@ -1296,6 +1297,8 @@ #define NVM_VERSION 0x0005 #define NVM_SERDES_AMPLITUDE 0x0006 /* SERDES output amplitude */ #define NVM_PHY_CLASS_WORD 0x0007 +#define NVM_FUTURE_INIT_WORD1 0x0019 +#define NVM_FUTURE_INIT_WORD2 0x001A #define NVM_ETRACK_WORD 0x0042 #define NVM_COMB_VER_OFF 0x0083 #define NVM_COMB_VER_PTR 0x003d @@ -1319,6 +1322,8 @@ #define NVM_LED_1_CFG 0x001C #define NVM_LED_0_2_CFG 0x001F +#define NVM_COMPAT_VALID_CSUM 0x0001 +#define NVM_FUTURE_INIT_WORD1_VALID_CSUM 0x0040 #define NVM_ETS_CFG 0x003E #define NVM_ETS_LTHRES_DELTA_MASK 0x07C0 #define NVM_ETS_LTHRES_DELTA_SHIFT 6 @@ -1756,7 +1761,7 @@ #define E1000_RXPBS_SIZE_I210_MASK 0x0000003F /* Rx packet buffer size */ #define E1000_TXPB0S_SIZE_I210_MASK 0x0000003F /* Tx packet buffer 0 size */ -/* Proxy Filer Control */ +/* Proxy Filter Control */ #define E1000_PROXYFC_D0 0x00000001 /* Enable offload in D0 */ #define E1000_PROXYFC_EX 0x00000004 /* Directed exact proxy */ #define E1000_PROXYFC_MC 0x00000008 /* Directed MC Proxy */ @@ -1764,7 +1769,7 @@ #define E1000_PROXYFC_ARP_DIRECTED 0x00000020 /* Directed ARP Proxy Ena */ #define E1000_PROXYFC_IPV4 0x00000040 /* Directed IPv4 Enable */ #define E1000_PROXYFC_IPV6 0x00000080 /* Directed IPv6 Enable */ -#define E1000_PROXYFC_NS 0x00000200 /* IPv4 NBRHD Solicitation */ +#define E1000_PROXYFC_NS 0x00000200 /* IPv6 Neighbor Solicitation */ #define E1000_PROXYFC_ARP 0x00000800 /* ARP Request Proxy Ena */ /* Proxy Status */ #define E1000_PROXYS_CLEAR 0xFFFFFFFF /* Clear */ diff --git a/kmod/igb/e1000_hw.h b/kmod/igb/e1000_hw.h index dba8088..f2c2cd7 100644 --- a/kmod/igb/e1000_hw.h +++ b/kmod/igb/e1000_hw.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -739,6 +739,7 @@ struct e1000_dev_spec_82575 { bool global_device_reset; bool eee_disable; bool module_plugged; + bool clear_semaphore_once; u32 mtu; struct sfp_e1000_flags eth_flags; }; diff --git a/kmod/igb/e1000_i210.c b/kmod/igb/e1000_i210.c index 9fd3aca..5762bef 100644 --- a/kmod/igb/e1000_i210.c +++ b/kmod/igb/e1000_i210.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -31,7 +31,6 @@ static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw); static void e1000_release_nvm_i210(struct e1000_hw *hw); static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw); -static void e1000_put_hw_semaphore_i210(struct e1000_hw *hw); static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); static s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw); @@ -103,8 +102,9 @@ s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask) /* * Firmware currently using resource (fwmask) + * or other software thread using resource (swmask) */ - e1000_put_hw_semaphore_i210(hw); + e1000_put_hw_semaphore_generic(hw); msec_delay_irq(5); i++; } @@ -118,7 +118,7 @@ s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask) swfw_sync |= swmask; E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); - e1000_put_hw_semaphore_i210(hw); + e1000_put_hw_semaphore_generic(hw); out: return ret_val; @@ -145,7 +145,7 @@ void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask) swfw_sync &= ~mask; E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); - e1000_put_hw_semaphore_i210(hw); + e1000_put_hw_semaphore_generic(hw); } /** @@ -157,12 +157,44 @@ void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask) static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw) { u32 swsm; - s32 ret_val = E1000_SUCCESS; s32 timeout = hw->nvm.word_size + 1; s32 i = 0; DEBUGFUNC("e1000_get_hw_semaphore_i210"); + /* Get the SW semaphore */ + while (i < timeout) { + swsm = E1000_READ_REG(hw, E1000_SWSM); + if (!(swsm & E1000_SWSM_SMBI)) + break; + + usec_delay(50); + i++; + } + + if (i == timeout) { + /* + * In rare circumstances, the driver may not have released the + * SW semaphore. Clear the semaphore once before giving up. + */ + if (hw->dev_spec._82575.clear_semaphore_once) { + hw->dev_spec._82575.clear_semaphore_once = false; + e1000_put_hw_semaphore_generic(hw); + for (i = 0; i < timeout; i++) { + swsm = E1000_READ_REG(hw, E1000_SWSM); + if (!(swsm & E1000_SWSM_SMBI)) + break; + + usec_delay(50); + } + } + + /* If we do not have the semaphore here, we have to give up. */ + if (i == timeout) { + DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); + return -E1000_ERR_NVM; + } + } /* Get the FW semaphore. */ for (i = 0; i < timeout; i++) { swsm = E1000_READ_REG(hw, E1000_SWSM); @@ -179,31 +211,10 @@ static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw) /* Release semaphores */ e1000_put_hw_semaphore_generic(hw); DEBUGOUT("Driver can't access the NVM\n"); - ret_val = -E1000_ERR_NVM; - goto out; + return -E1000_ERR_NVM; } -out: - return ret_val; -} - -/** - * e1000_put_hw_semaphore_i210 - Release hardware semaphore - * @hw: pointer to the HW structure - * - * Release hardware semaphore used to access the PHY or NVM - **/ -static void e1000_put_hw_semaphore_i210(struct e1000_hw *hw) -{ - u32 swsm; - - DEBUGFUNC("e1000_put_hw_semaphore_i210"); - - swsm = E1000_READ_REG(hw, E1000_SWSM); - - swsm &= ~E1000_SWSM_SWESMBI; - - E1000_WRITE_REG(hw, E1000_SWSM, swsm); + return E1000_SUCCESS; } /** diff --git a/kmod/igb/e1000_i210.h b/kmod/igb/e1000_i210.h index 83f0668..906fab8 100644 --- a/kmod/igb/e1000_i210.h +++ b/kmod/igb/e1000_i210.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -79,7 +79,7 @@ enum E1000_INVM_STRUCTURE_TYPE { (ID_LED_DEF1_DEF2 << 4) | \ (ID_LED_DEF1_DEF2)) -/* NVM offset defaults for Pearsonville device */ +/* NVM offset defaults for I211 devices */ #define NVM_INIT_CTRL_2_DEFAULT_I211 0X7243 #define NVM_INIT_CTRL_4_DEFAULT_I211 0x00C1 #define NVM_LED_1_CFG_DEFAULT_I211 0x0184 diff --git a/kmod/igb/e1000_mac.c b/kmod/igb/e1000_mac.c index 7b03600..be28caa 100644 --- a/kmod/igb/e1000_mac.c +++ b/kmod/igb/e1000_mac.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/e1000_mac.h b/kmod/igb/e1000_mac.h index 385b125..ae23d0e 100644 --- a/kmod/igb/e1000_mac.h +++ b/kmod/igb/e1000_mac.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/e1000_manage.c b/kmod/igb/e1000_manage.c index f61c176..243964c 100644 --- a/kmod/igb/e1000_manage.c +++ b/kmod/igb/e1000_manage.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/e1000_manage.h b/kmod/igb/e1000_manage.h index 31e4e3d..c94b218 100644 --- a/kmod/igb/e1000_manage.h +++ b/kmod/igb/e1000_manage.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/e1000_mbx.c b/kmod/igb/e1000_mbx.c index ae57bbc..34c9307 100644 --- a/kmod/igb/e1000_mbx.c +++ b/kmod/igb/e1000_mbx.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/e1000_mbx.h b/kmod/igb/e1000_mbx.h index d686e16..bbf838c 100644 --- a/kmod/igb/e1000_mbx.h +++ b/kmod/igb/e1000_mbx.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/e1000_nvm.c b/kmod/igb/e1000_nvm.c index ef28069..577eeaf 100644 --- a/kmod/igb/e1000_nvm.c +++ b/kmod/igb/e1000_nvm.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -506,7 +506,7 @@ s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; - s32 ret_val; + s32 ret_val = -E1000_ERR_NVM; u16 widx = 0; DEBUGFUNC("e1000_write_nvm_spi"); @@ -520,17 +520,18 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) DEBUGOUT("nvm parameter(s) out of bounds\n"); return -E1000_ERR_NVM; } + while (widx < words) { + u8 write_opcode = NVM_WRITE_OPCODE_SPI; ret_val = nvm->ops.acquire(hw); if (ret_val) return ret_val; - while (widx < words) { - u8 write_opcode = NVM_WRITE_OPCODE_SPI; - ret_val = e1000_ready_nvm_eeprom(hw); - if (ret_val) - goto release; + if (ret_val) { + nvm->ops.release(hw); + return ret_val; + } e1000_standby_nvm(hw); @@ -564,11 +565,10 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) break; } } - } - msec_delay(10); -release: - nvm->ops.release(hw); + msec_delay(10); + nvm->ops.release(hw); + } return ret_val; } diff --git a/kmod/igb/e1000_nvm.h b/kmod/igb/e1000_nvm.h index 93ab8b7..02120eb 100644 --- a/kmod/igb/e1000_nvm.h +++ b/kmod/igb/e1000_nvm.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/e1000_osdep.h b/kmod/igb/e1000_osdep.h index f819b6f..c532498 100644 --- a/kmod/igb/e1000_osdep.h +++ b/kmod/igb/e1000_osdep.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/e1000_phy.c b/kmod/igb/e1000_phy.c index 942b3c2..f2a7d3f 100644 --- a/kmod/igb/e1000_phy.c +++ b/kmod/igb/e1000_phy.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/e1000_phy.h b/kmod/igb/e1000_phy.h index 9e7b84a..fd41b3d 100644 --- a/kmod/igb/e1000_phy.h +++ b/kmod/igb/e1000_phy.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/igb.h b/kmod/igb/igb.h index 6826ba5..16f5b8d 100644 --- a/kmod/igb/igb.h +++ b/kmod/igb/igb.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -84,11 +84,11 @@ struct igb_user_page { printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \ __FUNCTION__ , ## args)) -#ifdef CONFIG_IGB_PTP +#ifdef HAVE_PTP_1588_CLOCK #include #include #include -#endif /* CONFIG_IGB_PTP */ +#endif /* HAVE_PTP_1588_CLOCK */ /* Interrupt defines */ #define IGB_START_ITR 648 /* ~6000 ints/sec */ #define IGB_4K_ITR 980 @@ -534,8 +534,6 @@ struct igb_adapter { u32 eims_other; /* to not mess up cache alignment, always add to the bottom */ - bool wol_supported; - u32 *config_space; u16 tx_ring_count; u16 rx_ring_count; @@ -576,7 +574,7 @@ struct igb_adapter { #endif /* IGB_SYSFS */ u32 etrack_id; -#ifdef CONFIG_IGB_PTP +#ifdef HAVE_PTP_1588_CLOCK struct ptp_clock *ptp_clock; struct ptp_clock_info ptp_caps; struct delayed_work ptp_overflow_work; @@ -585,7 +583,7 @@ struct igb_adapter { spinlock_t tmreg_lock; struct cyclecounter cc; struct timecounter tc; -#endif /* CONFIG_IGB_PTP */ +#endif /* HAVE_PTP_1588_CLOCK */ }; #ifdef CONFIG_IGB_VMDQ_NETDEV @@ -615,6 +613,9 @@ struct igb_vmdq_adapter { #define IGB_FLAG_DMAC (1 << 7) #define IGB_FLAG_DETECT_BAD_DMA (1 << 8) #define IGB_FLAG_PTP (1 << 9) +#define IGB_FLAG_RSS_FIELD_IPV4_UDP (1 << 10) +#define IGB_FLAG_RSS_FIELD_IPV6_UDP (1 << 11) +#define IGB_FLAG_WOL_SUPPORTED (1 << 12) #define IGB_MIN_TXPBSIZE 20408 #define IGB_TX_BUF_4096 4096 @@ -705,7 +706,7 @@ extern bool igb_has_link(struct igb_adapter *adapter); extern void igb_set_ethtool_ops(struct net_device *); extern void igb_check_options(struct igb_adapter *); extern void igb_power_up_link(struct igb_adapter *); -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK extern void igb_ptp_init(struct igb_adapter *adapter); extern void igb_ptp_stop(struct igb_adapter *adapter); extern void igb_ptp_reset(struct igb_adapter *adapter); @@ -716,7 +717,7 @@ extern void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb); extern int igb_ptp_hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); -#endif +#endif /* HAVE_PTP_1588_CLOCK */ #ifdef ETHTOOL_OPS_COMPAT extern int ethtool_ioctl(struct ifreq *); #endif @@ -730,6 +731,7 @@ extern void igb_enable_vlan_tags(struct igb_adapter *adapter); #ifndef HAVE_VLAN_RX_REGISTER extern void igb_vlan_mode(struct net_device *, u32); #endif +#define E1000_PCS_CFG_IGN_SD 1 #ifdef IGB_SYSFS void igb_sysfs_exit(struct igb_adapter *adapter); diff --git a/kmod/igb/igb_ethtool.c b/kmod/igb/igb_ethtool.c index 7b851fa..6a1be99 100644 --- a/kmod/igb/igb_ethtool.c +++ b/kmod/igb/igb_ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -194,10 +194,16 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ecmd->advertising = (ADVERTISED_FIBRE | ADVERTISED_Autoneg | ADVERTISED_Pause); - if (adapter->link_speed == SPEED_100) - ecmd->advertising = ADVERTISED_100baseT_Full; - else + switch (adapter->link_speed) { + case SPEED_1000: ecmd->advertising = ADVERTISED_1000baseT_Full; + break; + case SPEED_100: + ecmd->advertising = ADVERTISED_100baseT_Full; + break; + default: + break; + } ecmd->port = PORT_FIBRE; ecmd->transceiver = XCVR_EXTERNAL; @@ -289,12 +295,18 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) if (hw->phy.media_type == e1000_media_type_fiber) { hw->phy.autoneg_advertised = ADVERTISED_FIBRE | ADVERTISED_Autoneg; - if (adapter->link_speed == SPEED_1000) + switch (adapter->link_speed) { + case SPEED_1000: hw->phy.autoneg_advertised = ADVERTISED_1000baseT_Full; - else + break; + case SPEED_100: hw->phy.autoneg_advertised = ADVERTISED_100baseT_Full; + break; + default: + break; + } } else { hw->phy.autoneg_advertised = ecmd->advertising | ADVERTISED_TP | @@ -1408,6 +1420,19 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter) reg &= ~E1000_CONNSW_ENRGSRC; E1000_WRITE_REG(hw, E1000_CONNSW, reg); + /* Unset sigdetect for SERDES loopback on + * 82580 and i350 + */ + switch (hw->mac.type) { + case e1000_82580: + case e1000_i350: + reg = E1000_READ_REG(hw, E1000_PCS_CFG0); + reg |= E1000_PCS_CFG_IGN_SD; + E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg); + break; + default: + break; + } /* Set PCS register for forced speed */ reg = E1000_READ_REG(hw, E1000_PCS_LCTL); reg &= ~E1000_PCS_LCTL_AN_ENABLE; /* Disable Autoneg*/ @@ -1762,7 +1787,7 @@ static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) WAKE_PHY; wol->wolopts = 0; - if (!adapter->wol_supported || !device_can_wakeup(&adapter->pdev->dev)) + if (!(adapter->flags & IGB_FLAG_WOL_SUPPORTED)) return; /* apply any specific unsupported masks here */ @@ -1790,7 +1815,7 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE)) return -EOPNOTSUPP; - if (!adapter->wol_supported || !device_can_wakeup(&adapter->pdev->dev)) + if (!(adapter->flags & IGB_FLAG_WOL_SUPPORTED)) return wol->wolopts ? -EOPNOTSUPP : 0; /* these settings will always override what we currently have */ adapter->wol = 0; @@ -2068,7 +2093,7 @@ static int igb_get_ts_info(struct net_device *dev, struct igb_adapter *adapter = netdev_priv(dev); switch (adapter->hw.mac.type) { -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK case e1000_82576: case e1000_82580: case e1000_i350: @@ -2104,7 +2129,7 @@ static int igb_get_ts_info(struct net_device *dev, (1 << HWTSTAMP_FILTER_PTP_V2_EVENT); return 0; -#endif /* CONFIG_PTP */ +#endif /* HAVE_PTP_1588_CLOCK */ default: return -EOPNOTSUPP; } @@ -2346,7 +2371,7 @@ static int igb_get_eee(struct net_device *netdev, struct ethtool_eee *edata) /* EEE status on negotiated link */ if (ipcnfg & E1000_IPCNFG_EEE_1G_AN) - edata->advertised |= ADVERTISED_1000baseT_Full; + edata->advertised = ADVERTISED_1000baseT_Full; if (ipcnfg & E1000_IPCNFG_EEE_100M_AN) edata->advertised |= ADVERTISED_100baseT_Full; @@ -2367,6 +2392,7 @@ static int igb_get_eee(struct net_device *netdev, struct ethtool_eee *edata) edata->eee_enabled = false; edata->eee_active = false; edata->tx_lpi_enabled = false; + edata->advertised &= ~edata->advertised; } return 0; @@ -2379,26 +2405,239 @@ static int igb_set_eee(struct net_device *netdev, { struct igb_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; + struct ethtool_eee eee_curr; + s32 ret_val; if ((hw->mac.type < e1000_i350) || (hw->phy.media_type != e1000_media_type_copper)) return -EOPNOTSUPP; - while (test_and_set_bit(__IGB_RESETTING, &adapter->state)) - usleep_range(1000, 2000); + ret_val = igb_get_eee(netdev, &eee_curr); + if (ret_val) + return ret_val; - if (!edata->eee_enabled) { - hw->dev_spec._82575.eee_disable = true; - e1000_set_eee_i350(hw); - } else if (edata->eee_enabled) { - hw->dev_spec._82575.eee_disable = false; + if (eee_curr.eee_enabled) { + if (eee_curr.tx_lpi_enabled != edata->tx_lpi_enabled) { + dev_err(pci_dev_to_dev(adapter->pdev), + "Setting EEE tx-lpi is not supported\n"); + return -EINVAL; + } + + /* Tx LPI time is not implemented currently */ + if (edata->tx_lpi_timer) { + dev_err(pci_dev_to_dev(adapter->pdev), + "Setting EEE Tx LPI timer is not supported\n"); + return -EINVAL; + } + + if (eee_curr.advertised != edata->advertised) { + dev_err(pci_dev_to_dev(adapter->pdev), + "Setting EEE Advertisement is not supported\n"); + return -EINVAL; + } + + } else if (!edata->eee_enabled) { + dev_err(pci_dev_to_dev(adapter->pdev), + "Setting EEE options is not supported with EEE disabled\n"); + return -EINVAL; + } + + if (hw->dev_spec._82575.eee_disable != !edata->eee_enabled) { + hw->dev_spec._82575.eee_disable = !edata->eee_enabled; e1000_set_eee_i350(hw); + /* reset link */ + if (!netif_running(netdev)) + igb_reset(adapter); } - clear_bit(__IGB_RESETTING, &adapter->state); return 0; } #endif /* ETHTOOL_SEEE */ +#ifdef ETHTOOL_GRXRINGS +static int igb_get_rss_hash_opts(struct igb_adapter *adapter, + struct ethtool_rxnfc *cmd) +{ + cmd->data = 0; + + /* Report default options for RSS on igb */ + switch (cmd->flow_type) { + case TCP_V4_FLOW: + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + case UDP_V4_FLOW: + if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV4_UDP) + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + case SCTP_V4_FLOW: + case AH_ESP_V4_FLOW: + case AH_V4_FLOW: + case ESP_V4_FLOW: + case IPV4_FLOW: + cmd->data |= RXH_IP_SRC | RXH_IP_DST; + break; + case TCP_V6_FLOW: + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + case UDP_V6_FLOW: + if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV6_UDP) + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + case SCTP_V6_FLOW: + case AH_ESP_V6_FLOW: + case AH_V6_FLOW: + case ESP_V6_FLOW: + case IPV6_FLOW: + cmd->data |= RXH_IP_SRC | RXH_IP_DST; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int igb_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, +#ifdef HAVE_ETHTOOL_GET_RXNFC_VOID_RULE_LOCS + void *rule_locs) +#else + u32 *rule_locs) +#endif +{ + struct igb_adapter *adapter = netdev_priv(dev); + int ret = -EOPNOTSUPP; + + switch (cmd->cmd) { + case ETHTOOL_GRXRINGS: + cmd->data = adapter->num_rx_queues; + ret = 0; + break; + case ETHTOOL_GRXFH: + ret = igb_get_rss_hash_opts(adapter, cmd); + break; + default: + break; + } + + return ret; +} + +#define UDP_RSS_FLAGS (IGB_FLAG_RSS_FIELD_IPV4_UDP | \ + IGB_FLAG_RSS_FIELD_IPV6_UDP) +static int igb_set_rss_hash_opt(struct igb_adapter *adapter, + struct ethtool_rxnfc *nfc) +{ + u32 flags = adapter->flags; + + /* + * RSS does not support anything other than hashing + * to queues on src and dst IPs and ports + */ + if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3)) + return -EINVAL; + + switch (nfc->flow_type) { + case TCP_V4_FLOW: + case TCP_V6_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST) || + !(nfc->data & RXH_L4_B_0_1) || + !(nfc->data & RXH_L4_B_2_3)) + return -EINVAL; + break; + case UDP_V4_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST)) + return -EINVAL; + switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { + case 0: + flags &= ~IGB_FLAG_RSS_FIELD_IPV4_UDP; + break; + case (RXH_L4_B_0_1 | RXH_L4_B_2_3): + flags |= IGB_FLAG_RSS_FIELD_IPV4_UDP; + break; + default: + return -EINVAL; + } + break; + case UDP_V6_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST)) + return -EINVAL; + switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { + case 0: + flags &= ~IGB_FLAG_RSS_FIELD_IPV6_UDP; + break; + case (RXH_L4_B_0_1 | RXH_L4_B_2_3): + flags |= IGB_FLAG_RSS_FIELD_IPV6_UDP; + break; + default: + return -EINVAL; + } + break; + case AH_ESP_V4_FLOW: + case AH_V4_FLOW: + case ESP_V4_FLOW: + case SCTP_V4_FLOW: + case AH_ESP_V6_FLOW: + case AH_V6_FLOW: + case ESP_V6_FLOW: + case SCTP_V6_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST) || + (nfc->data & RXH_L4_B_0_1) || + (nfc->data & RXH_L4_B_2_3)) + return -EINVAL; + break; + default: + return -EINVAL; + } + + /* if we changed something we need to update flags */ + if (flags != adapter->flags) { + struct e1000_hw *hw = &adapter->hw; + u32 mrqc = E1000_READ_REG(hw, E1000_MRQC); + + if ((flags & UDP_RSS_FLAGS) && + !(adapter->flags & UDP_RSS_FLAGS)) + DPRINTK(DRV, WARNING, + "enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n"); + + adapter->flags = flags; + + /* Perform hash on these packet types */ + mrqc |= E1000_MRQC_RSS_FIELD_IPV4 | + E1000_MRQC_RSS_FIELD_IPV4_TCP | + E1000_MRQC_RSS_FIELD_IPV6 | + E1000_MRQC_RSS_FIELD_IPV6_TCP; + + mrqc &= ~(E1000_MRQC_RSS_FIELD_IPV4_UDP | + E1000_MRQC_RSS_FIELD_IPV6_UDP); + + if (flags & IGB_FLAG_RSS_FIELD_IPV4_UDP) + mrqc |= E1000_MRQC_RSS_FIELD_IPV4_UDP; + + if (flags & IGB_FLAG_RSS_FIELD_IPV6_UDP) + mrqc |= E1000_MRQC_RSS_FIELD_IPV6_UDP; + + E1000_WRITE_REG(hw, E1000_MRQC, mrqc); + } + + return 0; +} + +static int igb_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) +{ + struct igb_adapter *adapter = netdev_priv(dev); + int ret = -EOPNOTSUPP; + + switch (cmd->cmd) { + case ETHTOOL_SRXFH: + ret = igb_set_rss_hash_opt(adapter, cmd); + break; + default: + break; + } + + return ret; +} +#endif /* ETHTOOL_GRXRINGS */ static const struct ethtool_ops igb_ethtool_ops = { .get_settings = igb_get_settings, @@ -2421,11 +2660,13 @@ static const struct ethtool_ops igb_ethtool_ops = { .set_pauseparam = igb_set_pauseparam, .self_test = igb_diag_test, .get_strings = igb_get_strings, +#ifndef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT #ifdef HAVE_ETHTOOL_SET_PHYS_ID .set_phys_id = igb_set_phys_id, #else .phys_id = igb_phys_id, #endif /* HAVE_ETHTOOL_SET_PHYS_ID */ +#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */ #ifdef HAVE_ETHTOOL_GET_SSET_COUNT .get_sset_count = igb_get_sset_count, #else @@ -2438,9 +2679,11 @@ static const struct ethtool_ops igb_ethtool_ops = { #endif .get_coalesce = igb_get_coalesce, .set_coalesce = igb_set_coalesce, +#ifndef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT #ifdef HAVE_ETHTOOL_GET_TS_INFO .get_ts_info = igb_get_ts_info, #endif /* HAVE_ETHTOOL_GET_TS_INFO */ +#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */ #ifdef CONFIG_PM_RUNTIME .begin = igb_ethtool_begin, .complete = igb_ethtool_complete, @@ -2465,18 +2708,40 @@ static const struct ethtool_ops igb_ethtool_ops = { .get_advcoal = igb_get_adv_coal, .set_advcoal = igb_set_dmac_coal, #endif /* ETHTOOL_GADV_COAL */ +#ifndef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT #ifdef ETHTOOL_GEEE .get_eee = igb_get_eee, #endif #ifdef ETHTOOL_SEEE .set_eee = igb_set_eee, #endif +#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */ +#ifdef ETHTOOL_GRXRINGS + .get_rxnfc = igb_get_rxnfc, + .set_rxnfc = igb_set_rxnfc, +#endif +}; + +#ifdef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT +static const struct ethtool_ops_ext igb_ethtool_ops_ext = { + .size = sizeof(struct ethtool_ops_ext), + .get_ts_info = igb_get_ts_info, + .set_phys_id = igb_set_phys_id, + .get_eee = igb_get_eee, + .set_eee = igb_set_eee, }; void igb_set_ethtool_ops(struct net_device *netdev) { + SET_ETHTOOL_OPS(netdev, &igb_ethtool_ops); + set_ethtool_ops_ext(netdev, &igb_ethtool_ops_ext); +} +#else +void igb_set_ethtool_ops(struct net_device *netdev) +{ /* have to "undeclare" const on this struct to remove warnings */ SET_ETHTOOL_OPS(netdev, (struct ethtool_ops *)&igb_ethtool_ops); } +#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */ #endif /* SIOCETHTOOL */ diff --git a/kmod/igb/igb_main.c b/kmod/igb/igb_main.c index 9ccf640..3167a15 100644 --- a/kmod/igb/igb_main.c +++ b/kmod/igb/igb_main.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -24,7 +24,6 @@ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ - /* * NOTE: This is an AVB-customed version of the standard Intel igb * driver. This driver enables (1) transmit and (1) receive queue @@ -82,8 +81,8 @@ #define VERSION_SUFFIX "_AVB" #define MAJ 4 -#define MIN 0 -#define BUILD 17 +#define MIN 1 +#define BUILD 2.1 #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." __stringify(BUILD) VERSION_SUFFIX DRV_DEBUG DRV_HW_PERF char igb_driver_name[] = "igb_avb"; @@ -181,7 +180,7 @@ static int igb_find_enabled_vfs(struct igb_adapter *adapter); #endif static int igb_init_avb( struct e1000_hw *hw ); -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector, union e1000_adv_rx_desc *rx_desc, struct sk_buff *skb); #endif @@ -1789,10 +1788,10 @@ void igb_reset(struct igb_adapter *adapter) /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ E1000_WRITE_REG(hw, E1000_VET, ETHERNET_IEEE_VLAN_TYPE); -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK /* Re-enable PTP, where applicable. */ igb_ptp_reset(adapter); -#endif /* CONFIG_IGB_PTP */ +#endif /* HAVE_PTP_1588_CLOCK */ e1000_get_phy_info(hw); } @@ -2274,9 +2273,9 @@ static int __devinit igb_probe(struct pci_dev *pdev, e1000_validate_mdi_setting(hw); - /* Initial Wake on LAN setting If APM wake is enabled in the EEPROM, - * enable the ACPI Magic Packet filter - */ + /* By default, support wake on port A */ + if (hw->bus.func == 0) + adapter->flags |= IGB_FLAG_WOL_SUPPORTED; /* Check the NVM for wake support for non-port A ports */ if (hw->mac.type >= e1000_82580) @@ -2287,14 +2286,14 @@ static int __devinit igb_probe(struct pci_dev *pdev, e1000_read_nvm(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data); if (eeprom_data & IGB_EEPROM_APME) - adapter->wol_supported = true; + adapter->flags |= IGB_FLAG_WOL_SUPPORTED; /* now that we have the eeprom settings, apply the special cases where * the eeprom may be wrong or the board simply won't support wake on * lan on a particular port */ switch (pdev->device) { case E1000_DEV_ID_82575GB_QUAD_COPPER: - adapter->wol_supported = false; + adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED; break; case E1000_DEV_ID_82575EB_FIBER_SERDES: case E1000_DEV_ID_82576_FIBER: @@ -2302,13 +2301,13 @@ static int __devinit igb_probe(struct pci_dev *pdev, /* Wake events only supported on port A for dual fiber * regardless of eeprom setting */ if (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_FUNC_1) - adapter->wol_supported = false; + adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED; break; case E1000_DEV_ID_82576_QUAD_COPPER: case E1000_DEV_ID_82576_QUAD_COPPER_ET2: /* if quad port adapter, disable WoL on all but port A */ if (global_quad_port_a != 0) - adapter->wol_supported = false; + adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED; else adapter->flags |= IGB_FLAG_QUAD_PORT_A; /* Reset for multiple quad port adapters */ @@ -2316,25 +2315,25 @@ static int __devinit igb_probe(struct pci_dev *pdev, global_quad_port_a = 0; break; default: - /* For all other devices, support wake on port A */ - if (hw->bus.func == 0) - adapter->wol_supported = true; + /* If the device can't wake, don't set software support */ + if (!device_can_wakeup(&adapter->pdev->dev)) + adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED; break; } /* initialize the wol settings based on the eeprom settings */ - if (adapter->wol_supported) + if (adapter->flags & IGB_FLAG_WOL_SUPPORTED) adapter->wol |= E1000_WUFC_MAG; /* Some vendors want WoL disabled by default, but still supported */ if ((hw->mac.type == e1000_i350) && (pdev->subsystem_vendor == PCI_VENDOR_ID_HP)) { - adapter->wol_supported = true; + adapter->flags |= IGB_FLAG_WOL_SUPPORTED; adapter->wol = 0; } device_set_wakeup_enable(pci_dev_to_dev(adapter->pdev), - adapter->wol_supported); + adapter->flags & IGB_FLAG_WOL_SUPPORTED); /* reset the hardware with the new settings */ igb_reset(adapter); @@ -2364,10 +2363,10 @@ static int __devinit igb_probe(struct pci_dev *pdev, } #endif -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK /* do hw tstamp init after resetting */ igb_ptp_init(adapter); -#endif +#endif /* HAVE_PTP_1588_CLOCK */ dev_info(pci_dev_to_dev(pdev), "Intel(R) Gigabit Ethernet Network Connection\n"); /* print bus type/speed/width info */ dev_info(pci_dev_to_dev(pdev), "%s: (PCIe:%s:%s) ", @@ -2391,18 +2390,20 @@ static int __devinit igb_probe(struct pci_dev *pdev, /* Initialize the thermal sensor on i350 devices. */ - if (hw->mac.type == e1000_i350 && hw->bus.func == 0) { - u16 ets_word; + if (hw->mac.type == e1000_i350) { + if (hw->bus.func == 0) { + u16 ets_word; - /* - * Read the NVM to determine if this i350 device supports an - * external thermal sensor. - */ - e1000_read_nvm(hw, NVM_ETS_CFG, 1, &ets_word); - if (ets_word != 0x0000 && ets_word != 0xFFFF) - adapter->ets = true; - else - adapter->ets = false; + /* + * Read the NVM to determine if this i350 device + * supports an external thermal sensor. + */ + e1000_read_nvm(hw, NVM_ETS_CFG, 1, &ets_word); + if (ets_word != 0x0000 && ets_word != 0xFFFF) + adapter->ets = true; + else + adapter->ets = false; + } #ifdef IGB_SYSFS igb_sysfs_init(adapter); #else @@ -2484,9 +2485,9 @@ static void __devexit igb_remove(struct pci_dev *pdev) struct e1000_hw *hw = &adapter->hw; pm_runtime_get_noresume(&pdev->dev); -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK igb_ptp_stop(adapter); -#endif /* CONFIG_IGB_PTP */ +#endif /* HAVE_PTP_1588_CLOCK */ /* flush_scheduled work may reschedule our watchdog task, so * explicitly disable watchdog tasks from being rescheduled */ @@ -3079,15 +3080,18 @@ static void igb_setup_mrqc(struct igb_adapter *adapter) igb_vmm_control(adapter); /* - * Generate RSS hash based on TCP port numbers and/or - * IPv4/v6 src and dst addresses since UDP cannot be - * hashed reliably due to IP fragmentation + * Generate RSS hash based on packet types, TCP/UDP + * port numbers and/or IPv4/v6 src and dst addresses */ mrqc |= E1000_MRQC_RSS_FIELD_IPV4 | E1000_MRQC_RSS_FIELD_IPV4_TCP | E1000_MRQC_RSS_FIELD_IPV6 | E1000_MRQC_RSS_FIELD_IPV6_TCP | E1000_MRQC_RSS_FIELD_IPV6_TCP_EX; + if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV4_UDP) + mrqc |= E1000_MRQC_RSS_FIELD_IPV4_UDP; + if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV6_UDP) + mrqc |= E1000_MRQC_RSS_FIELD_IPV6_UDP; E1000_WRITE_REG(hw, E1000_MRQC, mrqc); } @@ -3297,10 +3301,10 @@ void igb_configure_rx_ring(struct igb_adapter *adapter, E1000_SRRCTL_BSIZEPKT_SHIFT; srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF; #endif /* CONFIG_IGB_DISABLE_PACKET_SPLIT */ -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK if (hw->mac.type >= e1000_82580) srrctl |= E1000_SRRCTL_TIMESTAMP; -#endif +#endif /* HAVE_PTP_1588_CLOCK */ /* * We should set the drop enable bit if: * SR-IOV is enabled @@ -3968,6 +3972,8 @@ static void igb_watchdog_task(struct work_struct *work) case SPEED_100: /* maybe add some timeout factor ? */ break; + default: + break; } netif_carrier_on(netdev); @@ -4035,7 +4041,7 @@ static void igb_watchdog_task(struct work_struct *work) igb_update_stats(adapter); for (i = 0; i < adapter->num_tx_queues; i++) { - struct igb_ring *tx_ring = adapter->tx_ring[3-i]; /* I210 rebase */ + struct igb_ring *tx_ring = adapter->tx_ring[3-i]; /* I210 rebase */ if (!netif_carrier_ok(netdev)) { /* We've lost link, so the controller stops DMA, * but we've got queued Tx work that's never going @@ -4518,11 +4524,11 @@ static __le32 igb_tx_cmd_type(u32 tx_flags) if (tx_flags & IGB_TX_FLAGS_VLAN) cmd_type |= cpu_to_le32(E1000_ADVTXD_DCMD_VLE); -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK /* set timestamp bit if present */ if (unlikely(tx_flags & IGB_TX_FLAGS_TSTAMP)) cmd_type |= cpu_to_le32(E1000_ADVTXD_MAC_TSTAMP); -#endif /* CONFIG_IGB_PTP */ +#endif /* HAVE_PTP_1588_CLOCK */ /* set segmentation bits for TSO */ if (tx_flags & IGB_TX_FLAGS_TSO) @@ -4741,9 +4747,9 @@ static inline int igb_maybe_stop_tx(struct igb_ring *tx_ring, const u16 size) netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, struct igb_ring *tx_ring) { -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK struct igb_adapter *adapter = netdev_priv(tx_ring->netdev); -#endif /* CONFIG_PTP */ +#endif /* HAVE_PTP_1588_CLOCK */ struct igb_tx_buffer *first; int tso; u32 tx_flags = 0; @@ -4766,7 +4772,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, first->bytecount = skb->len; first->gso_segs = 1; -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && !(adapter->ptp_tx_skb))) { skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; @@ -4776,7 +4782,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, if (adapter->hw.mac.type == e1000_82576) schedule_work(&adapter->ptp_tx_work); } -#endif +#endif /* HAVE_PTP_1588_CLOCK */ if (vlan_tx_tag_present(skb)) { tx_flags |= IGB_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT); @@ -5216,7 +5222,7 @@ static irqreturn_t igb_msix_other(int irq, void *data) mod_timer(&adapter->watchdog_timer, jiffies + 1); } -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK if (icr & E1000_ICR_TS) { u32 tsicr = E1000_READ_REG(hw, E1000_TSICR); @@ -5227,7 +5233,7 @@ static irqreturn_t igb_msix_other(int irq, void *data) schedule_work(&adapter->ptp_tx_work); } } -#endif /* CONFIG_PTP */ +#endif /* HAVE_PTP_1588_CLOCK */ /* Check for MDD event */ if (icr & E1000_ICR_MDDET) igb_process_mdd_event(adapter); @@ -6109,7 +6115,7 @@ static irqreturn_t igb_intr_msi(int irq, void *data) mod_timer(&adapter->watchdog_timer, jiffies + 1); } -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK if (icr & E1000_ICR_TS) { u32 tsicr = E1000_READ_REG(hw, E1000_TSICR); @@ -6120,7 +6126,7 @@ static irqreturn_t igb_intr_msi(int irq, void *data) schedule_work(&adapter->ptp_tx_work); } } -#endif /* CONFIG_IGB_PTP */ +#endif /* HAVE_PTP_1588_CLOCK */ napi_schedule(&q_vector->napi); @@ -6163,7 +6169,7 @@ static irqreturn_t igb_intr(int irq, void *data) mod_timer(&adapter->watchdog_timer, jiffies + 1); } -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK if (icr & E1000_ICR_TS) { u32 tsicr = E1000_READ_REG(hw, E1000_TSICR); @@ -6174,7 +6180,7 @@ static irqreturn_t igb_intr(int irq, void *data) schedule_work(&adapter->ptp_tx_work); } } -#endif /* CONFIG_PTP */ +#endif /* HAVE_PTP_1588_CLOCK */ napi_schedule(&q_vector->napi); @@ -7079,9 +7085,9 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget) goto next_desc; } -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK igb_ptp_rx_hwtstamp(q_vector, rx_desc, skb); -#endif +#endif /* HAVE_PTP_1588_CLOCK */ #ifdef NETIF_F_RXHASH igb_rx_hash(rx_ring, rx_desc, skb); @@ -7329,10 +7335,10 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) case SIOCSMIIREG: return igb_mii_ioctl(netdev, ifr, cmd); #endif -#ifdef CONFIG_PTP +#ifdef HAVE_PTP_1588_CLOCK case SIOCSHWTSTAMP: return igb_ptp_hwtstamp_ioctl(netdev, ifr, cmd); -#endif /* CONFIG_IGB_PTP */ +#endif /* HAVE_PTP_1588_CLOCK */ #ifdef ETHTOOL_OPS_COMPAT case SIOCETHTOOL: return ethtool_ioctl(ifr); @@ -7545,15 +7551,20 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx) mac->autoneg = 0; /* - * Fiber NIC's only allow 1000 gbps Full duplex + * SerDes device's only allow 2.5/1000 gbps Full duplex * and 100Mbps Full duplex for 100baseFx sfp */ - if (adapter->hw.phy.media_type == e1000_media_type_internal_serdes) - if (spddplx != (SPEED_1000 + DUPLEX_FULL) || - spddplx != (SPEED_100 + DUPLEX_FULL)) { + if (adapter->hw.phy.media_type == e1000_media_type_internal_serdes) { + switch (spddplx) { + case SPEED_10 + DUPLEX_HALF: + case SPEED_10 + DUPLEX_FULL: + case SPEED_100 + DUPLEX_HALF: dev_err(pci_dev_to_dev(pdev), "Unsupported Speed/Duplex configuration\n"); return -EINVAL; + default: + break; + } } switch (spddplx) { @@ -7878,7 +7889,7 @@ static pci_ers_result_t igb_io_error_detected(struct pci_dev *pdev, goto skip_bad_vf_detection; bdev = pdev->bus->self; - while (bdev && (bdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT)) + while (bdev && (pci_pcie_type(bdev) != PCI_EXP_TYPE_ROOT_PORT)) bdev = bdev->bus->self; if (!bdev) diff --git a/kmod/igb/igb_param.c b/kmod/igb/igb_param.c index 39853cb..4e87d7e 100644 --- a/kmod/igb/igb_param.c +++ b/kmod/igb/igb_param.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -676,8 +676,8 @@ void __devinit igb_check_options(struct igb_adapter *adapter) struct igb_option opt = { .type = enable_option, .name = "EEE Support", - .err = "defaulting to Enabled", - .def = OPTION_ENABLED + .err = "defaulting to Disabled", + .def = OPTION_DISABLED }; #ifdef module_param_array if (num_EEE > bd) { diff --git a/kmod/igb/igb_procfs.c b/kmod/igb/igb_procfs.c index 33b708c..2e96909 100644 --- a/kmod/igb/igb_procfs.c +++ b/kmod/igb/igb_procfs.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/igb_ptp.c b/kmod/igb/igb_ptp.c index 3f96846..8686b42 100644 --- a/kmod/igb/igb_ptp.c +++ b/kmod/igb/igb_ptp.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -32,7 +32,7 @@ #include "igb.h" -#ifdef CONFIG_IGB_PTP +#ifdef HAVE_PTP_1588_CLOCK #include #include #include @@ -762,7 +762,13 @@ void igb_ptp_init(struct igb_adapter *adapter) E1000_WRITE_REG(hw,E1000_IMS, E1000_IMS_TS); } - adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) + adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps, + &adapter->pdev->dev); +#else + adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps); +#endif + if (IS_ERR(adapter->ptp_clock)) { adapter->ptp_clock = NULL; dev_err(&adapter->pdev->dev, "ptp_clock_register failed\n"); @@ -847,4 +853,4 @@ void igb_ptp_reset(struct igb_adapter *adapter) ktime_to_ns(ktime_get_real())); } } -#endif /* CONFIG_IGB_PTP */ +#endif /* HAVE_PTP_1588_CLOCK */ diff --git a/kmod/igb/igb_regtest.h b/kmod/igb/igb_regtest.h index 55fad1d..a6761db 100644 --- a/kmod/igb/igb_regtest.h +++ b/kmod/igb/igb_regtest.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/igb_sysfs.c b/kmod/igb/igb_sysfs.c index c7fe788..2725892 100644 --- a/kmod/igb/igb_sysfs.c +++ b/kmod/igb/igb_sysfs.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -58,14 +58,12 @@ static struct net_device_stats *sysfs_get_stats(struct net_device *netdev) struct net_device *igb_get_netdev(struct kobject *kobj) { struct net_device *netdev; - struct kobject *parent; + struct kobject *parent = kobj->parent; struct device *device_info_kobj; if (kobj == NULL) return NULL; - parent = kobj->parent; - device_info_kobj = container_of(parent, struct device, kobj); if (device_info_kobj == NULL) return NULL; diff --git a/kmod/igb/igb_vmdq.c b/kmod/igb/igb_vmdq.c index 5a1db16..9fc32a8 100644 --- a/kmod/igb/igb_vmdq.c +++ b/kmod/igb/igb_vmdq.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/igb_vmdq.h b/kmod/igb/igb_vmdq.h index 2e69305..e51e7c4 100644 --- a/kmod/igb/igb_vmdq.h +++ b/kmod/igb/igb_vmdq.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/kmod/igb/kcompat.c b/kmod/igb/kcompat.c index 64c7e84..e5ef3eb 100644 --- a/kmod/igb/kcompat.c +++ b/kmod/igb/kcompat.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -927,6 +927,50 @@ void _kc_print_hex_dump(const char *level, } } } +#ifdef HAVE_I2C_SUPPORT +struct i2c_client * +_kc_i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) +{ + struct i2c_client *client; + int status; + + client = kzalloc(sizeof *client, GFP_KERNEL); + if (!client) + return NULL; + + client->adapter = adap; + + client->dev.platform_data = info->platform_data; + + client->flags = info->flags; + client->addr = info->addr; + + strlcpy(client->name, info->type, sizeof(client->name)); + + /* Check for address business */ + status = i2c_check_addr(adap, client->addr); + if (status) + goto out_err; + + client->dev.parent = &client->adapter->dev; + client->dev.bus = &i2c_bus_type; + + status = i2c_attach_client(client); + if (status) + goto out_err; + + dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n", + client->name, dev_name(&client->dev)); + + return client; + +out_err: + dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x " + "(%d)\n", client->name, client->addr, status); + kfree(client); + return NULL; +} +#endif /* HAVE_I2C_SUPPORT */ #endif /* < 2.6.22 */ /*****************************************************************************/ @@ -1113,6 +1157,25 @@ void _kc_netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) #endif /* CONFIG_NETDEVICES_MULTIQUEUE */ #endif /* !(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,0)) */ #endif /* HAVE_TX_MQ */ +ssize_t _kc_simple_write_to_buffer(void *to, size_t available, loff_t *ppos, + const void __user *from, size_t count) +{ + loff_t pos = *ppos; + size_t res; + + if (pos < 0) + return -EINVAL; + if (pos >= available || !count) + return 0; + if (count > available - pos) + count = available - pos; + res = copy_from_user(to + pos, from, count); + if (res == count) + return -EFAULT; + count -= res; + *ppos = pos + count; + return count; +} #endif /* < 2.6.35 */ /*****************************************************************************/ @@ -1136,51 +1199,183 @@ int _kc_ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported) } #endif /* < 2.6.36 */ -/*****************************************************************************/ -#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) ) -#ifdef HAVE_NETDEV_SELECT_QUEUE -#include -static u32 _kc_simple_tx_hashrnd; -static u32 _kc_simple_tx_hashrnd_initialized; - -u16 ___kc_skb_tx_hash(struct net_device *dev, const struct sk_buff *skb, - u16 num_tx_queues) +/******************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) ) +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0))) + +#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0)) */ +#endif /* < 2.6.39 */ + +/******************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) ) +void _kc_skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, + int off, int size, unsigned int truesize) { - u32 hash; + skb_fill_page_desc(skb, i, page, off, size); + skb->len += size; + skb->data_len += size; + skb->truesize += truesize; +} + +#endif /* < 3.4.0 */ + +/******************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) ) +static inline int __kc_pcie_cap_version(struct pci_dev *dev) +{ + int pos; + u16 reg16; - if (skb_rx_queue_recorded(skb)) { - hash = skb_get_rx_queue(skb); - while (unlikely(hash >= num_tx_queues)) - hash -= num_tx_queues; - return hash; + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (!pos) + return 0; + pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); + return reg16 & PCI_EXP_FLAGS_VERS; } - if (unlikely(!_kc_simple_tx_hashrnd_initialized)) { - get_random_bytes(&_kc_simple_tx_hashrnd, 4); - _kc_simple_tx_hashrnd_initialized = 1; +static inline bool __kc_pcie_cap_has_devctl(const struct pci_dev __always_unused *dev) +{ + return true; } - if (skb->sk && skb->sk->sk_hash) - hash = skb->sk->sk_hash; - else -#ifdef NETIF_F_RXHASH - hash = (__force u16) skb->protocol ^ skb->rxhash; -#else - hash = skb->protocol; -#endif +static inline bool __kc_pcie_cap_has_lnkctl(struct pci_dev *dev) +{ + int type = pci_pcie_type(dev); - hash = jhash_1word(hash, _kc_simple_tx_hashrnd); + return __kc_pcie_cap_version(dev) > 1 || + type == PCI_EXP_TYPE_ROOT_PORT || + type == PCI_EXP_TYPE_ENDPOINT || + type == PCI_EXP_TYPE_LEG_END; +} - return (u16) (((u64) hash * num_tx_queues) >> 32); +static inline bool __kc_pcie_cap_has_sltctl(struct pci_dev *dev) +{ + int type = pci_pcie_type(dev); + int pos; + u16 pcie_flags_reg; + + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (!pos) + return 0; + pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &pcie_flags_reg); + + return __kc_pcie_cap_version(dev) > 1 || + type == PCI_EXP_TYPE_ROOT_PORT || + (type == PCI_EXP_TYPE_DOWNSTREAM && + pcie_flags_reg & PCI_EXP_FLAGS_SLOT); } -#endif /* HAVE_NETDEV_SELECT_QUEUE */ -#endif /* < 2.6.38 */ +static inline bool __kc_pcie_cap_has_rtctl(struct pci_dev *dev) +{ + int type = pci_pcie_type(dev); + + return __kc_pcie_cap_version(dev) > 1 || + type == PCI_EXP_TYPE_ROOT_PORT || + type == PCI_EXP_TYPE_RC_EC; +} + +static bool __kc_pcie_capability_reg_implemented(struct pci_dev *dev, int pos) +{ + if (!pci_is_pcie(dev)) + return false; + + switch (pos) { + case PCI_EXP_FLAGS_TYPE: + return true; + case PCI_EXP_DEVCAP: + case PCI_EXP_DEVCTL: + case PCI_EXP_DEVSTA: + return __kc_pcie_cap_has_devctl(dev); + case PCI_EXP_LNKCAP: + case PCI_EXP_LNKCTL: + case PCI_EXP_LNKSTA: + return __kc_pcie_cap_has_lnkctl(dev); + case PCI_EXP_SLTCAP: + case PCI_EXP_SLTCTL: + case PCI_EXP_SLTSTA: + return __kc_pcie_cap_has_sltctl(dev); + case PCI_EXP_RTCTL: + case PCI_EXP_RTCAP: + case PCI_EXP_RTSTA: + return __kc_pcie_cap_has_rtctl(dev); + case PCI_EXP_DEVCAP2: + case PCI_EXP_DEVCTL2: + case PCI_EXP_LNKCAP2: + case PCI_EXP_LNKCTL2: + case PCI_EXP_LNKSTA2: + return __kc_pcie_cap_version(dev) > 1; + default: + return false; + } +} + +/* + * Note that these accessor functions are only for the "PCI Express + * Capability" (see PCIe spec r3.0, sec 7.8). They do not apply to the + * other "PCI Express Extended Capabilities" (AER, VC, ACS, MFVC, etc.) + */ +int __kc_pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) +{ + int ret; + + *val = 0; + if (pos & 1) + return -EINVAL; + + if (__kc_pcie_capability_reg_implemented(dev, pos)) { + ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val); + /* + * Reset *val to 0 if pci_read_config_word() fails, it may + * have been written as 0xFFFF if hardware error happens + * during pci_read_config_word(). + */ + if (ret) + *val = 0; + return ret; + } + + /* + * For Functions that do not implement the Slot Capabilities, + * Slot Status, and Slot Control registers, these spaces must + * be hardwired to 0b, with the exception of the Presence Detect + * State bit in the Slot Status register of Downstream Ports, + * which must be hardwired to 1b. (PCIe Base Spec 3.0, sec 7.8) + */ + if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA && + pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { + *val = PCI_EXP_SLTSTA_PDS; + } + + return 0; +} + +int __kc_pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val) +{ + if (pos & 1) + return -EINVAL; + + if (!__kc_pcie_capability_reg_implemented(dev, pos)) + return 0; + + return pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val); +} + +int __kc_pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, + u16 clear, u16 set) +{ + int ret; + u16 val; + + ret = __kc_pcie_capability_read_word(dev, pos, &val); + if (!ret) { + val &= ~clear; + val |= set; + ret = __kc_pcie_capability_write_word(dev, pos, val); + } + + return ret; +} +#endif /* < 3.7.0 */ /******************************************************************************/ -#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) ) -#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0))) -#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0)) */ -#endif /* < 2.6.39 */ -/******************************************************************************/ -#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) ) -#endif /* < 3.4.0 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) ) +#endif /* 3.9.0 */ diff --git a/kmod/igb/kcompat.h b/kmod/igb/kcompat.h index 1026f22..b741e3d 100644 --- a/kmod/igb/kcompat.h +++ b/kmod/igb/kcompat.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -287,6 +287,23 @@ struct msix_entry { #define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0) #endif +#ifdef IS_ENABLED +#undef IS_ENABLED +#undef __ARG_PLACEHOLDER_1 +#undef config_enabled +#undef _config_enabled +#undef __config_enabled +#undef ___config_enabled +#endif + +#define __ARG_PLACEHOLDER_1 0, +#define config_enabled(cfg) _config_enabled(cfg) +#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value) +#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0) +#define ___config_enabled(__ignored, val, ...) val + +#define IS_ENABLED(option) \ + (config_enabled(option) || config_enabled(option##_MODULE)) #ifndef NETIF_F_HW_VLAN_TX struct _kc_vlan_ethhdr { unsigned char h_dest[ETH_ALEN]; @@ -1048,6 +1065,11 @@ static inline void _kc_netif_tx_disable(struct net_device *dev) #endif /* 2.6.4 => 2.6.0 */ /*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) ) +#define __user +#endif /* < 2.4.27 */ + +/*****************************************************************************/ /* 2.5.71 => 2.4.x */ #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,71) ) #define sk_protocol protocol @@ -1231,13 +1253,6 @@ static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) /* 2.5.28 => 2.4.23 */ #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) ) -static inline void _kc_synchronize_irq(void) -{ - synchronize_irq(); -} -#undef synchronize_irq -#define synchronize_irq(X) _kc_synchronize_irq() - #include #define work_struct tq_struct #undef INIT_WORK @@ -1253,6 +1268,9 @@ static inline void _kc_synchronize_irq(void) /*****************************************************************************/ /* 2.6.0 => 2.5.28 */ #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ) +#ifndef read_barrier_depends +#define read_barrier_depends() rmb() +#endif #undef get_cpu #define get_cpu() smp_processor_id() #undef put_cpu @@ -1340,8 +1358,18 @@ extern uint32_t _kc__div64_32(uint64_t *dividend, uint32_t divisor); # error do_div() does not yet support the C64 #endif /* BITS_PER_LONG */ #endif /* do_div */ -#endif /* 2.6.0 => 2.5.28 */ +#ifndef NSEC_PER_SEC +#define NSEC_PER_SEC 1000000000L +#endif + +#undef HAVE_I2C_SUPPORT +#else /* 2.6.0 */ +#if IS_ENABLED(CONFIG_I2C_ALGOBIT) +#define HAVE_I2C_SUPPORT +#endif /* IS_ENABLED(CONFIG_I2C_ALGOBIT) */ + +#endif /* 2.6.0 => 2.5.28 */ /*****************************************************************************/ #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) ) #define dma_pool pci_pool @@ -1428,6 +1456,16 @@ static inline struct mii_ioctl_data *_kc_if_mii(struct ifreq *rq) #ifndef PCI_EXP_DEVCTL_CERE #define PCI_EXP_DEVCTL_CERE 0x0001 #endif +#define PCI_EXP_FLAGS 2 /* Capabilities register */ +#define PCI_EXP_FLAGS_VERS 0x000f /* Capability version */ +#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */ +#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */ +#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */ +#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */ +#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */ +#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */ +#define PCI_EXP_DEVCAP 4 /* Device capabilities */ +#define PCI_EXP_DEVSTA 10 /* Device Status */ #define msleep(x) do { set_current_state(TASK_UNINTERRUPTIBLE); \ schedule_timeout((x * HZ)/1000 + 2); \ } while (0) @@ -1618,6 +1656,14 @@ static inline unsigned long _kc_usecs_to_jiffies(const unsigned int m) return (m * HZ + KC_USEC_PER_SEC - 1) / KC_USEC_PER_SEC; #endif } +#define PCI_EXP_LNKCAP 12 /* Link Capabilities */ +#define PCI_EXP_LNKSTA 18 /* Link Status */ +#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ +#define PCI_EXP_SLTCTL 24 /* Slot Control */ +#define PCI_EXP_SLTSTA 26 /* Slot Status */ +#define PCI_EXP_RTCTL 28 /* Root Control */ +#define PCI_EXP_RTCAP 30 /* Root Capabilities */ +#define PCI_EXP_RTSTA 32 /* Root Status */ #endif /* < 2.6.11 */ /*****************************************************************************/ @@ -1631,8 +1677,15 @@ static inline unsigned long _kc_usecs_to_jiffies(const unsigned int m) /* Advertisement control register. */ #define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */ #define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymmetric pause */ +/* Link partner ability register. */ +#define LPA_PAUSE_CAP 0x0400 /* Can pause */ +#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */ /* 1000BASE-T Control register */ #define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ +#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ +/* 1000BASE-T Status register */ +#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */ +#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */ #ifndef is_zero_ether_addr #define is_zero_ether_addr _kc_is_zero_ether_addr static inline int _kc_is_zero_ether_addr(const u8 *addr) @@ -1845,6 +1898,9 @@ static inline int _kc_skb_padto(struct sk_buff *skb, unsigned int len) /*****************************************************************************/ #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) ) +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,4))) +#define i_private u.generic_ip +#endif /* >= RHEL 5.4 */ #ifndef DIV_ROUND_UP #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #endif @@ -2013,6 +2069,10 @@ static inline __wsum csum_unfold(__sum16 n) do { \ skb->tail = skb->data; \ } while (0) +#define skb_set_tail_pointer(skb, offset) \ + do { \ + skb->tail = skb->data + offset; \ + } while (0) #define skb_copy_to_linear_data(skb, from, len) \ memcpy(skb->data, from, len) #define skb_copy_to_linear_data_offset(skb, offset, from, len) \ @@ -2060,6 +2120,30 @@ extern void _kc_print_hex_dump(const char *level, const char *prefix_str, const void *buf, size_t len, bool ascii); #define print_hex_dump(lvl, s, t, r, g, b, l, a) \ _kc_print_hex_dump(lvl, s, t, r, g, b, l, a) +#ifndef ADVERTISED_2500baseX_Full +#define ADVERTISED_2500baseX_Full (1 << 15) +#endif +#ifndef SUPPORTED_2500baseX_Full +#define SUPPORTED_2500baseX_Full (1 << 15) +#endif + +#ifdef HAVE_I2C_SUPPORT +#include +#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,5))) +struct i2c_board_info { + char driver_name[KOBJ_NAME_LEN]; + char type[I2C_NAME_SIZE]; + unsigned short flags; + unsigned short addr; + void *platform_data; +}; +#define I2C_BOARD_INFO(driver, dev_addr) .driver_name = (driver),\ + .addr = (dev_addr) +#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,5)) */ +#define i2c_new_device(adap, info) _kc_i2c_new_device(adap, info) +extern struct i2c_client * +_kc_i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info); +#endif /* HAVE_I2C_SUPPORT */ #else /* 2.6.22 */ #define ETH_TYPE_TRANS_SETS_DEV #define HAVE_NETDEV_STATS_IN_NETDEV @@ -2229,16 +2313,20 @@ static inline int _kc_skb_is_gso_v6(const struct sk_buff *skb) #endif /* DEFINE_PCI_DEVICE_TABLE */ +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) #ifndef IGB_PROCFS #define IGB_PROCFS #endif /* IGB_PROCFS */ +#endif /* >= 2.6.0 */ #else /* < 2.6.25 */ -#ifndef IGB_SYSFS -#define IGB_SYSFS -#endif /* IGB_SYSFS */ +#if IS_ENABLED(CONFIG_HWMON) +#ifndef IGB_HWMON +#define IGB_HWMON +#endif /* IGB_HWMON */ +#endif /* CONFIG_HWMON */ #endif /* < 2.6.25 */ @@ -2371,9 +2459,13 @@ extern void __kc_warn_slowpath(const char *file, const int line, unlikely(__ret_warn_on); \ }) #endif /* WARN */ +#undef HAVE_IXGBE_DEBUG_FS #else /* < 2.6.27 */ #define HAVE_TX_MQ #define HAVE_NETDEV_SELECT_QUEUE +#ifdef CONFIG_DEBUG_FS +#define HAVE_IXGBE_DEBUG_FS +#endif /* CONFIG_DEBUG_FS */ #endif /* < 2.6.27 */ /*****************************************************************************/ @@ -2393,6 +2485,8 @@ static inline void __kc_skb_queue_head_init(struct sk_buff_head *list) } #define __skb_queue_head_init(_q) __kc_skb_queue_head_init(_q) #endif +#define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ +#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ #endif /* < 2.6.28 */ /*****************************************************************************/ @@ -2409,6 +2503,7 @@ static inline void __kc_skb_queue_head_init(struct sk_buff_head *list) #ifndef pcie_aspm_enabled #define pcie_aspm_enabled() (1) #endif /* pcie_aspm_enabled */ +#define PCI_EXP_SLTSTA_PDS 0x0040 /* Presence Detect State */ #else /* < 2.6.29 */ #ifndef HAVE_NET_DEVICE_OPS #define HAVE_NET_DEVICE_OPS @@ -2438,7 +2533,20 @@ static inline void __kc_skb_queue_head_init(struct sk_buff_head *list) #define pr_cont(fmt, ...) \ printk(KERN_CONT fmt, ##__VA_ARGS__) #endif /* pr_cont */ -#else +static inline void _kc_synchronize_irq(unsigned int a) +{ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) ) + synchronize_irq(); +#else /* < 2.5.28 */ + synchronize_irq(a); +#endif /* < 2.5.28 */ +} +#undef synchronize_irq +#define synchronize_irq(a) _kc_synchronize_irq(a) + +#define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ + +#else /* < 2.6.30 */ #define HAVE_ASPM_QUIRKS #endif /* < 2.6.30 */ @@ -2462,6 +2570,9 @@ static inline void __kc_skb_queue_head_init(struct sk_buff_head *list) #ifndef MDIO_PHY_ID_DEVAD #define MDIO_PHY_ID_DEVAD 0x001f #endif +#ifndef skb_dst +#define skb_dst(s) ((s)->dst) +#endif #else /* < 2.6.31 */ #ifndef HAVE_NETDEV_STORAGE_ADDRESS #define HAVE_NETDEV_STORAGE_ADDRESS @@ -2584,6 +2695,34 @@ static inline void __kc_skb_queue_head_init(struct sk_buff_head *list) #define dma_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) #endif /* CONFIG_X86_64 && !CONFIG_NEED_DMA_MAP_STATE */ #endif /* RHEL_RELEASE_CODE */ +#if (!(RHEL_RELEASE_CODE && \ + (((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,8)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,0))) || \ + ((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,1)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)))))) +static inline bool pci_is_pcie(struct pci_dev *dev) +{ + return !!pci_pcie_cap(dev); +} +#endif /* RHEL_RELEASE_CODE */ + +#ifndef __always_unused +#define __always_unused +#endif + +#if (!(RHEL_RELEASE_CODE && \ + (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,2)))) +#define sk_tx_queue_get(_sk) (-1) +#define sk_tx_queue_set(_sk, _tx_queue) do {} while(0) +#endif /* !(RHEL >= 6.2) */ + +#if (RHEL_RELEASE_CODE && \ + (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,4)) && \ + (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0))) +#define HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT +#define HAVE_ETHTOOL_SET_PHYS_ID +#define HAVE_ETHTOOL_GET_TS_INFO +#endif /* RHEL >= 6.4 && RHEL < 7.0 */ #else /* < 2.6.33 */ #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) #ifndef HAVE_NETDEV_OPS_FCOE_GETWWN @@ -2755,6 +2894,19 @@ do { \ #define dma_unmap_len pci_unmap_len #define dma_unmap_len_set pci_unmap_len_set #endif /* DEFINE_DMA_UNMAP_ADDR */ +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,3)) +#ifdef IGB_HWMON +#ifdef CONFIG_DEBUG_LOCK_ALLOC +#define sysfs_attr_init(attr) \ + do { \ + static struct lock_class_key __key; \ + (attr)->key = &__key; \ + } while (0) +#else +#define sysfs_attr_init(attr) do {} while (0) +#endif /* CONFIG_DEBUG_LOCK_ALLOC */ +#endif /* IGB_HWMON */ +#endif /* RHEL_RELEASE_CODE */ #else /* < 2.6.34 */ #define HAVE_SYSTEM_SLEEP_PM_OPS #ifndef HAVE_SET_RX_MODE @@ -2765,6 +2917,9 @@ do { \ /*****************************************************************************/ #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ) +ssize_t _kc_simple_write_to_buffer(void *to, size_t available, loff_t *ppos, + const void __user *from, size_t count); +#define simple_write_to_buffer _kc_simple_write_to_buffer #ifndef numa_node_id #define numa_node_id() 0 #endif @@ -2787,6 +2942,9 @@ void _kc_netif_set_real_num_tx_queues(struct net_device *, unsigned int); #ifndef ETH_FLAG_RXHASH #define ETH_FLAG_RXHASH (1<<28) #endif /* ETH_FLAG_RXHASH */ +#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,0)) +#define HAVE_IRQ_AFFINITY_HINT +#endif #else /* < 2.6.35 */ #define HAVE_PM_QOS_REQUEST_LIST #define HAVE_IRQ_AFFINITY_HINT @@ -2957,9 +3115,9 @@ static inline int _kc_skb_checksum_start_offset(const struct sk_buff *skb) #define DCB_CAP_DCBX_STATIC 0x10 #endif #endif /* CONFIG_DCB */ -extern u16 ___kc_skb_tx_hash(struct net_device *, const struct sk_buff *, u16); -#define __skb_tx_hash(n, s, q) ___kc_skb_tx_hash((n), (s), (q)) -#else /* < 2.6.38 */ +#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,2)) +#define CONFIG_XPS +#endif /* RHEL_RELEASE_VERSION(6,2) */ #endif /* < 2.6.38 */ /*****************************************************************************/ @@ -3039,19 +3197,6 @@ struct _kc_ethtool_rx_flow_spec { #else /* < 2.6.40 */ #define HAVE_ETHTOOL_SET_PHYS_ID #endif /* < 2.6.40 */ -/*****************************************************************************/ - -/*****************************************************************************/ -#undef CONFIG_IGB_PTP -#ifdef CONFIG_PTP -#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) ) && (defined(CONFIG_PTP_1588_CLOCK) || defined(CONFIG_PTP_1588_CLOCK_MODULE)) -#define CONFIG_IGB_PTP -#else -#error Cannot enable PTP Hardware Clock due to insufficient kernel support -#endif -#endif /* IGB_PTP */ - -/*****************************************************************************/ /*****************************************************************************/ #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) ) @@ -3061,6 +3206,9 @@ struct _kc_ethtool_rx_flow_spec { #define dcb_ieee_setapp(dev, app) dcb_setapp(dev, app) #define dcb_ieee_delapp(dev, app) 0 #define dcb_ieee_getapp_mask(dev, app) (1 << app->priority) +/* 1000BASE-T Control register */ +#define CTL1000_AS_MASTER 0x0800 +#define CTL1000_ENABLE_MASTER 0x1000 #else /* < 3.1.0 */ #ifndef HAVE_DCBNL_IEEE_DELAPP #define HAVE_DCBNL_IEEE_DELAPP @@ -3106,6 +3254,9 @@ static inline void *_kc_skb_frag_address(const skb_frag_t *frag) #endif /* skb_frag_address */ #ifndef skb_frag_dma_map +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) +#include +#endif #define skb_frag_dma_map(dev,frag,offset,size,dir) \ _kc_skb_frag_dma_map(dev,frag,offset,size,dir) static inline dma_addr_t _kc_skb_frag_dma_map(struct device *dev, @@ -3146,6 +3297,8 @@ static inline void __kc_skb_frag_unref(skb_frag_t *frag) /*****************************************************************************/ #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) ) typedef u32 netdev_features_t; +#undef PCI_EXP_TYPE_RC_EC +#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */ #else /* ! < 3.3.0 */ #define HAVE_INT_NDO_VLAN_RX_ADD_VID #ifdef ETHTOOL_SRXNTUPLE @@ -3164,8 +3317,34 @@ typedef u32 netdev_features_t; #define NUMTCS_RETURNS_U8 +int _kc_simple_open(struct inode *inode, struct file *file); +#define simple_open _kc_simple_open -#endif /* < 3.4.0 */ +#ifndef skb_add_rx_frag +#define skb_add_rx_frag _kc_skb_add_rx_frag +extern void _kc_skb_add_rx_frag(struct sk_buff *, int, struct page *, + int, int, unsigned int); +#endif +#ifdef NET_ADDR_RANDOM +#define eth_hw_addr_random(N) do { \ + random_ether_addr(N->dev_addr); \ + N->addr_assign_type |= NET_ADDR_RANDOM; \ + } while (0) +#else /* NET_ADDR_RANDOM */ +#define eth_hw_addr_random(N) random_ether_addr(N->dev_addr) +#endif /* NET_ADDR_RANDOM */ +#else /* < 3.4.0 */ +#include +#endif /* >= 3.4.0 */ + +/*****************************************************************************/ +#if defined(E1000E_PTP) || defined(IGB_PTP) || defined(IXGBE_PTP) +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) ) && IS_ENABLED(CONFIG_PTP_1588_CLOCK) +#define HAVE_PTP_1588_CLOCK +#else +#error Cannot enable PTP Hardware Clock support due to a pre-3.0 kernel version or CONFIG_PTP_1588_CLOCK not enabled in the kernel +#endif /* > 3.0.0 && IS_ENABLED(CONFIG_PTP_1588_CLOCK) */ +#endif /* E1000E_PTP || IGB_PTP || IXGBE_PTP */ /*****************************************************************************/ #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) ) @@ -3173,11 +3352,34 @@ typedef u32 netdev_features_t; #else #define HAVE_FDB_OPS #define HAVE_ETHTOOL_GET_TS_INFO +#define HAVE_SKB_HEAD_FRAG #endif /* < 3.5.0 */ +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) ) +#define PCI_EXP_LNKCAP2 44 /* Link Capability 2 */ +#endif /* < 3.6.0 */ /******************************************************************************/ #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) ) #ifdef ETHTOOL_GEEE #include +#ifndef MDIO_EEE_100TX +#define MDIO_EEE_100TX 0x0002 /* 100TX EEE cap */ +#endif +#ifndef MDIO_EEE_1000T +#define MDIO_EEE_1000T 0x0004 /* 1000T EEE cap */ +#endif +#ifndef MDIO_EEE_10GT +#define MDIO_EEE_10GT 0x0008 /* 10GT EEE cap */ +#endif +#ifndef MDIO_EEE_1000KX +#define MDIO_EEE_1000KX 0x0010 /* 1000KX EEE cap */ +#endif +#ifndef MDIO_EEE_10GKX4 +#define MDIO_EEE_10GKX4 0x0020 /* 10G KX4 EEE cap */ +#endif +#ifndef MDIO_EEE_10GKR +#define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE cap */ +#endif /** * mmd_eee_cap_to_ethtool_sup_t * @eee_cap: value of the MMD EEE Capability register @@ -3233,5 +3435,87 @@ static inline u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv) return adv; } #endif /* ETHTOOL_GEEE */ -#endif /* < 3.7.0 */ +#ifndef pci_pcie_type +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ) +static inline u8 pci_pcie_type(struct pci_dev *pdev) +{ + int pos; + u16 reg16; + + pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); + if (!pos) + BUG(); + pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); + return (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; +} +#else /* < 2.6.24 */ +#define pci_pcie_type(x) (x)->pcie_type +#endif /* < 2.6.24 */ +#endif /* pci_pcie_type */ + +#define ptp_clock_register(caps, args...) ptp_clock_register(caps) + +int __kc_pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val); +#define pcie_capability_read_word(d,p,v) __kc_pcie_capability_read_word(d,p,v) +int __kc_pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val); +#define pcie_capability_write_word(d,p,v) __kc_pcie_capability_write_word(d,p,v) +int __kc_pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, + u16 clear, u16 set); +#define pcie_capability_clear_and_set_word(d,p,c,s) \ + __kc_pcie_capability_clear_and_set_word(d,p,c,s) + +#define PCI_EXP_LNKSTA2 50 /* Link Status 2 */ + +static inline int pcie_capability_clear_word(struct pci_dev *dev, int pos, + u16 clear) +{ + return __kc_pcie_capability_clear_and_set_word(dev, pos, clear, 0); +} + +#else /* >= 3.7.0 */ +#define HAVE_CONST_STRUCT_PCI_ERROR_HANDLERS +#endif /* >= 3.7.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) ) +#ifndef PCI_EXP_LNKCTL_ASPM_L0S +#define PCI_EXP_LNKCTL_ASPM_L0S 0x01 /* L0s Enable */ +#endif +#ifndef PCI_EXP_LNKCTL_ASPM_L1 +#define PCI_EXP_LNKCTL_ASPM_L1 0x02 /* L1 Enable */ +#endif +#define HAVE_CONFIG_HOTPLUG +#else /* >= 3.8.0 */ +#ifndef __devinit +#define __devinit +#endif + +#ifndef __devinitdata +#define __devinitdata +#endif + +#ifndef __devexit +#define __devexit +#endif + +#ifndef __devexit_p +#define __devexit_p +#endif +#endif /* >= 3.8.0 */ + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) ) +#ifdef CONFIG_XPS +extern int __kc_netif_set_xps_queue(struct net_device *, struct cpumask *, u16); +#define netif_set_xps_queue(_dev, _mask, _idx) __kc_netif_set_xps_queue((_dev), (_mask), (_idx)) +#else /* CONFIG_XPS */ +#define netif_set_xps_queue(_dev, _mask, _idx) do {} while (0) +#endif /* CONFIG_XPS */ + +#ifdef HAVE_NETDEV_SELECT_QUEUE +#define _kc_hashrnd 0xd631614b /* not so random hash salt */ +extern u16 __kc_netdev_pick_tx(struct net_device *dev, struct sk_buff *skb); +#define __netdev_pick_tx __kc_netdev_pick_tx +#endif /* HAVE_NETDEV_SELECT_QUEUE */ +#endif /* < 3.9.0 */ #endif /* _KCOMPAT_H_ */ diff --git a/kmod/igb/kcompat_ethtool.c b/kmod/igb/kcompat_ethtool.c index 01c8c9c..3adf869 100644 --- a/kmod/igb/kcompat_ethtool.c +++ b/kmod/igb/kcompat_ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. + Copyright(c) 2007-2013 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, -- 2.7.4