net/txgbe: add EEPROM functions
Add EEPROM functions. Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
This commit is contained in:
parent
def7714516
commit
35c90ecccf
@ -2,7 +2,9 @@
|
||||
# Copyright(c) 2015-2020
|
||||
|
||||
sources = [
|
||||
'txgbe_eeprom.c',
|
||||
'txgbe_hw.c',
|
||||
'txgbe_mng.c',
|
||||
]
|
||||
|
||||
error_cflags = []
|
||||
|
@ -6,6 +6,8 @@
|
||||
#define _TXGBE_H_
|
||||
|
||||
#include "txgbe_type.h"
|
||||
#include "txgbe_mng.h"
|
||||
#include "txgbe_eeprom.h"
|
||||
#include "txgbe_hw.h"
|
||||
|
||||
#endif /* _TXGBE_H_ */
|
||||
|
581
drivers/net/txgbe/base/txgbe_eeprom.c
Normal file
581
drivers/net/txgbe/base/txgbe_eeprom.c
Normal file
@ -0,0 +1,581 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2015-2020
|
||||
*/
|
||||
|
||||
#include "txgbe_hw.h"
|
||||
#include "txgbe_mng.h"
|
||||
#include "txgbe_eeprom.h"
|
||||
|
||||
/**
|
||||
* txgbe_init_eeprom_params - Initialize EEPROM params
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Initializes the EEPROM parameters txgbe_rom_info within the
|
||||
* txgbe_hw struct in order to set up EEPROM access.
|
||||
**/
|
||||
s32 txgbe_init_eeprom_params(struct txgbe_hw *hw)
|
||||
{
|
||||
struct txgbe_rom_info *eeprom = &hw->rom;
|
||||
u32 eec;
|
||||
u16 eeprom_size;
|
||||
int err = 0;
|
||||
|
||||
DEBUGFUNC("txgbe_init_eeprom_params");
|
||||
|
||||
if (eeprom->type != txgbe_eeprom_unknown)
|
||||
return 0;
|
||||
|
||||
eeprom->type = txgbe_eeprom_none;
|
||||
/* Set default semaphore delay to 10ms which is a well
|
||||
* tested value
|
||||
*/
|
||||
eeprom->semaphore_delay = 10; /*ms*/
|
||||
/* Clear EEPROM page size, it will be initialized as needed */
|
||||
eeprom->word_page_size = 0;
|
||||
|
||||
/*
|
||||
* Check for EEPROM present first.
|
||||
* If not present leave as none
|
||||
*/
|
||||
eec = rd32(hw, TXGBE_SPISTAT);
|
||||
if (!(eec & TXGBE_SPISTAT_BPFLASH)) {
|
||||
eeprom->type = txgbe_eeprom_flash;
|
||||
|
||||
/*
|
||||
* SPI EEPROM is assumed here. This code would need to
|
||||
* change if a future EEPROM is not SPI.
|
||||
*/
|
||||
eeprom_size = 4096;
|
||||
eeprom->word_size = eeprom_size >> 1;
|
||||
}
|
||||
|
||||
eeprom->address_bits = 16;
|
||||
|
||||
err = eeprom->read32(hw, TXGBE_SW_REGION_PTR << 1, &eeprom->sw_addr);
|
||||
if (err) {
|
||||
DEBUGOUT("EEPROM read failed.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
DEBUGOUT("eeprom params: type = %d, size = %d, address bits: "
|
||||
"%d %d\n", eeprom->type, eeprom->word_size,
|
||||
eeprom->address_bits, eeprom->sw_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_get_eeprom_semaphore - Get hardware semaphore
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Sets the hardware semaphores so EEPROM access can occur for bit-bang method
|
||||
**/
|
||||
s32 txgbe_get_eeprom_semaphore(struct txgbe_hw *hw)
|
||||
{
|
||||
s32 status = TXGBE_ERR_EEPROM;
|
||||
u32 timeout = 2000;
|
||||
u32 i;
|
||||
u32 swsm;
|
||||
|
||||
DEBUGFUNC("txgbe_get_eeprom_semaphore");
|
||||
|
||||
|
||||
/* Get SMBI software semaphore between device drivers first */
|
||||
for (i = 0; i < timeout; i++) {
|
||||
/*
|
||||
* If the SMBI bit is 0 when we read it, then the bit will be
|
||||
* set and we have the semaphore
|
||||
*/
|
||||
swsm = rd32(hw, TXGBE_SWSEM);
|
||||
if (!(swsm & TXGBE_SWSEM_PF)) {
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
usec_delay(50);
|
||||
}
|
||||
|
||||
if (i == timeout) {
|
||||
DEBUGOUT("Driver can't access the eeprom - SMBI Semaphore "
|
||||
"not granted.\n");
|
||||
/*
|
||||
* this release is particularly important because our attempts
|
||||
* above to get the semaphore may have succeeded, and if there
|
||||
* was a timeout, we should unconditionally clear the semaphore
|
||||
* bits to free the driver to make progress
|
||||
*/
|
||||
txgbe_release_eeprom_semaphore(hw);
|
||||
|
||||
usec_delay(50);
|
||||
/*
|
||||
* one last try
|
||||
* If the SMBI bit is 0 when we read it, then the bit will be
|
||||
* set and we have the semaphore
|
||||
*/
|
||||
swsm = rd32(hw, TXGBE_SWSEM);
|
||||
if (!(swsm & TXGBE_SWSEM_PF))
|
||||
status = 0;
|
||||
}
|
||||
|
||||
/* Now get the semaphore between SW/FW through the SWESMBI bit */
|
||||
if (status == 0) {
|
||||
for (i = 0; i < timeout; i++) {
|
||||
/* Set the SW EEPROM semaphore bit to request access */
|
||||
wr32m(hw, TXGBE_MNGSWSYNC,
|
||||
TXGBE_MNGSWSYNC_REQ, TXGBE_MNGSWSYNC_REQ);
|
||||
|
||||
/*
|
||||
* If we set the bit successfully then we got the
|
||||
* semaphore.
|
||||
*/
|
||||
swsm = rd32(hw, TXGBE_MNGSWSYNC);
|
||||
if (swsm & TXGBE_MNGSWSYNC_REQ)
|
||||
break;
|
||||
|
||||
usec_delay(50);
|
||||
}
|
||||
|
||||
/*
|
||||
* Release semaphores and return error if SW EEPROM semaphore
|
||||
* was not granted because we don't have access to the EEPROM
|
||||
*/
|
||||
if (i >= timeout) {
|
||||
DEBUGOUT("SWESMBI Software EEPROM semaphore not granted.\n");
|
||||
txgbe_release_eeprom_semaphore(hw);
|
||||
status = TXGBE_ERR_EEPROM;
|
||||
}
|
||||
} else {
|
||||
DEBUGOUT("Software semaphore SMBI between device drivers "
|
||||
"not granted.\n");
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_release_eeprom_semaphore - Release hardware semaphore
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* This function clears hardware semaphore bits.
|
||||
**/
|
||||
void txgbe_release_eeprom_semaphore(struct txgbe_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("txgbe_release_eeprom_semaphore");
|
||||
|
||||
wr32m(hw, TXGBE_MNGSWSYNC, TXGBE_MNGSWSYNC_REQ, 0);
|
||||
wr32m(hw, TXGBE_SWSEM, TXGBE_SWSEM_PF, 0);
|
||||
txgbe_flush(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_ee_read - Read EEPROM word using a host interface cmd
|
||||
* @hw: pointer to hardware structure
|
||||
* @offset: offset of word in the EEPROM to read
|
||||
* @data: word read from the EEPROM
|
||||
*
|
||||
* Reads a 16 bit word from the EEPROM using the hostif.
|
||||
**/
|
||||
s32 txgbe_ee_read16(struct txgbe_hw *hw, u32 offset,
|
||||
u16 *data)
|
||||
{
|
||||
const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
|
||||
u32 addr = (offset << 1);
|
||||
int err;
|
||||
|
||||
err = hw->mac.acquire_swfw_sync(hw, mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 2);
|
||||
|
||||
hw->mac.release_swfw_sync(hw, mask);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_ee_read_buffer- Read EEPROM word(s) using hostif
|
||||
* @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 hostif.
|
||||
**/
|
||||
s32 txgbe_ee_readw_buffer(struct txgbe_hw *hw,
|
||||
u32 offset, u32 words, void *data)
|
||||
{
|
||||
const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
|
||||
u32 addr = (offset << 1);
|
||||
u32 len = (words << 1);
|
||||
u8 *buf = (u8 *)data;
|
||||
int err;
|
||||
|
||||
err = hw->mac.acquire_swfw_sync(hw, mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
while (len) {
|
||||
u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
|
||||
? len : TXGBE_PMMBX_DATA_SIZE);
|
||||
|
||||
err = txgbe_hic_sr_read(hw, addr, buf, seg);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
len -= seg;
|
||||
addr += seg;
|
||||
buf += seg;
|
||||
}
|
||||
|
||||
hw->mac.release_swfw_sync(hw, mask);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
s32 txgbe_ee_readw_sw(struct txgbe_hw *hw, u32 offset,
|
||||
u16 *data)
|
||||
{
|
||||
const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
|
||||
u32 addr = hw->rom.sw_addr + (offset << 1);
|
||||
int err;
|
||||
|
||||
err = hw->mac.acquire_swfw_sync(hw, mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 2);
|
||||
|
||||
hw->mac.release_swfw_sync(hw, mask);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_ee_read32 - Read EEPROM word using a host interface cmd
|
||||
* @hw: pointer to hardware structure
|
||||
* @offset: offset of word in the EEPROM to read
|
||||
* @data: word read from the EEPROM
|
||||
*
|
||||
* Reads a 32 bit word from the EEPROM using the hostif.
|
||||
**/
|
||||
s32 txgbe_ee_read32(struct txgbe_hw *hw, u32 addr, u32 *data)
|
||||
{
|
||||
const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
|
||||
int err;
|
||||
|
||||
err = hw->mac.acquire_swfw_sync(hw, mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 4);
|
||||
|
||||
hw->mac.release_swfw_sync(hw, mask);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_ee_read_buffer - Read EEPROM byte(s) using hostif
|
||||
* @hw: pointer to hardware structure
|
||||
* @addr: offset of bytes in the EEPROM to read
|
||||
* @len: number of bytes
|
||||
* @data: byte(s) read from the EEPROM
|
||||
*
|
||||
* Reads a 8 bit byte(s) from the EEPROM using the hostif.
|
||||
**/
|
||||
s32 txgbe_ee_read_buffer(struct txgbe_hw *hw,
|
||||
u32 addr, u32 len, void *data)
|
||||
{
|
||||
const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
|
||||
u8 *buf = (u8 *)data;
|
||||
int err;
|
||||
|
||||
err = hw->mac.acquire_swfw_sync(hw, mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
while (len) {
|
||||
u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
|
||||
? len : TXGBE_PMMBX_DATA_SIZE);
|
||||
|
||||
err = txgbe_hic_sr_read(hw, addr, buf, seg);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
len -= seg;
|
||||
buf += seg;
|
||||
}
|
||||
|
||||
hw->mac.release_swfw_sync(hw, mask);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_ee_write - Write EEPROM word using hostif
|
||||
* @hw: pointer to hardware structure
|
||||
* @offset: offset of word in the EEPROM to write
|
||||
* @data: word write to the EEPROM
|
||||
*
|
||||
* Write a 16 bit word to the EEPROM using the hostif.
|
||||
**/
|
||||
s32 txgbe_ee_write16(struct txgbe_hw *hw, u32 offset,
|
||||
u16 data)
|
||||
{
|
||||
const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
|
||||
u32 addr = (offset << 1);
|
||||
int err;
|
||||
|
||||
DEBUGFUNC("\n");
|
||||
|
||||
err = hw->mac.acquire_swfw_sync(hw, mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 2);
|
||||
|
||||
hw->mac.release_swfw_sync(hw, mask);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_ee_write_buffer - Write EEPROM word(s) using hostif
|
||||
* @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 hostif.
|
||||
**/
|
||||
s32 txgbe_ee_writew_buffer(struct txgbe_hw *hw,
|
||||
u32 offset, u32 words, void *data)
|
||||
{
|
||||
const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
|
||||
u32 addr = (offset << 1);
|
||||
u32 len = (words << 1);
|
||||
u8 *buf = (u8 *)data;
|
||||
int err;
|
||||
|
||||
err = hw->mac.acquire_swfw_sync(hw, mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
while (len) {
|
||||
u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
|
||||
? len : TXGBE_PMMBX_DATA_SIZE);
|
||||
|
||||
err = txgbe_hic_sr_write(hw, addr, buf, seg);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
len -= seg;
|
||||
buf += seg;
|
||||
}
|
||||
|
||||
hw->mac.release_swfw_sync(hw, mask);
|
||||
return err;
|
||||
}
|
||||
|
||||
s32 txgbe_ee_writew_sw(struct txgbe_hw *hw, u32 offset,
|
||||
u16 data)
|
||||
{
|
||||
const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
|
||||
u32 addr = hw->rom.sw_addr + (offset << 1);
|
||||
int err;
|
||||
|
||||
DEBUGFUNC("\n");
|
||||
|
||||
err = hw->mac.acquire_swfw_sync(hw, mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 2);
|
||||
|
||||
hw->mac.release_swfw_sync(hw, mask);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_ee_write32 - Read EEPROM word using a host interface cmd
|
||||
* @hw: pointer to hardware structure
|
||||
* @offset: offset of word in the EEPROM to read
|
||||
* @data: word read from the EEPROM
|
||||
*
|
||||
* Reads a 32 bit word from the EEPROM using the hostif.
|
||||
**/
|
||||
s32 txgbe_ee_write32(struct txgbe_hw *hw, u32 addr, u32 data)
|
||||
{
|
||||
const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
|
||||
int err;
|
||||
|
||||
err = hw->mac.acquire_swfw_sync(hw, mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 4);
|
||||
|
||||
hw->mac.release_swfw_sync(hw, mask);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_ee_write_buffer - Write EEPROM byte(s) using hostif
|
||||
* @hw: pointer to hardware structure
|
||||
* @addr: offset of bytes in the EEPROM to write
|
||||
* @len: number of bytes
|
||||
* @data: word(s) write to the EEPROM
|
||||
*
|
||||
* Write a 8 bit byte(s) to the EEPROM using the hostif.
|
||||
**/
|
||||
s32 txgbe_ee_write_buffer(struct txgbe_hw *hw,
|
||||
u32 addr, u32 len, void *data)
|
||||
{
|
||||
const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
|
||||
u8 *buf = (u8 *)data;
|
||||
int err;
|
||||
|
||||
err = hw->mac.acquire_swfw_sync(hw, mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
while (len) {
|
||||
u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
|
||||
? len : TXGBE_PMMBX_DATA_SIZE);
|
||||
|
||||
err = txgbe_hic_sr_write(hw, addr, buf, seg);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
len -= seg;
|
||||
buf += seg;
|
||||
}
|
||||
|
||||
hw->mac.release_swfw_sync(hw, mask);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_calc_eeprom_checksum - Calculates and returns the checksum
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Returns a negative error code on error, or the 16-bit checksum
|
||||
**/
|
||||
#define BUFF_SIZE 64
|
||||
s32 txgbe_calc_eeprom_checksum(struct txgbe_hw *hw)
|
||||
{
|
||||
u16 checksum = 0, read_checksum = 0;
|
||||
int i, j, seg;
|
||||
int err;
|
||||
u16 buffer[BUFF_SIZE];
|
||||
|
||||
DEBUGFUNC("txgbe_calc_eeprom_checksum");
|
||||
|
||||
err = hw->rom.readw_sw(hw, TXGBE_EEPROM_CHECKSUM, &read_checksum);
|
||||
if (err) {
|
||||
DEBUGOUT("EEPROM read failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i = 0; i < TXGBE_EE_CSUM_MAX; i += seg) {
|
||||
seg = (i + BUFF_SIZE < TXGBE_EE_CSUM_MAX
|
||||
? BUFF_SIZE : TXGBE_EE_CSUM_MAX - i);
|
||||
err = hw->rom.readw_buffer(hw, i, seg, buffer);
|
||||
if (err)
|
||||
return err;
|
||||
for (j = 0; j < seg; j++)
|
||||
checksum += buffer[j];
|
||||
}
|
||||
|
||||
checksum = (u16)TXGBE_EEPROM_SUM - checksum + read_checksum;
|
||||
|
||||
return (s32)checksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_validate_eeprom_checksum - Validate EEPROM checksum
|
||||
* @hw: pointer to hardware structure
|
||||
* @checksum_val: calculated checksum
|
||||
*
|
||||
* Performs checksum calculation and validates the EEPROM checksum. If the
|
||||
* caller does not need checksum_val, the value can be NULL.
|
||||
**/
|
||||
s32 txgbe_validate_eeprom_checksum(struct txgbe_hw *hw,
|
||||
u16 *checksum_val)
|
||||
{
|
||||
u16 checksum;
|
||||
u16 read_checksum = 0;
|
||||
int err;
|
||||
|
||||
DEBUGFUNC("txgbe_validate_eeprom_checksum");
|
||||
|
||||
/* Read the first word from the EEPROM. If this times out or fails, do
|
||||
* not continue or we could be in for a very long wait while every
|
||||
* EEPROM read fails
|
||||
*/
|
||||
err = hw->rom.read16(hw, 0, &checksum);
|
||||
if (err) {
|
||||
DEBUGOUT("EEPROM read failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
err = hw->rom.calc_checksum(hw);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
checksum = (u16)(err & 0xffff);
|
||||
|
||||
err = hw->rom.readw_sw(hw, TXGBE_EEPROM_CHECKSUM, &read_checksum);
|
||||
if (err) {
|
||||
DEBUGOUT("EEPROM read failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Verify read checksum from EEPROM is the same as
|
||||
* calculated checksum
|
||||
*/
|
||||
if (read_checksum != checksum) {
|
||||
err = TXGBE_ERR_EEPROM_CHECKSUM;
|
||||
DEBUGOUT("EEPROM checksum error\n");
|
||||
}
|
||||
|
||||
/* If the user cares, return the calculated checksum */
|
||||
if (checksum_val)
|
||||
*checksum_val = checksum;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_update_eeprom_checksum - Updates the EEPROM checksum
|
||||
* @hw: pointer to hardware structure
|
||||
**/
|
||||
s32 txgbe_update_eeprom_checksum(struct txgbe_hw *hw)
|
||||
{
|
||||
s32 status;
|
||||
u16 checksum;
|
||||
|
||||
DEBUGFUNC("txgbe_update_eeprom_checksum");
|
||||
|
||||
/* Read the first word from the EEPROM. If this times out or fails, do
|
||||
* not continue or we could be in for a very long wait while every
|
||||
* EEPROM read fails
|
||||
*/
|
||||
status = hw->rom.read16(hw, 0, &checksum);
|
||||
if (status) {
|
||||
DEBUGOUT("EEPROM read failed\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = hw->rom.calc_checksum(hw);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
checksum = (u16)(status & 0xffff);
|
||||
|
||||
status = hw->rom.writew_sw(hw, TXGBE_EEPROM_CHECKSUM, checksum);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
49
drivers/net/txgbe/base/txgbe_eeprom.h
Normal file
49
drivers/net/txgbe/base/txgbe_eeprom.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2015-2020
|
||||
*/
|
||||
|
||||
#ifndef _TXGBE_EEPROM_H_
|
||||
#define _TXGBE_EEPROM_H_
|
||||
|
||||
/* Checksum and EEPROM pointers */
|
||||
#define TXGBE_PBANUM_PTR_GUARD 0xFAFA
|
||||
#define TXGBE_EEPROM_SUM 0xBABA
|
||||
|
||||
#define TXGBE_FW_PTR 0x0F
|
||||
#define TXGBE_PBANUM0_PTR 0x05
|
||||
#define TXGBE_PBANUM1_PTR 0x06
|
||||
#define TXGBE_SW_REGION_PTR 0x1C
|
||||
|
||||
#define TXGBE_EE_CSUM_MAX 0x800
|
||||
#define TXGBE_EEPROM_CHECKSUM 0x2F
|
||||
|
||||
#define TXGBE_SAN_MAC_ADDR_PTR 0x18
|
||||
#define TXGBE_DEVICE_CAPS 0x1C
|
||||
#define TXGBE_EEPROM_VERSION_L 0x1D
|
||||
#define TXGBE_EEPROM_VERSION_H 0x1E
|
||||
#define TXGBE_ISCSI_BOOT_CONFIG 0x07
|
||||
|
||||
|
||||
s32 txgbe_init_eeprom_params(struct txgbe_hw *hw);
|
||||
s32 txgbe_calc_eeprom_checksum(struct txgbe_hw *hw);
|
||||
s32 txgbe_validate_eeprom_checksum(struct txgbe_hw *hw, u16 *checksum_val);
|
||||
s32 txgbe_update_eeprom_checksum(struct txgbe_hw *hw);
|
||||
s32 txgbe_get_eeprom_semaphore(struct txgbe_hw *hw);
|
||||
void txgbe_release_eeprom_semaphore(struct txgbe_hw *hw);
|
||||
|
||||
s32 txgbe_ee_read16(struct txgbe_hw *hw, u32 offset, u16 *data);
|
||||
s32 txgbe_ee_readw_sw(struct txgbe_hw *hw, u32 offset, u16 *data);
|
||||
s32 txgbe_ee_readw_buffer(struct txgbe_hw *hw, u32 offset, u32 words,
|
||||
void *data);
|
||||
s32 txgbe_ee_read32(struct txgbe_hw *hw, u32 addr, u32 *data);
|
||||
s32 txgbe_ee_read_buffer(struct txgbe_hw *hw, u32 addr, u32 len, void *data);
|
||||
|
||||
s32 txgbe_ee_write16(struct txgbe_hw *hw, u32 offset, u16 data);
|
||||
s32 txgbe_ee_writew_sw(struct txgbe_hw *hw, u32 offset, u16 data);
|
||||
s32 txgbe_ee_writew_buffer(struct txgbe_hw *hw, u32 offset, u32 words,
|
||||
void *data);
|
||||
s32 txgbe_ee_write32(struct txgbe_hw *hw, u32 addr, u32 data);
|
||||
s32 txgbe_ee_write_buffer(struct txgbe_hw *hw, u32 addr, u32 len, void *data);
|
||||
|
||||
|
||||
#endif /* _TXGBE_EEPROM_H_ */
|
@ -3,6 +3,7 @@
|
||||
*/
|
||||
|
||||
#include "txgbe_type.h"
|
||||
#include "txgbe_eeprom.h"
|
||||
#include "txgbe_hw.h"
|
||||
|
||||
#define TXGBE_RAPTOR_RAR_ENTRIES 128
|
||||
@ -135,13 +136,29 @@ s32 txgbe_init_ops_pf(struct txgbe_hw *hw)
|
||||
{
|
||||
struct txgbe_bus_info *bus = &hw->bus;
|
||||
struct txgbe_mac_info *mac = &hw->mac;
|
||||
struct txgbe_rom_info *rom = &hw->rom;
|
||||
|
||||
DEBUGFUNC("txgbe_init_ops_pf");
|
||||
|
||||
/* BUS */
|
||||
bus->set_lan_id = txgbe_set_lan_id_multi_port;
|
||||
|
||||
/* MAC */
|
||||
mac->num_rar_entries = TXGBE_RAPTOR_RAR_ENTRIES;
|
||||
|
||||
/* EEPROM */
|
||||
rom->init_params = txgbe_init_eeprom_params;
|
||||
rom->read16 = txgbe_ee_read16;
|
||||
rom->readw_buffer = txgbe_ee_readw_buffer;
|
||||
rom->readw_sw = txgbe_ee_readw_sw;
|
||||
rom->read32 = txgbe_ee_read32;
|
||||
rom->write16 = txgbe_ee_write16;
|
||||
rom->writew_buffer = txgbe_ee_writew_buffer;
|
||||
rom->writew_sw = txgbe_ee_writew_sw;
|
||||
rom->write32 = txgbe_ee_write32;
|
||||
rom->validate_checksum = txgbe_validate_eeprom_checksum;
|
||||
rom->update_checksum = txgbe_update_eeprom_checksum;
|
||||
rom->calc_checksum = txgbe_calc_eeprom_checksum;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
396
drivers/net/txgbe/base/txgbe_mng.c
Normal file
396
drivers/net/txgbe/base/txgbe_mng.c
Normal file
@ -0,0 +1,396 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2015-2020
|
||||
*/
|
||||
|
||||
#include "txgbe_type.h"
|
||||
#include "txgbe_mng.h"
|
||||
|
||||
/**
|
||||
* txgbe_calculate_checksum - Calculate checksum for buffer
|
||||
* @buffer: pointer to EEPROM
|
||||
* @length: size of EEPROM to calculate a checksum for
|
||||
* Calculates the checksum for some buffer on a specified length. The
|
||||
* checksum calculated is returned.
|
||||
**/
|
||||
static u8
|
||||
txgbe_calculate_checksum(u8 *buffer, u32 length)
|
||||
{
|
||||
u32 i;
|
||||
u8 sum = 0;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
sum += buffer[i];
|
||||
|
||||
return (u8)(0 - sum);
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_hic_unlocked - Issue command to manageability block unlocked
|
||||
* @hw: pointer to the HW structure
|
||||
* @buffer: command to write and where the return status will be placed
|
||||
* @length: length of buffer, must be multiple of 4 bytes
|
||||
* @timeout: time in ms to wait for command completion
|
||||
*
|
||||
* Communicates with the manageability block. On success return 0
|
||||
* else returns semaphore error when encountering an error acquiring
|
||||
* semaphore or TXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
|
||||
*
|
||||
* This function assumes that the TXGBE_MNGSEM_SWMBX semaphore is held
|
||||
* by the caller.
|
||||
**/
|
||||
static s32
|
||||
txgbe_hic_unlocked(struct txgbe_hw *hw, u32 *buffer, u32 length, u32 timeout)
|
||||
{
|
||||
u32 value, loop;
|
||||
u16 i, dword_len;
|
||||
|
||||
DEBUGFUNC("txgbe_hic_unlocked");
|
||||
|
||||
if (!length || length > TXGBE_PMMBX_BSIZE) {
|
||||
DEBUGOUT("Buffer length failure buffersize=%d.\n", length);
|
||||
return TXGBE_ERR_HOST_INTERFACE_COMMAND;
|
||||
}
|
||||
|
||||
/* Calculate length in DWORDs. We must be DWORD aligned */
|
||||
if (length % sizeof(u32)) {
|
||||
DEBUGOUT("Buffer length failure, not aligned to dword");
|
||||
return TXGBE_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
dword_len = length >> 2;
|
||||
|
||||
/* The device driver writes the relevant command block
|
||||
* into the ram area.
|
||||
*/
|
||||
for (i = 0; i < dword_len; i++) {
|
||||
wr32a(hw, TXGBE_MNGMBX, i, cpu_to_le32(buffer[i]));
|
||||
buffer[i] = rd32a(hw, TXGBE_MNGMBX, i);
|
||||
}
|
||||
txgbe_flush(hw);
|
||||
|
||||
/* Setting this bit tells the ARC that a new command is pending. */
|
||||
wr32m(hw, TXGBE_MNGMBXCTL,
|
||||
TXGBE_MNGMBXCTL_SWRDY, TXGBE_MNGMBXCTL_SWRDY);
|
||||
|
||||
/* Check command completion */
|
||||
loop = po32m(hw, TXGBE_MNGMBXCTL,
|
||||
TXGBE_MNGMBXCTL_FWRDY, TXGBE_MNGMBXCTL_FWRDY,
|
||||
&value, timeout, 1000);
|
||||
if (!loop || !(value & TXGBE_MNGMBXCTL_FWACK)) {
|
||||
DEBUGOUT("Command has failed with no status valid.\n");
|
||||
return TXGBE_ERR_HOST_INTERFACE_COMMAND;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_host_interface_command - Issue command to manageability block
|
||||
* @hw: pointer to the HW structure
|
||||
* @buffer: contains the command to write and where the return status will
|
||||
* be placed
|
||||
* @length: length of buffer, must be multiple of 4 bytes
|
||||
* @timeout: time in ms to wait for command completion
|
||||
* @return_data: read and return data from the buffer (true) or not (false)
|
||||
* Needed because FW structures are big endian and decoding of
|
||||
* these fields can be 8 bit or 16 bit based on command. Decoding
|
||||
* is not easily understood without making a table of commands.
|
||||
* So we will leave this up to the caller to read back the data
|
||||
* in these cases.
|
||||
*
|
||||
* Communicates with the manageability block. On success return 0
|
||||
* else returns semaphore error when encountering an error acquiring
|
||||
* semaphore or TXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
|
||||
**/
|
||||
static s32
|
||||
txgbe_host_interface_command(struct txgbe_hw *hw, u32 *buffer,
|
||||
u32 length, u32 timeout, bool return_data)
|
||||
{
|
||||
u32 hdr_size = sizeof(struct txgbe_hic_hdr);
|
||||
struct txgbe_hic_hdr *resp = (struct txgbe_hic_hdr *)buffer;
|
||||
u16 buf_len;
|
||||
s32 err;
|
||||
u32 bi;
|
||||
u32 dword_len;
|
||||
|
||||
DEBUGFUNC("txgbe_host_interface_command");
|
||||
|
||||
if (length == 0 || length > TXGBE_PMMBX_BSIZE) {
|
||||
DEBUGOUT("Buffer length failure buffersize=%d.\n", length);
|
||||
return TXGBE_ERR_HOST_INTERFACE_COMMAND;
|
||||
}
|
||||
|
||||
/* Take management host interface semaphore */
|
||||
err = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWMBX);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = txgbe_hic_unlocked(hw, buffer, length, timeout);
|
||||
if (err)
|
||||
goto rel_out;
|
||||
|
||||
if (!return_data)
|
||||
goto rel_out;
|
||||
|
||||
/* Calculate length in DWORDs */
|
||||
dword_len = hdr_size >> 2;
|
||||
|
||||
/* first pull in the header so we know the buffer length */
|
||||
for (bi = 0; bi < dword_len; bi++)
|
||||
buffer[bi] = rd32a(hw, TXGBE_MNGMBX, bi);
|
||||
|
||||
/*
|
||||
* If there is any thing in data position pull it in
|
||||
* Read Flash command requires reading buffer length from
|
||||
* two byes instead of one byte
|
||||
*/
|
||||
if (resp->cmd == 0x30) {
|
||||
for (; bi < dword_len + 2; bi++)
|
||||
buffer[bi] = rd32a(hw, TXGBE_MNGMBX, bi);
|
||||
|
||||
buf_len = (((u16)(resp->cmd_or_resp.ret_status) << 3)
|
||||
& 0xF00) | resp->buf_len;
|
||||
hdr_size += (2 << 2);
|
||||
} else {
|
||||
buf_len = resp->buf_len;
|
||||
}
|
||||
if (!buf_len)
|
||||
goto rel_out;
|
||||
|
||||
if (length < buf_len + hdr_size) {
|
||||
DEBUGOUT("Buffer not large enough for reply message.\n");
|
||||
err = TXGBE_ERR_HOST_INTERFACE_COMMAND;
|
||||
goto rel_out;
|
||||
}
|
||||
|
||||
/* Calculate length in DWORDs, add 3 for odd lengths */
|
||||
dword_len = (buf_len + 3) >> 2;
|
||||
|
||||
/* Pull in the rest of the buffer (bi is where we left off) */
|
||||
for (; bi <= dword_len; bi++)
|
||||
buffer[bi] = rd32a(hw, TXGBE_MNGMBX, bi);
|
||||
|
||||
rel_out:
|
||||
hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWMBX);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_hic_sr_read - Read EEPROM word using a host interface cmd
|
||||
* assuming that the semaphore is already obtained.
|
||||
* @hw: pointer to hardware structure
|
||||
* @offset: offset of word in the EEPROM to read
|
||||
* @data: word read from the EEPROM
|
||||
*
|
||||
* Reads a 16 bit word from the EEPROM using the hostif.
|
||||
**/
|
||||
s32 txgbe_hic_sr_read(struct txgbe_hw *hw, u32 addr, u8 *buf, int len)
|
||||
{
|
||||
struct txgbe_hic_read_shadow_ram command;
|
||||
u32 value;
|
||||
int err, i = 0, j = 0;
|
||||
|
||||
if (len > TXGBE_PMMBX_DATA_SIZE)
|
||||
return TXGBE_ERR_HOST_INTERFACE_COMMAND;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
command.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
|
||||
command.hdr.req.buf_lenh = 0;
|
||||
command.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
|
||||
command.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
|
||||
command.address = cpu_to_be32(addr);
|
||||
command.length = cpu_to_be16(len);
|
||||
|
||||
err = txgbe_hic_unlocked(hw, (u32 *)&command,
|
||||
sizeof(command), TXGBE_HI_COMMAND_TIMEOUT);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
while (i < (len >> 2)) {
|
||||
value = rd32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + i);
|
||||
((u32 *)buf)[i] = value;
|
||||
i++;
|
||||
}
|
||||
|
||||
value = rd32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + i);
|
||||
for (i <<= 2; i < len; i++)
|
||||
((u8 *)buf)[i] = ((u8 *)&value)[j++];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_hic_sr_write - Write EEPROM word using hostif
|
||||
* @hw: pointer to hardware structure
|
||||
* @offset: offset of word in the EEPROM to write
|
||||
* @data: word write to the EEPROM
|
||||
*
|
||||
* Write a 16 bit word to the EEPROM using the hostif.
|
||||
**/
|
||||
s32 txgbe_hic_sr_write(struct txgbe_hw *hw, u32 addr, u8 *buf, int len)
|
||||
{
|
||||
struct txgbe_hic_write_shadow_ram command;
|
||||
u32 value;
|
||||
int err = 0, i = 0, j = 0;
|
||||
|
||||
if (len > TXGBE_PMMBX_DATA_SIZE)
|
||||
return TXGBE_ERR_HOST_INTERFACE_COMMAND;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
command.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
|
||||
command.hdr.req.buf_lenh = 0;
|
||||
command.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
|
||||
command.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
|
||||
command.address = cpu_to_be32(addr);
|
||||
command.length = cpu_to_be16(len);
|
||||
|
||||
while (i < (len >> 2)) {
|
||||
value = ((u32 *)buf)[i];
|
||||
wr32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + i, value);
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i <<= 2; i < len; i++)
|
||||
((u8 *)&value)[j++] = ((u8 *)buf)[i];
|
||||
|
||||
wr32a(hw, TXGBE_MNGMBX, FW_NVM_DATA_OFFSET + (i >> 2), value);
|
||||
|
||||
UNREFERENCED_PARAMETER(&command);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_hic_set_drv_ver - Sends driver version to firmware
|
||||
* @hw: pointer to the HW structure
|
||||
* @maj: driver version major number
|
||||
* @min: driver version minor number
|
||||
* @build: driver version build number
|
||||
* @sub: driver version sub build number
|
||||
* @len: unused
|
||||
* @driver_ver: unused
|
||||
*
|
||||
* Sends driver version number to firmware through the manageability
|
||||
* block. On success return 0
|
||||
* else returns TXGBE_ERR_SWFW_SYNC when encountering an error acquiring
|
||||
* semaphore or TXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
|
||||
**/
|
||||
s32 txgbe_hic_set_drv_ver(struct txgbe_hw *hw, u8 maj, u8 min,
|
||||
u8 build, u8 sub, u16 len,
|
||||
const char *driver_ver)
|
||||
{
|
||||
struct txgbe_hic_drv_info fw_cmd;
|
||||
int i;
|
||||
s32 ret_val = 0;
|
||||
|
||||
DEBUGFUNC("txgbe_hic_set_drv_ver");
|
||||
UNREFERENCED_PARAMETER(len, driver_ver);
|
||||
|
||||
fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
|
||||
fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN;
|
||||
fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
|
||||
fw_cmd.port_num = (u8)hw->bus.func;
|
||||
fw_cmd.ver_maj = maj;
|
||||
fw_cmd.ver_min = min;
|
||||
fw_cmd.ver_build = build;
|
||||
fw_cmd.ver_sub = sub;
|
||||
fw_cmd.hdr.checksum = 0;
|
||||
fw_cmd.pad = 0;
|
||||
fw_cmd.pad2 = 0;
|
||||
fw_cmd.hdr.checksum = txgbe_calculate_checksum((u8 *)&fw_cmd,
|
||||
(FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
|
||||
|
||||
for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
|
||||
ret_val = txgbe_host_interface_command(hw, (u32 *)&fw_cmd,
|
||||
sizeof(fw_cmd),
|
||||
TXGBE_HI_COMMAND_TIMEOUT,
|
||||
true);
|
||||
if (ret_val != 0)
|
||||
continue;
|
||||
|
||||
if (fw_cmd.hdr.cmd_or_resp.ret_status ==
|
||||
FW_CEM_RESP_STATUS_SUCCESS)
|
||||
ret_val = 0;
|
||||
else
|
||||
ret_val = TXGBE_ERR_HOST_INTERFACE_COMMAND;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_hic_reset - send reset cmd to fw
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Sends reset cmd to firmware through the manageability
|
||||
* block. On success return 0
|
||||
* else returns TXGBE_ERR_SWFW_SYNC when encountering an error acquiring
|
||||
* semaphore or TXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
|
||||
**/
|
||||
s32
|
||||
txgbe_hic_reset(struct txgbe_hw *hw)
|
||||
{
|
||||
struct txgbe_hic_reset reset_cmd;
|
||||
int i;
|
||||
s32 err = 0;
|
||||
|
||||
DEBUGFUNC("\n");
|
||||
|
||||
reset_cmd.hdr.cmd = FW_RESET_CMD;
|
||||
reset_cmd.hdr.buf_len = FW_RESET_LEN;
|
||||
reset_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
|
||||
reset_cmd.lan_id = hw->bus.lan_id;
|
||||
reset_cmd.reset_type = (u16)hw->reset_type;
|
||||
reset_cmd.hdr.checksum = 0;
|
||||
reset_cmd.hdr.checksum = txgbe_calculate_checksum((u8 *)&reset_cmd,
|
||||
(FW_CEM_HDR_LEN + reset_cmd.hdr.buf_len));
|
||||
|
||||
for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
|
||||
err = txgbe_host_interface_command(hw, (u32 *)&reset_cmd,
|
||||
sizeof(reset_cmd),
|
||||
TXGBE_HI_COMMAND_TIMEOUT,
|
||||
true);
|
||||
if (err != 0)
|
||||
continue;
|
||||
|
||||
if (reset_cmd.hdr.cmd_or_resp.ret_status ==
|
||||
FW_CEM_RESP_STATUS_SUCCESS)
|
||||
err = 0;
|
||||
else
|
||||
err = TXGBE_ERR_HOST_INTERFACE_COMMAND;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_mng_present - returns true when management capability is present
|
||||
* @hw: pointer to hardware structure
|
||||
*/
|
||||
bool
|
||||
txgbe_mng_present(struct txgbe_hw *hw)
|
||||
{
|
||||
if (hw->mac.type == txgbe_mac_unknown)
|
||||
return false;
|
||||
|
||||
return !!rd32m(hw, TXGBE_STAT, TXGBE_STAT_MNGINIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_mng_enabled - Is the manageability engine enabled?
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Returns true if the manageability engine is enabled.
|
||||
**/
|
||||
bool
|
||||
txgbe_mng_enabled(struct txgbe_hw *hw)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(hw);
|
||||
/* firmware does not control laser */
|
||||
return false;
|
||||
}
|
176
drivers/net/txgbe/base/txgbe_mng.h
Normal file
176
drivers/net/txgbe/base/txgbe_mng.h
Normal file
@ -0,0 +1,176 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2015-2020
|
||||
*/
|
||||
|
||||
#ifndef _TXGBE_MNG_H_
|
||||
#define _TXGBE_MNG_H_
|
||||
|
||||
#include "txgbe_type.h"
|
||||
|
||||
|
||||
#define TXGBE_PMMBX_QSIZE 64 /* Num of dwords in range */
|
||||
#define TXGBE_PMMBX_BSIZE (TXGBE_PMMBX_QSIZE * 4)
|
||||
#define TXGBE_PMMBX_DATA_SIZE (TXGBE_PMMBX_BSIZE - FW_NVM_DATA_OFFSET * 4)
|
||||
#define TXGBE_HI_COMMAND_TIMEOUT 5000 /* Process HI command limit */
|
||||
#define TXGBE_HI_FLASH_ERASE_TIMEOUT 5000 /* Process Erase command limit */
|
||||
#define TXGBE_HI_FLASH_UPDATE_TIMEOUT 5000 /* Process Update command limit */
|
||||
#define TXGBE_HI_FLASH_VERIFY_TIMEOUT 60000 /* Process Apply command limit */
|
||||
#define TXGBE_HI_PHY_MGMT_REQ_TIMEOUT 2000 /* Wait up to 2 seconds */
|
||||
|
||||
/* CEM Support */
|
||||
#define FW_CEM_HDR_LEN 0x4
|
||||
#define FW_CEM_CMD_DRIVER_INFO 0xDD
|
||||
#define FW_CEM_CMD_DRIVER_INFO_LEN 0x5
|
||||
#define FW_CEM_CMD_RESERVED 0X0
|
||||
#define FW_CEM_UNUSED_VER 0x0
|
||||
#define FW_CEM_MAX_RETRIES 3
|
||||
#define FW_CEM_RESP_STATUS_SUCCESS 0x1
|
||||
#define FW_READ_SHADOW_RAM_CMD 0x31
|
||||
#define FW_READ_SHADOW_RAM_LEN 0x6
|
||||
#define FW_WRITE_SHADOW_RAM_CMD 0x33
|
||||
#define FW_WRITE_SHADOW_RAM_LEN 0xA /* 8 plus 1 WORD to write */
|
||||
#define FW_SHADOW_RAM_DUMP_CMD 0x36
|
||||
#define FW_SHADOW_RAM_DUMP_LEN 0
|
||||
#define FW_DEFAULT_CHECKSUM 0xFF /* checksum always 0xFF */
|
||||
#define FW_NVM_DATA_OFFSET 3
|
||||
#define FW_MAX_READ_BUFFER_SIZE 244
|
||||
#define FW_DISABLE_RXEN_CMD 0xDE
|
||||
#define FW_DISABLE_RXEN_LEN 0x1
|
||||
#define FW_PHY_MGMT_REQ_CMD 0x20
|
||||
#define FW_RESET_CMD 0xDF
|
||||
#define FW_RESET_LEN 0x2
|
||||
#define FW_SETUP_MAC_LINK_CMD 0xE0
|
||||
#define FW_SETUP_MAC_LINK_LEN 0x2
|
||||
#define FW_FLASH_UPGRADE_START_CMD 0xE3
|
||||
#define FW_FLASH_UPGRADE_START_LEN 0x1
|
||||
#define FW_FLASH_UPGRADE_WRITE_CMD 0xE4
|
||||
#define FW_FLASH_UPGRADE_VERIFY_CMD 0xE5
|
||||
#define FW_FLASH_UPGRADE_VERIFY_LEN 0x4
|
||||
#define FW_PHY_ACT_DATA_COUNT 4
|
||||
#define FW_PHY_TOKEN_DELAY 5 /* milliseconds */
|
||||
#define FW_PHY_TOKEN_WAIT 5 /* seconds */
|
||||
#define FW_PHY_TOKEN_RETRIES ((FW_PHY_TOKEN_WAIT * 1000) / FW_PHY_TOKEN_DELAY)
|
||||
|
||||
/* Host Interface Command Structures */
|
||||
struct txgbe_hic_hdr {
|
||||
u8 cmd;
|
||||
u8 buf_len;
|
||||
union {
|
||||
u8 cmd_resv;
|
||||
u8 ret_status;
|
||||
} cmd_or_resp;
|
||||
u8 checksum;
|
||||
};
|
||||
|
||||
struct txgbe_hic_hdr2_req {
|
||||
u8 cmd;
|
||||
u8 buf_lenh;
|
||||
u8 buf_lenl;
|
||||
u8 checksum;
|
||||
};
|
||||
|
||||
struct txgbe_hic_hdr2_rsp {
|
||||
u8 cmd;
|
||||
u8 buf_lenl;
|
||||
u8 buf_lenh_status; /* 7-5: high bits of buf_len, 4-0: status */
|
||||
u8 checksum;
|
||||
};
|
||||
|
||||
union txgbe_hic_hdr2 {
|
||||
struct txgbe_hic_hdr2_req req;
|
||||
struct txgbe_hic_hdr2_rsp rsp;
|
||||
};
|
||||
|
||||
struct txgbe_hic_drv_info {
|
||||
struct txgbe_hic_hdr hdr;
|
||||
u8 port_num;
|
||||
u8 ver_sub;
|
||||
u8 ver_build;
|
||||
u8 ver_min;
|
||||
u8 ver_maj;
|
||||
u8 pad; /* end spacing to ensure length is mult. of dword */
|
||||
u16 pad2; /* end spacing to ensure length is mult. of dword2 */
|
||||
};
|
||||
|
||||
/* These need to be dword aligned */
|
||||
struct txgbe_hic_read_shadow_ram {
|
||||
union txgbe_hic_hdr2 hdr;
|
||||
u32 address;
|
||||
u16 length;
|
||||
u16 pad2;
|
||||
u16 data;
|
||||
u16 pad3;
|
||||
};
|
||||
|
||||
struct txgbe_hic_write_shadow_ram {
|
||||
union txgbe_hic_hdr2 hdr;
|
||||
u32 address;
|
||||
u16 length;
|
||||
u16 pad2;
|
||||
u16 data;
|
||||
u16 pad3;
|
||||
};
|
||||
|
||||
struct txgbe_hic_disable_rxen {
|
||||
struct txgbe_hic_hdr hdr;
|
||||
u8 port_number;
|
||||
u8 pad2;
|
||||
u16 pad3;
|
||||
};
|
||||
|
||||
struct txgbe_hic_reset {
|
||||
struct txgbe_hic_hdr hdr;
|
||||
u16 lan_id;
|
||||
u16 reset_type;
|
||||
};
|
||||
|
||||
struct txgbe_hic_phy_cfg {
|
||||
struct txgbe_hic_hdr hdr;
|
||||
u8 lan_id;
|
||||
u8 phy_mode;
|
||||
u16 phy_speed;
|
||||
};
|
||||
|
||||
enum txgbe_module_id {
|
||||
TXGBE_MODULE_EEPROM = 0,
|
||||
TXGBE_MODULE_FIRMWARE,
|
||||
TXGBE_MODULE_HARDWARE,
|
||||
TXGBE_MODULE_PCIE
|
||||
};
|
||||
|
||||
struct txgbe_hic_upg_start {
|
||||
struct txgbe_hic_hdr hdr;
|
||||
u8 module_id;
|
||||
u8 pad2;
|
||||
u16 pad3;
|
||||
};
|
||||
|
||||
struct txgbe_hic_upg_write {
|
||||
struct txgbe_hic_hdr hdr;
|
||||
u8 data_len;
|
||||
u8 eof_flag;
|
||||
u16 check_sum;
|
||||
u32 data[62];
|
||||
};
|
||||
|
||||
enum txgbe_upg_flag {
|
||||
TXGBE_RESET_NONE = 0,
|
||||
TXGBE_RESET_FIRMWARE,
|
||||
TXGBE_RELOAD_EEPROM,
|
||||
TXGBE_RESET_LAN
|
||||
};
|
||||
|
||||
struct txgbe_hic_upg_verify {
|
||||
struct txgbe_hic_hdr hdr;
|
||||
u32 action_flag;
|
||||
};
|
||||
|
||||
s32 txgbe_hic_sr_read(struct txgbe_hw *hw, u32 addr, u8 *buf, int len);
|
||||
s32 txgbe_hic_sr_write(struct txgbe_hw *hw, u32 addr, u8 *buf, int len);
|
||||
|
||||
s32 txgbe_hic_set_drv_ver(struct txgbe_hw *hw, u8 maj, u8 min, u8 build,
|
||||
u8 ver, u16 len, const char *str);
|
||||
s32 txgbe_hic_reset(struct txgbe_hw *hw);
|
||||
bool txgbe_mng_present(struct txgbe_hw *hw);
|
||||
bool txgbe_mng_enabled(struct txgbe_hw *hw);
|
||||
#endif /* _TXGBE_MNG_H_ */
|
@ -13,6 +13,13 @@
|
||||
#include "txgbe_osdep.h"
|
||||
#include "txgbe_devids.h"
|
||||
|
||||
enum txgbe_eeprom_type {
|
||||
txgbe_eeprom_unknown = 0,
|
||||
txgbe_eeprom_spi,
|
||||
txgbe_eeprom_flash,
|
||||
txgbe_eeprom_none /* No NVM support */
|
||||
};
|
||||
|
||||
enum txgbe_mac_type {
|
||||
txgbe_mac_unknown = 0,
|
||||
txgbe_mac_raptor,
|
||||
@ -177,6 +184,15 @@ struct txgbe_rom_info {
|
||||
s32 (*validate_checksum)(struct txgbe_hw *hw, u16 *checksum_val);
|
||||
s32 (*update_checksum)(struct txgbe_hw *hw);
|
||||
s32 (*calc_checksum)(struct txgbe_hw *hw);
|
||||
|
||||
enum txgbe_eeprom_type type;
|
||||
u32 semaphore_delay;
|
||||
u16 word_size;
|
||||
u16 address_bits;
|
||||
u16 word_page_size;
|
||||
u16 ctrl_word_3;
|
||||
|
||||
u32 sw_addr;
|
||||
};
|
||||
|
||||
struct txgbe_flash_info {
|
||||
@ -357,6 +373,11 @@ struct txgbe_hw {
|
||||
|
||||
uint64_t isb_dma;
|
||||
void IOMEM *isb_mem;
|
||||
enum txgbe_reset_type {
|
||||
TXGBE_LAN_RESET = 0,
|
||||
TXGBE_SW_RESET,
|
||||
TXGBE_GLOBAL_RESET
|
||||
} reset_type;
|
||||
};
|
||||
|
||||
#include "txgbe_regs.h"
|
||||
|
@ -51,6 +51,7 @@ eth_txgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
|
||||
struct txgbe_hw *hw = TXGBE_DEV_HW(eth_dev);
|
||||
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
|
||||
const struct rte_memzone *mz;
|
||||
uint16_t csum;
|
||||
int err;
|
||||
|
||||
PMD_INIT_FUNC_TRACE();
|
||||
@ -81,6 +82,19 @@ eth_txgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
err = hw->rom.init_params(hw);
|
||||
if (err != 0) {
|
||||
PMD_INIT_LOG(ERR, "The EEPROM init failed: %d", err);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Make sure we have a good EEPROM before we read from it */
|
||||
err = hw->rom.validate_checksum(hw, &csum);
|
||||
if (err != 0) {
|
||||
PMD_INIT_LOG(ERR, "The EEPROM checksum is not valid: %d", err);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Allocate memory for storing MAC addresses */
|
||||
eth_dev->data->mac_addrs = rte_zmalloc("txgbe", RTE_ETHER_ADDR_LEN *
|
||||
hw->mac.num_rar_entries, 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user