mirror of
https://github.com/torvalds/linux.git
synced 2024-12-22 10:56:40 +00:00
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/jkirsher/net-next-2.6
This commit is contained in:
commit
5a412ad7f4
@ -1512,7 +1512,7 @@ static int e100_phy_init(struct nic *nic)
|
|||||||
|
|
||||||
static int e100_hw_init(struct nic *nic)
|
static int e100_hw_init(struct nic *nic)
|
||||||
{
|
{
|
||||||
int err;
|
int err = 0;
|
||||||
|
|
||||||
e100_hw_reset(nic);
|
e100_hw_reset(nic);
|
||||||
|
|
||||||
|
@ -244,6 +244,14 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
|
|||||||
*/
|
*/
|
||||||
size += NVM_WORD_SIZE_BASE_SHIFT;
|
size += NVM_WORD_SIZE_BASE_SHIFT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for invalid size
|
||||||
|
*/
|
||||||
|
if ((hw->mac.type == e1000_82576) && (size > 15)) {
|
||||||
|
printk("igb: The NVM size is not valid, "
|
||||||
|
"defaulting to 32K.\n");
|
||||||
|
size = 15;
|
||||||
|
}
|
||||||
nvm->word_size = 1 << size;
|
nvm->word_size = 1 << size;
|
||||||
if (nvm->word_size == (1 << 15))
|
if (nvm->word_size == (1 << 15))
|
||||||
nvm->page_size = 128;
|
nvm->page_size = 128;
|
||||||
|
@ -391,11 +391,6 @@ static int igbvf_set_wol(struct net_device *netdev,
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int igbvf_phys_id(struct net_device *netdev, u32 data)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int igbvf_get_coalesce(struct net_device *netdev,
|
static int igbvf_get_coalesce(struct net_device *netdev,
|
||||||
struct ethtool_coalesce *ec)
|
struct ethtool_coalesce *ec)
|
||||||
{
|
{
|
||||||
@ -527,7 +522,6 @@ static const struct ethtool_ops igbvf_ethtool_ops = {
|
|||||||
.self_test = igbvf_diag_test,
|
.self_test = igbvf_diag_test,
|
||||||
.get_sset_count = igbvf_get_sset_count,
|
.get_sset_count = igbvf_get_sset_count,
|
||||||
.get_strings = igbvf_get_strings,
|
.get_strings = igbvf_get_strings,
|
||||||
.phys_id = igbvf_phys_id,
|
|
||||||
.get_ethtool_stats = igbvf_get_ethtool_stats,
|
.get_ethtool_stats = igbvf_get_ethtool_stats,
|
||||||
.get_coalesce = igbvf_get_coalesce,
|
.get_coalesce = igbvf_get_coalesce,
|
||||||
.set_coalesce = igbvf_set_coalesce,
|
.set_coalesce = igbvf_set_coalesce,
|
||||||
|
@ -157,9 +157,6 @@ struct ixgb_adapter {
|
|||||||
u16 link_duplex;
|
u16 link_duplex;
|
||||||
struct work_struct tx_timeout_task;
|
struct work_struct tx_timeout_task;
|
||||||
|
|
||||||
struct timer_list blink_timer;
|
|
||||||
unsigned long led_status;
|
|
||||||
|
|
||||||
/* TX */
|
/* TX */
|
||||||
struct ixgb_desc_ring tx_ring ____cacheline_aligned_in_smp;
|
struct ixgb_desc_ring tx_ring ____cacheline_aligned_in_smp;
|
||||||
unsigned int restart_queue;
|
unsigned int restart_queue;
|
||||||
|
@ -611,46 +611,24 @@ err_setup_rx:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* toggle LED 4 times per second = 2 "blinks" per second */
|
|
||||||
#define IXGB_ID_INTERVAL (HZ/4)
|
|
||||||
|
|
||||||
/* bit defines for adapter->led_status */
|
|
||||||
#define IXGB_LED_ON 0
|
|
||||||
|
|
||||||
static void
|
|
||||||
ixgb_led_blink_callback(unsigned long data)
|
|
||||||
{
|
|
||||||
struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
|
|
||||||
|
|
||||||
if (test_and_change_bit(IXGB_LED_ON, &adapter->led_status))
|
|
||||||
ixgb_led_off(&adapter->hw);
|
|
||||||
else
|
|
||||||
ixgb_led_on(&adapter->hw);
|
|
||||||
|
|
||||||
mod_timer(&adapter->blink_timer, jiffies + IXGB_ID_INTERVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ixgb_phys_id(struct net_device *netdev, u32 data)
|
ixgb_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
|
||||||
{
|
{
|
||||||
struct ixgb_adapter *adapter = netdev_priv(netdev);
|
struct ixgb_adapter *adapter = netdev_priv(netdev);
|
||||||
|
|
||||||
if (!data)
|
switch (state) {
|
||||||
data = INT_MAX;
|
case ETHTOOL_ID_ACTIVE:
|
||||||
|
return 2;
|
||||||
|
|
||||||
if (!adapter->blink_timer.function) {
|
case ETHTOOL_ID_ON:
|
||||||
init_timer(&adapter->blink_timer);
|
ixgb_led_on(&adapter->hw);
|
||||||
adapter->blink_timer.function = ixgb_led_blink_callback;
|
break;
|
||||||
adapter->blink_timer.data = (unsigned long)adapter;
|
|
||||||
|
case ETHTOOL_ID_OFF:
|
||||||
|
case ETHTOOL_ID_INACTIVE:
|
||||||
|
ixgb_led_off(&adapter->hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
mod_timer(&adapter->blink_timer, jiffies);
|
|
||||||
|
|
||||||
msleep_interruptible(data * 1000);
|
|
||||||
del_timer_sync(&adapter->blink_timer);
|
|
||||||
ixgb_led_off(&adapter->hw);
|
|
||||||
clear_bit(IXGB_LED_ON, &adapter->led_status);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,7 +745,7 @@ static const struct ethtool_ops ixgb_ethtool_ops = {
|
|||||||
.set_msglevel = ixgb_set_msglevel,
|
.set_msglevel = ixgb_set_msglevel,
|
||||||
.set_tso = ixgb_set_tso,
|
.set_tso = ixgb_set_tso,
|
||||||
.get_strings = ixgb_get_strings,
|
.get_strings = ixgb_get_strings,
|
||||||
.phys_id = ixgb_phys_id,
|
.set_phys_id = ixgb_set_phys_id,
|
||||||
.get_sset_count = ixgb_get_sset_count,
|
.get_sset_count = ixgb_get_sset_count,
|
||||||
.get_ethtool_stats = ixgb_get_ethtool_stats,
|
.get_ethtool_stats = ixgb_get_ethtool_stats,
|
||||||
.get_flags = ethtool_op_get_flags,
|
.get_flags = ethtool_op_get_flags,
|
||||||
|
@ -1281,6 +1281,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
|
|||||||
static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
|
static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
|
||||||
.init_params = &ixgbe_init_eeprom_params_generic,
|
.init_params = &ixgbe_init_eeprom_params_generic,
|
||||||
.read = &ixgbe_read_eerd_generic,
|
.read = &ixgbe_read_eerd_generic,
|
||||||
|
.read_buffer = &ixgbe_read_eerd_buffer_generic,
|
||||||
.calc_checksum = &ixgbe_calc_eeprom_checksum_generic,
|
.calc_checksum = &ixgbe_calc_eeprom_checksum_generic,
|
||||||
.validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
|
.validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
|
||||||
.update_checksum = &ixgbe_update_eeprom_checksum_generic,
|
.update_checksum = &ixgbe_update_eeprom_checksum_generic,
|
||||||
|
@ -110,7 +110,6 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
|
|||||||
|
|
||||||
ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
|
ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
|
||||||
&data_offset);
|
&data_offset);
|
||||||
|
|
||||||
if (ret_val != 0)
|
if (ret_val != 0)
|
||||||
goto setup_sfp_out;
|
goto setup_sfp_out;
|
||||||
|
|
||||||
@ -130,7 +129,7 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Release the semaphore */
|
/* Release the semaphore */
|
||||||
ixgbe_release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
|
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
|
||||||
/*
|
/*
|
||||||
* Delay obtaining semaphore again to allow FW access,
|
* Delay obtaining semaphore again to allow FW access,
|
||||||
* semaphore_delay is in ms usleep_range needs us.
|
* semaphore_delay is in ms usleep_range needs us.
|
||||||
@ -2064,6 +2063,39 @@ out:
|
|||||||
return lesm_enabled;
|
return lesm_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_read_eeprom_buffer_82599 - Read EEPROM word(s) using
|
||||||
|
* fastest available method
|
||||||
|
*
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
* @offset: offset of word in EEPROM to read
|
||||||
|
* @words: number of words
|
||||||
|
* @data: word(s) read from the EEPROM
|
||||||
|
*
|
||||||
|
* Retrieves 16 bit word(s) read from EEPROM
|
||||||
|
**/
|
||||||
|
static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 words, u16 *data)
|
||||||
|
{
|
||||||
|
struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
|
||||||
|
s32 ret_val = IXGBE_ERR_CONFIG;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If EEPROM is detected and can be addressed using 14 bits,
|
||||||
|
* use EERD otherwise use bit bang
|
||||||
|
*/
|
||||||
|
if ((eeprom->type == ixgbe_eeprom_spi) &&
|
||||||
|
(offset + (words - 1) <= IXGBE_EERD_MAX_ADDR))
|
||||||
|
ret_val = ixgbe_read_eerd_buffer_generic(hw, offset, words,
|
||||||
|
data);
|
||||||
|
else
|
||||||
|
ret_val = ixgbe_read_eeprom_buffer_bit_bang_generic(hw, offset,
|
||||||
|
words,
|
||||||
|
data);
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ixgbe_read_eeprom_82599 - Read EEPROM word using
|
* ixgbe_read_eeprom_82599 - Read EEPROM word using
|
||||||
* fastest available method
|
* fastest available method
|
||||||
@ -2140,7 +2172,9 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
|
|||||||
static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
|
static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
|
||||||
.init_params = &ixgbe_init_eeprom_params_generic,
|
.init_params = &ixgbe_init_eeprom_params_generic,
|
||||||
.read = &ixgbe_read_eeprom_82599,
|
.read = &ixgbe_read_eeprom_82599,
|
||||||
|
.read_buffer = &ixgbe_read_eeprom_buffer_82599,
|
||||||
.write = &ixgbe_write_eeprom_generic,
|
.write = &ixgbe_write_eeprom_generic,
|
||||||
|
.write_buffer = &ixgbe_write_eeprom_buffer_bit_bang_generic,
|
||||||
.calc_checksum = &ixgbe_calc_eeprom_checksum_generic,
|
.calc_checksum = &ixgbe_calc_eeprom_checksum_generic,
|
||||||
.validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
|
.validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
|
||||||
.update_checksum = &ixgbe_update_eeprom_checksum_generic,
|
.update_checksum = &ixgbe_update_eeprom_checksum_generic,
|
||||||
|
@ -55,6 +55,12 @@ static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
|
|||||||
u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
|
u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
|
||||||
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
|
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
|
||||||
static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg);
|
static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg);
|
||||||
|
static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 words, u16 *data);
|
||||||
|
static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 words, u16 *data);
|
||||||
|
static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
|
||||||
|
u16 offset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
|
* ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
|
||||||
@ -585,6 +591,8 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
|
|||||||
/* Set default semaphore delay to 10ms which is a well
|
/* Set default semaphore delay to 10ms which is a well
|
||||||
* tested value */
|
* tested value */
|
||||||
eeprom->semaphore_delay = 10;
|
eeprom->semaphore_delay = 10;
|
||||||
|
/* Clear EEPROM page size, it will be initialized as needed */
|
||||||
|
eeprom->word_page_size = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for EEPROM present first.
|
* Check for EEPROM present first.
|
||||||
@ -617,26 +625,78 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
|
* ixgbe_write_eeprom_buffer_bit_bang_generic - Write EEPROM using bit-bang
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
* @offset: offset within the EEPROM to write
|
||||||
|
* @words: number of words
|
||||||
|
* @data: 16 bit word(s) to write to EEPROM
|
||||||
|
*
|
||||||
|
* Reads 16 bit word(s) from EEPROM through bit-bang method
|
||||||
|
**/
|
||||||
|
s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 words, u16 *data)
|
||||||
|
{
|
||||||
|
s32 status = 0;
|
||||||
|
u16 i, count;
|
||||||
|
|
||||||
|
hw->eeprom.ops.init_params(hw);
|
||||||
|
|
||||||
|
if (words == 0) {
|
||||||
|
status = IXGBE_ERR_INVALID_ARGUMENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset + words > hw->eeprom.word_size) {
|
||||||
|
status = IXGBE_ERR_EEPROM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The EEPROM page size cannot be queried from the chip. We do lazy
|
||||||
|
* initialization. It is worth to do that when we write large buffer.
|
||||||
|
*/
|
||||||
|
if ((hw->eeprom.word_page_size == 0) &&
|
||||||
|
(words > IXGBE_EEPROM_PAGE_SIZE_MAX))
|
||||||
|
ixgbe_detect_eeprom_page_size_generic(hw, offset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We cannot hold synchronization semaphores for too long
|
||||||
|
* to avoid other entity starvation. However it is more efficient
|
||||||
|
* to read in bursts than synchronizing access for each word.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
|
||||||
|
count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
|
||||||
|
IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
|
||||||
|
status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset + i,
|
||||||
|
count, &data[i]);
|
||||||
|
|
||||||
|
if (status != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_write_eeprom_buffer_bit_bang - Writes 16 bit word(s) to EEPROM
|
||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
* @offset: offset within the EEPROM to be written to
|
* @offset: offset within the EEPROM to be written to
|
||||||
* @data: 16 bit word to be written to the EEPROM
|
* @words: number of word(s)
|
||||||
|
* @data: 16 bit word(s) to be written to the EEPROM
|
||||||
*
|
*
|
||||||
* If ixgbe_eeprom_update_checksum is not called after this function, the
|
* If ixgbe_eeprom_update_checksum is not called after this function, the
|
||||||
* EEPROM will most likely contain an invalid checksum.
|
* EEPROM will most likely contain an invalid checksum.
|
||||||
**/
|
**/
|
||||||
s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
|
static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 words, u16 *data)
|
||||||
{
|
{
|
||||||
s32 status;
|
s32 status;
|
||||||
|
u16 word;
|
||||||
|
u16 page_size;
|
||||||
|
u16 i;
|
||||||
u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
|
u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
|
||||||
|
|
||||||
hw->eeprom.ops.init_params(hw);
|
|
||||||
|
|
||||||
if (offset >= hw->eeprom.word_size) {
|
|
||||||
status = IXGBE_ERR_EEPROM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare the EEPROM for writing */
|
/* Prepare the EEPROM for writing */
|
||||||
status = ixgbe_acquire_eeprom(hw);
|
status = ixgbe_acquire_eeprom(hw);
|
||||||
|
|
||||||
@ -648,54 +708,69 @@ s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
ixgbe_standby_eeprom(hw);
|
for (i = 0; i < words; i++) {
|
||||||
|
ixgbe_standby_eeprom(hw);
|
||||||
|
|
||||||
/* Send the WRITE ENABLE command (8 bit opcode ) */
|
/* Send the WRITE ENABLE command (8 bit opcode ) */
|
||||||
ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_WREN_OPCODE_SPI,
|
ixgbe_shift_out_eeprom_bits(hw,
|
||||||
IXGBE_EEPROM_OPCODE_BITS);
|
IXGBE_EEPROM_WREN_OPCODE_SPI,
|
||||||
|
IXGBE_EEPROM_OPCODE_BITS);
|
||||||
|
|
||||||
ixgbe_standby_eeprom(hw);
|
ixgbe_standby_eeprom(hw);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some SPI eeproms use the 8th address bit embedded in the
|
* Some SPI eeproms use the 8th address bit embedded
|
||||||
* opcode
|
* in the opcode
|
||||||
*/
|
*/
|
||||||
if ((hw->eeprom.address_bits == 8) && (offset >= 128))
|
if ((hw->eeprom.address_bits == 8) &&
|
||||||
write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
|
((offset + i) >= 128))
|
||||||
|
write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
|
||||||
|
|
||||||
/* Send the Write command (8-bit opcode + addr) */
|
/* Send the Write command (8-bit opcode + addr) */
|
||||||
ixgbe_shift_out_eeprom_bits(hw, write_opcode,
|
ixgbe_shift_out_eeprom_bits(hw, write_opcode,
|
||||||
IXGBE_EEPROM_OPCODE_BITS);
|
IXGBE_EEPROM_OPCODE_BITS);
|
||||||
ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
|
ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
|
||||||
hw->eeprom.address_bits);
|
hw->eeprom.address_bits);
|
||||||
|
|
||||||
/* Send the data */
|
page_size = hw->eeprom.word_page_size;
|
||||||
data = (data >> 8) | (data << 8);
|
|
||||||
ixgbe_shift_out_eeprom_bits(hw, data, 16);
|
|
||||||
ixgbe_standby_eeprom(hw);
|
|
||||||
|
|
||||||
|
/* Send the data in burst via SPI*/
|
||||||
|
do {
|
||||||
|
word = data[i];
|
||||||
|
word = (word >> 8) | (word << 8);
|
||||||
|
ixgbe_shift_out_eeprom_bits(hw, word, 16);
|
||||||
|
|
||||||
|
if (page_size == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* do not wrap around page */
|
||||||
|
if (((offset + i) & (page_size - 1)) ==
|
||||||
|
(page_size - 1))
|
||||||
|
break;
|
||||||
|
} while (++i < words);
|
||||||
|
|
||||||
|
ixgbe_standby_eeprom(hw);
|
||||||
|
usleep_range(10000, 20000);
|
||||||
|
}
|
||||||
/* Done with writing - release the EEPROM */
|
/* Done with writing - release the EEPROM */
|
||||||
ixgbe_release_eeprom(hw);
|
ixgbe_release_eeprom(hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
|
* ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
|
||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
* @offset: offset within the EEPROM to be read
|
* @offset: offset within the EEPROM to be written to
|
||||||
* @data: read 16 bit value from EEPROM
|
* @data: 16 bit word to be written to the EEPROM
|
||||||
*
|
*
|
||||||
* Reads 16 bit value from EEPROM through bit-bang method
|
* If ixgbe_eeprom_update_checksum is not called after this function, the
|
||||||
|
* EEPROM will most likely contain an invalid checksum.
|
||||||
**/
|
**/
|
||||||
s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
|
s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
|
||||||
u16 *data)
|
|
||||||
{
|
{
|
||||||
s32 status;
|
s32 status;
|
||||||
u16 word_in;
|
|
||||||
u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
|
|
||||||
|
|
||||||
hw->eeprom.ops.init_params(hw);
|
hw->eeprom.ops.init_params(hw);
|
||||||
|
|
||||||
@ -704,6 +779,76 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data);
|
||||||
|
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_read_eeprom_buffer_bit_bang_generic - Read EEPROM using bit-bang
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
* @offset: offset within the EEPROM to be read
|
||||||
|
* @words: number of word(s)
|
||||||
|
* @data: read 16 bit words(s) from EEPROM
|
||||||
|
*
|
||||||
|
* Reads 16 bit word(s) from EEPROM through bit-bang method
|
||||||
|
**/
|
||||||
|
s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 words, u16 *data)
|
||||||
|
{
|
||||||
|
s32 status = 0;
|
||||||
|
u16 i, count;
|
||||||
|
|
||||||
|
hw->eeprom.ops.init_params(hw);
|
||||||
|
|
||||||
|
if (words == 0) {
|
||||||
|
status = IXGBE_ERR_INVALID_ARGUMENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset + words > hw->eeprom.word_size) {
|
||||||
|
status = IXGBE_ERR_EEPROM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We cannot hold synchronization semaphores for too long
|
||||||
|
* to avoid other entity starvation. However it is more efficient
|
||||||
|
* to read in bursts than synchronizing access for each word.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
|
||||||
|
count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
|
||||||
|
IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
|
||||||
|
|
||||||
|
status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset + i,
|
||||||
|
count, &data[i]);
|
||||||
|
|
||||||
|
if (status != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_read_eeprom_buffer_bit_bang - Read EEPROM using bit-bang
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
* @offset: offset within the EEPROM to be read
|
||||||
|
* @words: number of word(s)
|
||||||
|
* @data: read 16 bit word(s) from EEPROM
|
||||||
|
*
|
||||||
|
* Reads 16 bit word(s) from EEPROM through bit-bang method
|
||||||
|
**/
|
||||||
|
static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 words, u16 *data)
|
||||||
|
{
|
||||||
|
s32 status;
|
||||||
|
u16 word_in;
|
||||||
|
u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
|
||||||
|
u16 i;
|
||||||
|
|
||||||
/* Prepare the EEPROM for reading */
|
/* Prepare the EEPROM for reading */
|
||||||
status = ixgbe_acquire_eeprom(hw);
|
status = ixgbe_acquire_eeprom(hw);
|
||||||
|
|
||||||
@ -715,29 +860,145 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
ixgbe_standby_eeprom(hw);
|
for (i = 0; i < words; i++) {
|
||||||
|
ixgbe_standby_eeprom(hw);
|
||||||
|
/*
|
||||||
|
* Some SPI eeproms use the 8th address bit embedded
|
||||||
|
* in the opcode
|
||||||
|
*/
|
||||||
|
if ((hw->eeprom.address_bits == 8) &&
|
||||||
|
((offset + i) >= 128))
|
||||||
|
read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
|
||||||
|
|
||||||
/*
|
/* Send the READ command (opcode + addr) */
|
||||||
* Some SPI eeproms use the 8th address bit embedded in the
|
ixgbe_shift_out_eeprom_bits(hw, read_opcode,
|
||||||
* opcode
|
IXGBE_EEPROM_OPCODE_BITS);
|
||||||
*/
|
ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
|
||||||
if ((hw->eeprom.address_bits == 8) && (offset >= 128))
|
hw->eeprom.address_bits);
|
||||||
read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
|
|
||||||
|
|
||||||
/* Send the READ command (opcode + addr) */
|
/* Read the data. */
|
||||||
ixgbe_shift_out_eeprom_bits(hw, read_opcode,
|
word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
|
||||||
IXGBE_EEPROM_OPCODE_BITS);
|
data[i] = (word_in >> 8) | (word_in << 8);
|
||||||
ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
|
}
|
||||||
hw->eeprom.address_bits);
|
|
||||||
|
|
||||||
/* Read the data. */
|
|
||||||
word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
|
|
||||||
*data = (word_in >> 8) | (word_in << 8);
|
|
||||||
|
|
||||||
/* End this read operation */
|
/* End this read operation */
|
||||||
ixgbe_release_eeprom(hw);
|
ixgbe_release_eeprom(hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
* @offset: offset within the EEPROM to be read
|
||||||
|
* @data: read 16 bit value from EEPROM
|
||||||
|
*
|
||||||
|
* Reads 16 bit value from EEPROM through bit-bang method
|
||||||
|
**/
|
||||||
|
s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 *data)
|
||||||
|
{
|
||||||
|
s32 status;
|
||||||
|
|
||||||
|
hw->eeprom.ops.init_params(hw);
|
||||||
|
|
||||||
|
if (offset >= hw->eeprom.word_size) {
|
||||||
|
status = IXGBE_ERR_EEPROM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
|
||||||
|
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_read_eerd_buffer_generic - Read EEPROM word(s) using EERD
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
* @offset: offset of word in the EEPROM to read
|
||||||
|
* @words: number of word(s)
|
||||||
|
* @data: 16 bit word(s) from the EEPROM
|
||||||
|
*
|
||||||
|
* Reads a 16 bit word(s) from the EEPROM using the EERD register.
|
||||||
|
**/
|
||||||
|
s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 words, u16 *data)
|
||||||
|
{
|
||||||
|
u32 eerd;
|
||||||
|
s32 status = 0;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
hw->eeprom.ops.init_params(hw);
|
||||||
|
|
||||||
|
if (words == 0) {
|
||||||
|
status = IXGBE_ERR_INVALID_ARGUMENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset >= hw->eeprom.word_size) {
|
||||||
|
status = IXGBE_ERR_EEPROM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < words; i++) {
|
||||||
|
eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) +
|
||||||
|
IXGBE_EEPROM_RW_REG_START;
|
||||||
|
|
||||||
|
IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
|
||||||
|
status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
|
||||||
|
|
||||||
|
if (status == 0) {
|
||||||
|
data[i] = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
|
||||||
|
IXGBE_EEPROM_RW_REG_DATA);
|
||||||
|
} else {
|
||||||
|
hw_dbg(hw, "Eeprom read timed out\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_detect_eeprom_page_size_generic - Detect EEPROM page size
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
* @offset: offset within the EEPROM to be used as a scratch pad
|
||||||
|
*
|
||||||
|
* Discover EEPROM page size by writing marching data at given offset.
|
||||||
|
* This function is called only when we are writing a new large buffer
|
||||||
|
* at given offset so the data would be overwritten anyway.
|
||||||
|
**/
|
||||||
|
static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
|
||||||
|
u16 offset)
|
||||||
|
{
|
||||||
|
u16 data[IXGBE_EEPROM_PAGE_SIZE_MAX];
|
||||||
|
s32 status = 0;
|
||||||
|
u16 i;
|
||||||
|
|
||||||
|
for (i = 0; i < IXGBE_EEPROM_PAGE_SIZE_MAX; i++)
|
||||||
|
data[i] = i;
|
||||||
|
|
||||||
|
hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX;
|
||||||
|
status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset,
|
||||||
|
IXGBE_EEPROM_PAGE_SIZE_MAX, data);
|
||||||
|
hw->eeprom.word_page_size = 0;
|
||||||
|
if (status != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
|
||||||
|
if (status != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When writing in burst more than the actual page size
|
||||||
|
* EEPROM address wraps around current page.
|
||||||
|
*/
|
||||||
|
hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0];
|
||||||
|
|
||||||
|
hw_dbg(hw, "Detected EEPROM page size = %d words.",
|
||||||
|
hw->eeprom.word_page_size);
|
||||||
out:
|
out:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -752,27 +1013,56 @@ out:
|
|||||||
**/
|
**/
|
||||||
s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
|
s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
|
||||||
{
|
{
|
||||||
u32 eerd;
|
return ixgbe_read_eerd_buffer_generic(hw, offset, 1, data);
|
||||||
s32 status;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_write_eewr_buffer_generic - Write EEPROM word(s) using EEWR
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
* @offset: offset of word in the EEPROM to write
|
||||||
|
* @words: number of words
|
||||||
|
* @data: word(s) write to the EEPROM
|
||||||
|
*
|
||||||
|
* Write a 16 bit word(s) to the EEPROM using the EEWR register.
|
||||||
|
**/
|
||||||
|
s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 words, u16 *data)
|
||||||
|
{
|
||||||
|
u32 eewr;
|
||||||
|
s32 status = 0;
|
||||||
|
u16 i;
|
||||||
|
|
||||||
hw->eeprom.ops.init_params(hw);
|
hw->eeprom.ops.init_params(hw);
|
||||||
|
|
||||||
|
if (words == 0) {
|
||||||
|
status = IXGBE_ERR_INVALID_ARGUMENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (offset >= hw->eeprom.word_size) {
|
if (offset >= hw->eeprom.word_size) {
|
||||||
status = IXGBE_ERR_EEPROM;
|
status = IXGBE_ERR_EEPROM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
eerd = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) +
|
for (i = 0; i < words; i++) {
|
||||||
IXGBE_EEPROM_RW_REG_START;
|
eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
|
||||||
|
(data[i] << IXGBE_EEPROM_RW_REG_DATA) |
|
||||||
|
IXGBE_EEPROM_RW_REG_START;
|
||||||
|
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
|
status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
|
||||||
status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
|
if (status != 0) {
|
||||||
|
hw_dbg(hw, "Eeprom write EEWR timed out\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (status == 0)
|
IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
|
||||||
*data = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
|
|
||||||
IXGBE_EEPROM_RW_REG_DATA);
|
status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
|
||||||
else
|
if (status != 0) {
|
||||||
hw_dbg(hw, "Eeprom read timed out\n");
|
hw_dbg(hw, "Eeprom write EEWR timed out\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return status;
|
return status;
|
||||||
@ -788,35 +1078,7 @@ out:
|
|||||||
**/
|
**/
|
||||||
s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
|
s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
|
||||||
{
|
{
|
||||||
u32 eewr;
|
return ixgbe_write_eewr_buffer_generic(hw, offset, 1, &data);
|
||||||
s32 status;
|
|
||||||
|
|
||||||
hw->eeprom.ops.init_params(hw);
|
|
||||||
|
|
||||||
if (offset >= hw->eeprom.word_size) {
|
|
||||||
status = IXGBE_ERR_EEPROM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
eewr = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) |
|
|
||||||
(data << IXGBE_EEPROM_RW_REG_DATA) | IXGBE_EEPROM_RW_REG_START;
|
|
||||||
|
|
||||||
status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
|
|
||||||
if (status != 0) {
|
|
||||||
hw_dbg(hw, "Eeprom write EEWR timed out\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
|
|
||||||
|
|
||||||
status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
|
|
||||||
if (status != 0) {
|
|
||||||
hw_dbg(hw, "Eeprom write EEWR timed out\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,10 +49,18 @@ s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index);
|
|||||||
|
|
||||||
s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
|
s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
|
||||||
s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
|
s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
|
||||||
|
s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 words, u16 *data);
|
||||||
s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
|
s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
|
||||||
|
s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 words, u16 *data);
|
||||||
s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
|
s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
|
||||||
|
s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 words, u16 *data);
|
||||||
s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
|
s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
|
||||||
u16 *data);
|
u16 *data);
|
||||||
|
s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
|
||||||
|
u16 words, u16 *data);
|
||||||
u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
|
u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
|
||||||
s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
|
s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
|
||||||
u16 *checksum_val);
|
u16 *checksum_val);
|
||||||
|
@ -847,11 +847,8 @@ static int ixgbe_get_eeprom(struct net_device *netdev,
|
|||||||
if (!eeprom_buff)
|
if (!eeprom_buff)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < eeprom_len; i++) {
|
ret_val = hw->eeprom.ops.read_buffer(hw, first_word, eeprom_len,
|
||||||
if ((ret_val = hw->eeprom.ops.read(hw, first_word + i,
|
eeprom_buff);
|
||||||
&eeprom_buff[i])))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Device's eeprom is always little-endian, word addressable */
|
/* Device's eeprom is always little-endian, word addressable */
|
||||||
for (i = 0; i < eeprom_len; i++)
|
for (i = 0; i < eeprom_len; i++)
|
||||||
@ -1236,46 +1233,62 @@ static const struct ixgbe_reg_test reg_test_82598[] = {
|
|||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u32 register_test_patterns[] = {
|
static bool reg_pattern_test(struct ixgbe_adapter *adapter, u64 *data, int reg,
|
||||||
0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
|
u32 mask, u32 write)
|
||||||
};
|
{
|
||||||
|
u32 pat, val, before;
|
||||||
|
static const u32 test_pattern[] = {
|
||||||
|
0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
|
||||||
|
|
||||||
#define REG_PATTERN_TEST(R, M, W) \
|
for (pat = 0; pat < ARRAY_SIZE(test_pattern); pat++) {
|
||||||
{ \
|
before = readl(adapter->hw.hw_addr + reg);
|
||||||
u32 pat, val, before; \
|
writel((test_pattern[pat] & write),
|
||||||
for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { \
|
(adapter->hw.hw_addr + reg));
|
||||||
before = readl(adapter->hw.hw_addr + R); \
|
val = readl(adapter->hw.hw_addr + reg);
|
||||||
writel((register_test_patterns[pat] & W), \
|
if (val != (test_pattern[pat] & write & mask)) {
|
||||||
(adapter->hw.hw_addr + R)); \
|
e_err(drv, "pattern test reg %04X failed: got "
|
||||||
val = readl(adapter->hw.hw_addr + R); \
|
"0x%08X expected 0x%08X\n",
|
||||||
if (val != (register_test_patterns[pat] & W & M)) { \
|
reg, val, (test_pattern[pat] & write & mask));
|
||||||
e_err(drv, "pattern test reg %04X failed: got " \
|
*data = reg;
|
||||||
"0x%08X expected 0x%08X\n", \
|
writel(before, adapter->hw.hw_addr + reg);
|
||||||
R, val, (register_test_patterns[pat] & W & M)); \
|
return 1;
|
||||||
*data = R; \
|
}
|
||||||
writel(before, adapter->hw.hw_addr + R); \
|
writel(before, adapter->hw.hw_addr + reg);
|
||||||
return 1; \
|
}
|
||||||
} \
|
return 0;
|
||||||
writel(before, adapter->hw.hw_addr + R); \
|
|
||||||
} \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REG_SET_AND_CHECK(R, M, W) \
|
static bool reg_set_and_check(struct ixgbe_adapter *adapter, u64 *data, int reg,
|
||||||
{ \
|
u32 mask, u32 write)
|
||||||
u32 val, before; \
|
{
|
||||||
before = readl(adapter->hw.hw_addr + R); \
|
u32 val, before;
|
||||||
writel((W & M), (adapter->hw.hw_addr + R)); \
|
before = readl(adapter->hw.hw_addr + reg);
|
||||||
val = readl(adapter->hw.hw_addr + R); \
|
writel((write & mask), (adapter->hw.hw_addr + reg));
|
||||||
if ((W & M) != (val & M)) { \
|
val = readl(adapter->hw.hw_addr + reg);
|
||||||
e_err(drv, "set/check reg %04X test failed: got 0x%08X " \
|
if ((write & mask) != (val & mask)) {
|
||||||
"expected 0x%08X\n", R, (val & M), (W & M)); \
|
e_err(drv, "set/check reg %04X test failed: got 0x%08X "
|
||||||
*data = R; \
|
"expected 0x%08X\n", reg, (val & mask), (write & mask));
|
||||||
writel(before, (adapter->hw.hw_addr + R)); \
|
*data = reg;
|
||||||
return 1; \
|
writel(before, (adapter->hw.hw_addr + reg));
|
||||||
} \
|
return 1;
|
||||||
writel(before, (adapter->hw.hw_addr + R)); \
|
}
|
||||||
|
writel(before, (adapter->hw.hw_addr + reg));
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define REG_PATTERN_TEST(reg, mask, write) \
|
||||||
|
do { \
|
||||||
|
if (reg_pattern_test(adapter, data, reg, mask, write)) \
|
||||||
|
return 1; \
|
||||||
|
} while (0) \
|
||||||
|
|
||||||
|
|
||||||
|
#define REG_SET_AND_CHECK(reg, mask, write) \
|
||||||
|
do { \
|
||||||
|
if (reg_set_and_check(adapter, data, reg, mask, write)) \
|
||||||
|
return 1; \
|
||||||
|
} while (0) \
|
||||||
|
|
||||||
static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
|
static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
|
||||||
{
|
{
|
||||||
const struct ixgbe_reg_test *test;
|
const struct ixgbe_reg_test *test;
|
||||||
@ -1326,13 +1339,13 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
|
|||||||
switch (test->test_type) {
|
switch (test->test_type) {
|
||||||
case PATTERN_TEST:
|
case PATTERN_TEST:
|
||||||
REG_PATTERN_TEST(test->reg + (i * 0x40),
|
REG_PATTERN_TEST(test->reg + (i * 0x40),
|
||||||
test->mask,
|
test->mask,
|
||||||
test->write);
|
test->write);
|
||||||
break;
|
break;
|
||||||
case SET_READ_TEST:
|
case SET_READ_TEST:
|
||||||
REG_SET_AND_CHECK(test->reg + (i * 0x40),
|
REG_SET_AND_CHECK(test->reg + (i * 0x40),
|
||||||
test->mask,
|
test->mask,
|
||||||
test->write);
|
test->write);
|
||||||
break;
|
break;
|
||||||
case WRITE_NO_TEST:
|
case WRITE_NO_TEST:
|
||||||
writel(test->write,
|
writel(test->write,
|
||||||
@ -1341,18 +1354,18 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
|
|||||||
break;
|
break;
|
||||||
case TABLE32_TEST:
|
case TABLE32_TEST:
|
||||||
REG_PATTERN_TEST(test->reg + (i * 4),
|
REG_PATTERN_TEST(test->reg + (i * 4),
|
||||||
test->mask,
|
test->mask,
|
||||||
test->write);
|
test->write);
|
||||||
break;
|
break;
|
||||||
case TABLE64_TEST_LO:
|
case TABLE64_TEST_LO:
|
||||||
REG_PATTERN_TEST(test->reg + (i * 8),
|
REG_PATTERN_TEST(test->reg + (i * 8),
|
||||||
test->mask,
|
test->mask,
|
||||||
test->write);
|
test->write);
|
||||||
break;
|
break;
|
||||||
case TABLE64_TEST_HI:
|
case TABLE64_TEST_HI:
|
||||||
REG_PATTERN_TEST((test->reg + 4) + (i * 8),
|
REG_PATTERN_TEST((test->reg + 4) + (i * 8),
|
||||||
test->mask,
|
test->mask,
|
||||||
test->write);
|
test->write);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3862,9 +3862,10 @@ static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter)
|
|||||||
if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
|
if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
|
||||||
gpie |= IXGBE_SDP1_GPIEN;
|
gpie |= IXGBE_SDP1_GPIEN;
|
||||||
|
|
||||||
if (hw->mac.type == ixgbe_mac_82599EB)
|
if (hw->mac.type == ixgbe_mac_82599EB) {
|
||||||
gpie |= IXGBE_SDP1_GPIEN;
|
gpie |= IXGBE_SDP1_GPIEN;
|
||||||
gpie |= IXGBE_SDP2_GPIEN;
|
gpie |= IXGBE_SDP2_GPIEN;
|
||||||
|
}
|
||||||
|
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
|
IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
|
||||||
}
|
}
|
||||||
@ -7468,8 +7469,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
|
|||||||
|
|
||||||
/* print bus type/speed/width info */
|
/* print bus type/speed/width info */
|
||||||
e_dev_info("(PCI Express:%s:%s) %pM\n",
|
e_dev_info("(PCI Express:%s:%s) %pM\n",
|
||||||
(hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0Gb/s" :
|
(hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0GT/s" :
|
||||||
hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5Gb/s" :
|
hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5GT/s" :
|
||||||
"Unknown"),
|
"Unknown"),
|
||||||
(hw->bus.width == ixgbe_bus_width_pcie_x8 ? "Width x8" :
|
(hw->bus.width == ixgbe_bus_width_pcie_x8 ? "Width x8" :
|
||||||
hw->bus.width == ixgbe_bus_width_pcie_x4 ? "Width x4" :
|
hw->bus.width == ixgbe_bus_width_pcie_x4 ? "Width x4" :
|
||||||
|
@ -1222,7 +1222,7 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
|
|||||||
swfw_mask = IXGBE_GSSR_PHY0_SM;
|
swfw_mask = IXGBE_GSSR_PHY0_SM;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != 0) {
|
if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != 0) {
|
||||||
status = IXGBE_ERR_SWFW_SYNC;
|
status = IXGBE_ERR_SWFW_SYNC;
|
||||||
goto read_byte_out;
|
goto read_byte_out;
|
||||||
}
|
}
|
||||||
@ -1269,7 +1269,7 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
ixgbe_release_swfw_sync(hw, swfw_mask);
|
hw->mac.ops.release_swfw_sync(hw, swfw_mask);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
ixgbe_i2c_bus_clear(hw);
|
ixgbe_i2c_bus_clear(hw);
|
||||||
retry++;
|
retry++;
|
||||||
@ -1280,7 +1280,7 @@ fail:
|
|||||||
|
|
||||||
} while (retry < max_retry);
|
} while (retry < max_retry);
|
||||||
|
|
||||||
ixgbe_release_swfw_sync(hw, swfw_mask);
|
hw->mac.ops.release_swfw_sync(hw, swfw_mask);
|
||||||
|
|
||||||
read_byte_out:
|
read_byte_out:
|
||||||
return status;
|
return status;
|
||||||
@ -1308,7 +1308,7 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
|
|||||||
else
|
else
|
||||||
swfw_mask = IXGBE_GSSR_PHY0_SM;
|
swfw_mask = IXGBE_GSSR_PHY0_SM;
|
||||||
|
|
||||||
if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != 0) {
|
if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != 0) {
|
||||||
status = IXGBE_ERR_SWFW_SYNC;
|
status = IXGBE_ERR_SWFW_SYNC;
|
||||||
goto write_byte_out;
|
goto write_byte_out;
|
||||||
}
|
}
|
||||||
@ -1352,7 +1352,7 @@ fail:
|
|||||||
hw_dbg(hw, "I2C byte write error.\n");
|
hw_dbg(hw, "I2C byte write error.\n");
|
||||||
} while (retry < max_retry);
|
} while (retry < max_retry);
|
||||||
|
|
||||||
ixgbe_release_swfw_sync(hw, swfw_mask);
|
hw->mac.ops.release_swfw_sync(hw, swfw_mask);
|
||||||
|
|
||||||
write_byte_out:
|
write_byte_out:
|
||||||
return status;
|
return status;
|
||||||
|
@ -1668,6 +1668,10 @@
|
|||||||
|
|
||||||
#define IXGBE_ETH_LENGTH_OF_ADDRESS 6
|
#define IXGBE_ETH_LENGTH_OF_ADDRESS 6
|
||||||
|
|
||||||
|
#define IXGBE_EEPROM_PAGE_SIZE_MAX 128
|
||||||
|
#define IXGBE_EEPROM_RD_BUFFER_MAX_COUNT 512 /* EEPROM words # read in burst */
|
||||||
|
#define IXGBE_EEPROM_WR_BUFFER_MAX_COUNT 256 /* EEPROM words # wr in burst */
|
||||||
|
|
||||||
#ifndef IXGBE_EEPROM_GRANT_ATTEMPTS
|
#ifndef IXGBE_EEPROM_GRANT_ATTEMPTS
|
||||||
#define IXGBE_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
|
#define IXGBE_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
|
||||||
#endif
|
#endif
|
||||||
@ -2563,7 +2567,9 @@ typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr,
|
|||||||
struct ixgbe_eeprom_operations {
|
struct ixgbe_eeprom_operations {
|
||||||
s32 (*init_params)(struct ixgbe_hw *);
|
s32 (*init_params)(struct ixgbe_hw *);
|
||||||
s32 (*read)(struct ixgbe_hw *, u16, u16 *);
|
s32 (*read)(struct ixgbe_hw *, u16, u16 *);
|
||||||
|
s32 (*read_buffer)(struct ixgbe_hw *, u16, u16, u16 *);
|
||||||
s32 (*write)(struct ixgbe_hw *, u16, u16);
|
s32 (*write)(struct ixgbe_hw *, u16, u16);
|
||||||
|
s32 (*write_buffer)(struct ixgbe_hw *, u16, u16, u16 *);
|
||||||
s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
|
s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
|
||||||
s32 (*update_checksum)(struct ixgbe_hw *);
|
s32 (*update_checksum)(struct ixgbe_hw *);
|
||||||
u16 (*calc_checksum)(struct ixgbe_hw *);
|
u16 (*calc_checksum)(struct ixgbe_hw *);
|
||||||
@ -2649,6 +2655,7 @@ struct ixgbe_eeprom_info {
|
|||||||
u32 semaphore_delay;
|
u32 semaphore_delay;
|
||||||
u16 word_size;
|
u16 word_size;
|
||||||
u16 address_bits;
|
u16 address_bits;
|
||||||
|
u16 word_page_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IXGBE_FLAGS_DOUBLE_RESET_REQUIRED 0x01
|
#define IXGBE_FLAGS_DOUBLE_RESET_REQUIRED 0x01
|
||||||
|
@ -304,21 +304,49 @@ static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ixgbe_read_eerd_X540 - Read EEPROM word using EERD
|
* ixgbe_read_eerd_X540- Read EEPROM word using EERD
|
||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
* @offset: offset of word in the EEPROM to read
|
* @offset: offset of word in the EEPROM to read
|
||||||
* @data: word read from the EERPOM
|
* @data: word read from the EEPROM
|
||||||
|
*
|
||||||
|
* Reads a 16 bit word from the EEPROM using the EERD register.
|
||||||
**/
|
**/
|
||||||
static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
|
static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
|
||||||
{
|
{
|
||||||
s32 status;
|
s32 status = 0;
|
||||||
|
|
||||||
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0)
|
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
|
||||||
|
0)
|
||||||
status = ixgbe_read_eerd_generic(hw, offset, data);
|
status = ixgbe_read_eerd_generic(hw, offset, data);
|
||||||
else
|
else
|
||||||
status = IXGBE_ERR_SWFW_SYNC;
|
status = IXGBE_ERR_SWFW_SYNC;
|
||||||
|
|
||||||
ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM);
|
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_read_eerd_buffer_X540 - Read EEPROM word(s) using EERD
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
* @offset: offset of word in the EEPROM to read
|
||||||
|
* @words: number of words
|
||||||
|
* @data: word(s) read from the EEPROM
|
||||||
|
*
|
||||||
|
* Reads a 16 bit word(s) from the EEPROM using the EERD register.
|
||||||
|
**/
|
||||||
|
static s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw,
|
||||||
|
u16 offset, u16 words, u16 *data)
|
||||||
|
{
|
||||||
|
s32 status = 0;
|
||||||
|
|
||||||
|
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
|
||||||
|
0)
|
||||||
|
status = ixgbe_read_eerd_buffer_generic(hw, offset,
|
||||||
|
words, data);
|
||||||
|
else
|
||||||
|
status = IXGBE_ERR_SWFW_SYNC;
|
||||||
|
|
||||||
|
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,6 +371,31 @@ static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
* @offset: offset of word in the EEPROM to write
|
||||||
|
* @words: number of words
|
||||||
|
* @data: word(s) write to the EEPROM
|
||||||
|
*
|
||||||
|
* Write a 16 bit word(s) to the EEPROM using the EEWR register.
|
||||||
|
**/
|
||||||
|
static s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw,
|
||||||
|
u16 offset, u16 words, u16 *data)
|
||||||
|
{
|
||||||
|
s32 status = 0;
|
||||||
|
|
||||||
|
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
|
||||||
|
0)
|
||||||
|
status = ixgbe_write_eewr_buffer_generic(hw, offset,
|
||||||
|
words, data);
|
||||||
|
else
|
||||||
|
status = IXGBE_ERR_SWFW_SYNC;
|
||||||
|
|
||||||
|
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
|
* ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
|
||||||
*
|
*
|
||||||
@ -851,7 +904,9 @@ static struct ixgbe_mac_operations mac_ops_X540 = {
|
|||||||
static struct ixgbe_eeprom_operations eeprom_ops_X540 = {
|
static struct ixgbe_eeprom_operations eeprom_ops_X540 = {
|
||||||
.init_params = &ixgbe_init_eeprom_params_X540,
|
.init_params = &ixgbe_init_eeprom_params_X540,
|
||||||
.read = &ixgbe_read_eerd_X540,
|
.read = &ixgbe_read_eerd_X540,
|
||||||
|
.read_buffer = &ixgbe_read_eerd_buffer_X540,
|
||||||
.write = &ixgbe_write_eewr_X540,
|
.write = &ixgbe_write_eewr_X540,
|
||||||
|
.write_buffer = &ixgbe_write_eewr_buffer_X540,
|
||||||
.calc_checksum = &ixgbe_calc_eeprom_checksum_X540,
|
.calc_checksum = &ixgbe_calc_eeprom_checksum_X540,
|
||||||
.validate_checksum = &ixgbe_validate_eeprom_checksum_X540,
|
.validate_checksum = &ixgbe_validate_eeprom_checksum_X540,
|
||||||
.update_checksum = &ixgbe_update_eeprom_checksum_X540,
|
.update_checksum = &ixgbe_update_eeprom_checksum_X540,
|
||||||
|
Loading…
Reference in New Issue
Block a user