Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net...
authorDavid S. Miller <davem@davemloft.net>
Fri, 2 Nov 2012 22:45:35 +0000 (18:45 -0400)
committerDavid S. Miller <davem@davemloft.net>
Fri, 2 Nov 2012 22:45:35 +0000 (18:45 -0400)
Jeff Kirsher says:

====================
This series contains updates to igb, ixgbe and e1000.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/intel/e1000/e1000_hw.c
drivers/net/ethernet/intel/igb/e1000_82575.c
drivers/net/ethernet/intel/igb/e1000_i210.c
drivers/net/ethernet/intel/igb/e1000_i210.h
drivers/net/ethernet/intel/igb/e1000_mac.h
drivers/net/ethernet/intel/igb/e1000_nvm.c
drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c

index 3d6839528761c77462f0fee647d8fab1984913ef..8fedd2451538c255d0238a7f367bbb2d402aa2c8 100644 (file)
@@ -107,6 +107,7 @@ u16 e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = {
 };
 
 static DEFINE_SPINLOCK(e1000_eeprom_lock);
+static DEFINE_SPINLOCK(e1000_phy_lock);
 
 /**
  * e1000_set_phy_type - Set the phy type member in the hw struct.
@@ -2830,19 +2831,25 @@ static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw)
 s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 *phy_data)
 {
        u32 ret_val;
+       unsigned long flags;
 
        e_dbg("e1000_read_phy_reg");
 
+       spin_lock_irqsave(&e1000_phy_lock, flags);
+
        if ((hw->phy_type == e1000_phy_igp) &&
            (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
                ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
                                                 (u16) reg_addr);
-               if (ret_val)
+               if (ret_val) {
+                       spin_unlock_irqrestore(&e1000_phy_lock, flags);
                        return ret_val;
+               }
        }
 
        ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
                                        phy_data);
+       spin_unlock_irqrestore(&e1000_phy_lock, flags);
 
        return ret_val;
 }
@@ -2965,19 +2972,25 @@ static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
 s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 phy_data)
 {
        u32 ret_val;
+       unsigned long flags;
 
        e_dbg("e1000_write_phy_reg");
 
+       spin_lock_irqsave(&e1000_phy_lock, flags);
+
        if ((hw->phy_type == e1000_phy_igp) &&
            (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
                ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
                                                 (u16) reg_addr);
-               if (ret_val)
+               if (ret_val) {
+                       spin_unlock_irqrestore(&e1000_phy_lock, flags);
                        return ret_val;
+               }
        }
 
        ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
                                         phy_data);
+       spin_unlock_irqrestore(&e1000_phy_lock, flags);
 
        return ret_val;
 }
index ca4641e2f74870c1bac8c147ad231b19ba660e12..deb05970b9f16a3ed6913d4d15aaa252f80daad0 100644 (file)
@@ -319,6 +319,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
                nvm->ops.acquire = igb_acquire_nvm_i210;
                nvm->ops.release = igb_release_nvm_i210;
                nvm->ops.read    = igb_read_nvm_srrd_i210;
+               nvm->ops.write   = igb_write_nvm_srwr_i210;
                nvm->ops.valid_led_default = igb_valid_led_default_i210;
                break;
        case e1000_i211:
@@ -2233,19 +2234,16 @@ s32 igb_set_eee_i350(struct e1000_hw *hw)
 
        /* enable or disable per user setting */
        if (!(hw->dev_spec._82575.eee_disable)) {
-               ipcnfg |= (E1000_IPCNFG_EEE_1G_AN |
-                       E1000_IPCNFG_EEE_100M_AN);
-               eeer |= (E1000_EEER_TX_LPI_EN |
-                       E1000_EEER_RX_LPI_EN |
+               u32 eee_su = rd32(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 = rd32(E1000_EEE_SU);
-                       eee_su &= ~E1000_EEE_SU_LPI_CLK_STP;
-                       wr32(E1000_EEE_SU, eee_su);
-               }
+               /* This bit should not be set in normal operation. */
+               if (eee_su & E1000_EEE_SU_LPI_CLK_STP)
+                       hw_dbg("LPI Clock Stop Bit should not be set!\n");
+
 
        } else {
                ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN |
index 77a5f939bc7413ed84c5dfb7e2aa97a166047743..41474298d365559b9c76d83dd6056a7872bfc91d 100644 (file)
@@ -422,6 +422,100 @@ s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data)
        return status;
 }
 
