Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next

Jeff Kirsher says:

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

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2012-11-02 18:45:35 -04:00
Родитель f4d5392e5f ac56558fc6
Коммит 202975b4c5
9 изменённых файлов: 155 добавлений и 33 удалений

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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 |

Просмотреть файл

@ -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

Просмотреть файл

@ -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) | \

Просмотреть файл

@ -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

Просмотреть файл

@ -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:

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);