+/**
+ *  igb_read_invm_version - Reads iNVM version and image type
+ *  @hw: pointer to the HW structure
+ *  @invm_ver: version structure for the version read
+ *
+ *  Reads iNVM version and image type.
+ **/
+s32 igb_read_invm_version(struct e1000_hw *hw,
+                         struct e1000_fw_version *invm_ver) {
+       u32 *record = NULL;
+       u32 *next_record = NULL;
+       u32 i = 0;
+       u32 invm_dword = 0;
+       u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE /
+                                            E1000_INVM_RECORD_SIZE_IN_BYTES);
+       u32 buffer[E1000_INVM_SIZE];
+       s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
+       u16 version = 0;
+
+       /* Read iNVM memory */
+       for (i = 0; i < E1000_INVM_SIZE; i++) {
+               invm_dword = rd32(E1000_INVM_DATA_REG(i));
+               buffer[i] = invm_dword;
+       }
+
+       /* Read version number */
+       for (i = 1; i < invm_blocks; i++) {
+               record = &buffer[invm_blocks - i];
+               next_record = &buffer[invm_blocks - i + 1];
+
+               /* Check if we have first version location used */
+               if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
+                       version = 0;
+                       status = E1000_SUCCESS;
+                       break;
+               }
+               /* Check if we have second version location used */
+               else if ((i == 1) &&
+                        ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
+                       version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
+                       status = E1000_SUCCESS;
+                       break;
+               }
+               /* Check if we have odd version location
+                * used and it is the last one used
+                */
+               else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
+                        ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
+                        (i != 1))) {
+                       version = (*next_record & E1000_INVM_VER_FIELD_TWO)
+                                 >> 13;
+                       status = E1000_SUCCESS;
+                       break;
+               }
+               /* Check if we have even version location
+                * used and it is the last one used
+                */
+               else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
+                        ((*record & 0x3) == 0)) {
+                       version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
+                       status = E1000_SUCCESS;
+                       break;
+               }
+       }
+
+       if (status == E1000_SUCCESS) {
+               invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK)
+                                       >> E1000_INVM_MAJOR_SHIFT;
+               invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
+       }
+       /* Read Image Type */
+       for (i = 1; i < invm_blocks; i++) {
+               record = &buffer[invm_blocks - i];
+               next_record = &buffer[invm_blocks - i + 1];
+
+               /* Check if we have image type in first location used */
+               if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
+                       invm_ver->invm_img_type = 0;
+                       status = E1000_SUCCESS;
+                       break;
+               }
+               /* Check if we have image type in first location used */
+               else if ((((*record & 0x3) == 0) &&
+                        ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
+                        ((((*record & 0x3) != 0) && (i != 1)))) {
+                       invm_ver->invm_img_type =
+                               (*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23;
+                       status = E1000_SUCCESS;
+                       break;
+               }
+       }
+       return status;
+}
+
 /**
  *  igb_validate_nvm_checksum_i210 - Validate EEPROM checksum
  *  @hw: pointer to the HW structure
index 5dc2bd3f50bc1df3076d59e61ba1f30209bacc5b..974d23584d70e06680c0dccd6c3cc533c6fc0050 100644 (file)
@@ -43,6 +43,8 @@ extern void igb_release_nvm_i210(struct e1000_hw *hw);
 extern s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data);
 extern s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
                               u16 *data);
+extern s32 igb_read_invm_version(struct e1000_hw *hw,
+                                struct e1000_fw_version *invm_ver);
 
 #define E1000_STM_OPCODE               0xDB00
 #define E1000_EEPROM_FLASH_SIZE_WORD   0x11
@@ -65,6 +67,15 @@ enum E1000_INVM_STRUCTURE_TYPE {
 
 #define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS  8
 #define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS    1
+#define E1000_INVM_ULT_BYTES_SIZE                      8
+#define E1000_INVM_RECORD_SIZE_IN_BYTES                        4
+#define E1000_INVM_VER_FIELD_ONE                       0x1FF8
+#define E1000_INVM_VER_FIELD_TWO                       0x7FE000
+#define E1000_INVM_IMGTYPE_FIELD                       0x1F800000
+
+#define E1000_INVM_MAJOR_MASK          0x3F0
+#define E1000_INVM_MINOR_MASK          0xF
+#define E1000_INVM_MAJOR_SHIFT         4
 
 #define ID_LED_DEFAULT_I210            ((ID_LED_OFF1_ON2  << 8) | \
                                         (ID_LED_OFF1_OFF2 <<  4) | \
index cbddc4e51e30d9c304b11c75250d04ddde39c5b7..e2b2c4b9c951fd704a5d452f00e6efd190ec307b 100644 (file)
@@ -33,6 +33,7 @@
 #include "e1000_phy.h"
 #include "e1000_nvm.h"
 #include "e1000_defines.h"
+#include "e1000_i210.h"
 
 /*
  * Functions that should not be called directly from drivers but can be used
index 54ff53905ffe70f7d16db93f93d7c23744d83023..7db3f80bcd5713cad349ee566e222315be9d7cd4 100644 (file)
@@ -727,6 +727,7 @@ void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
 
        switch (hw->mac.type) {
        case e1000_i211:
+               igb_read_invm_version(hw, fw_vers);
                return;
        case e1000_82575:
        case e1000_82576:
index 5e508b614dc376d5ac7a7473f4cce9767ec8d848..8c74f739011dd6a09ddbae19b4cf3bbe663c8a43 100644 (file)
@@ -824,6 +824,21 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
        /* initialize pointer to rings */
        ring = q_vector->ring;
 
+       /* intialize ITR */
+       if (txr_count && !rxr_count) {
+               /* tx only vector */
+               if (adapter->tx_itr_setting == 1)
+                       q_vector->itr = IXGBE_10K_ITR;
+               else
+                       q_vector->itr = adapter->tx_itr_setting;
+       } else {
+               /* rx or rx/tx vector */
+               if (adapter->rx_itr_setting == 1)
+                       q_vector->itr = IXGBE_20K_ITR;
+               else
+                       q_vector->itr = adapter->rx_itr_setting;
+       }
+
        while (txr_count) {
                /* assign generic ring traits */
                ring->dev = &adapter->pdev->dev;
index e5f993e8069c5b5d568dc8e4dcf0a7d2c6f3fe5c..b54bc40f00b0dbb8c4557b90c2d1c0e0bbd654b1 100644 (file)
@@ -1972,20 +1972,6 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
                ixgbe_for_each_ring(ring, q_vector->tx)
                        ixgbe_set_ivar(adapter, 1, ring->reg_idx, v_idx);
 
-               if (q_vector->tx.ring && !q_vector->rx.ring) {
-                       /* tx only vector */
-                       if (adapter->tx_itr_setting == 1)
-                               q_vector->itr = IXGBE_10K_ITR;
-                       else
-                               q_vector->itr = adapter->tx_itr_setting;
-               } else {
-                       /* rx or rx/tx vector */
-                       if (adapter->rx_itr_setting == 1)
-                               q_vector->itr = IXGBE_20K_ITR;
-                       else
-                               q_vector->itr = adapter->rx_itr_setting;
-               }
-
                ixgbe_write_eitr(q_vector);
        }
 
@@ -2751,12 +2737,6 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
 {
        struct ixgbe_q_vector *q_vector = adapter->q_vector[0];
 
-       /* rx/tx vector */
-       if (adapter->rx_itr_setting == 1)
-               q_vector->itr = IXGBE_20K_ITR;
-       else
-               q_vector->itr = adapter->rx_itr_setting;
-
        ixgbe_write_eitr(q_vector);
 
        ixgbe_set_ivar(adapter, 0, 0, 0);
index 842ba15550a545afd70f6b9dab78f51152ca9479..01d99af0b9bad90816ac9ccb9dc9f85bc8002617 100644 (file)
@@ -387,6 +387,15 @@ void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr)
        struct ixgbe_hw *hw = &adapter->hw;
        struct ptp_clock_event event;
 
+       event.type = PTP_CLOCK_PPS;
+
+       /* this check is necessary in case the interrupt was enabled via some
+        * alternative means (ex. debug_fs). Better to check here than
+        * everywhere that calls this function.
+        */
+       if (!adapter->ptp_clock)
+               return;
+
        switch (hw->mac.type) {
        case ixgbe_mac_X540:
                ptp_clock_event(adapter->ptp_clock, &event);
This page took 0.036447 seconds and 5 git commands to generate.