#include "lm5710.h"
#include "hw_dump.h"
#include "577xx_int_offsets.h"
void ecore_init_cmng(const struct cmng_init_input *input_data,
struct cmng_init *ram_data);
void ecore_init_max_per_vn(u16_t vnic_max_rate,
struct rate_shaping_vars_per_vn *ram_data);
#define IS_VALID_NIG_IDX(_idx) ((_idx != ECORE_LLH_CAM_ETH_LINE) && (_idx != ECORE_LLH_CAM_ISCSI_ETH_LINE))
#define INVALID_NIG_OFFSET ((u8_t)-1)
void lm_cmng_init(struct _lm_device_t *pdev, u32_t port_rate)
{
u8_t vnic = 0;
u32_t i = 0;
u32_t* buf = NULL;
u8_t all_zero = 0;
u8_t num_vnics = pdev->params.vnics_per_port;
const u8_t b_afex_and_non_pmf = IS_MF_AFEX_MODE(pdev) && (!IS_PMF(pdev));
const u8_t port_id = PORT_ID(pdev);
const u8_t vnic_id = VNIC_ID(pdev);
static const u8_t DEF_MIN_RATE = 1 ;
struct cmng_init_input input_data = {0};
struct cmng_init ram_data = {{{0}}};
if(IS_MULTI_VNIC(pdev) && pdev->params.cmng_enable)
{
SET_FLAGS(input_data.flags.cmng_enables, CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN);
input_data.port_rate = port_rate;
all_zero = TRUE;
for (vnic = 0 ; vnic < num_vnics ; vnic++)
{
input_data.vnic_max_rate[vnic] = lm_get_max_bw(pdev,
port_rate,
vnic);
if (!GET_FLAGS(pdev->hw_info.mf_info.func_mf_cfg , FUNC_MF_CFG_FUNC_HIDE))
{
if (pdev->hw_info.mf_info.min_bw[vnic] == 0)
{
input_data.vnic_min_rate[vnic] = DEF_MIN_RATE;
}
else
{
input_data.vnic_min_rate[vnic] = pdev->hw_info.mf_info.min_bw[vnic];
all_zero = FALSE;
}
}
}
if (!(all_zero || LM_DCBX_ETS_IS_ENABLED(pdev)))
{
SET_FLAGS(input_data.flags.cmng_enables,CMNG_FLAGS_PER_PORT_FAIRNESS_VN);
}
if( b_afex_and_non_pmf )
{
ecore_init_max_per_vn( input_data.vnic_max_rate[vnic_id], &ram_data.vnic.vnic_max_rate[vnic_id] );
}
else
{
ecore_init_cmng(&input_data,&ram_data);
}
}
for (vnic = 0; vnic < ARRSIZE(ram_data.vnic.vnic_max_rate); vnic++)
{
buf = (u32_t *)&ram_data.vnic.vnic_max_rate[vnic];
ASSERT_STATIC(0 == sizeof(ram_data.vnic.vnic_max_rate[vnic]) % 4);
if( b_afex_and_non_pmf && (vnic != vnic_id) )
{
continue;
}
for (i = 0; i < sizeof(ram_data.vnic.vnic_max_rate[vnic])/4; i++)
{
LM_INTMEM_WRITE32(pdev,XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET((port_id+2*vnic))+i*4,
buf[i], BAR_XSTRORM_INTMEM);
}
}
if( b_afex_and_non_pmf )
{
return;
}
buf = (u32_t *)&ram_data.port.rs_vars;
ASSERT_STATIC(0 == (sizeof(ram_data.port.rs_vars) % 4)) ;
for (i = 0; i < sizeof(ram_data.port.rs_vars)/4; i++)
{
LM_INTMEM_WRITE32(pdev,(XSTORM_CMNG_PER_PORT_VARS_OFFSET(port_id) + OFFSETOF(struct cmng_struct_per_port, rs_vars) + i*4),
buf[i], BAR_XSTRORM_INTMEM);
}
buf = (u32_t *)&ram_data.port.fair_vars;
ASSERT_STATIC(0 == (sizeof(ram_data.port.fair_vars) % 4)) ;
for (i = 0; i < sizeof(ram_data.port.fair_vars)/4; i++)
{
LM_INTMEM_WRITE32(pdev,(XSTORM_CMNG_PER_PORT_VARS_OFFSET(port_id) + OFFSETOF(struct cmng_struct_per_port, fair_vars) + i*4),
buf[i], BAR_XSTRORM_INTMEM);
}
buf = (u32_t *)&ram_data.port.flags;
ASSERT_STATIC(0 == (sizeof(ram_data.port.flags) % 4));
for (i = 0; i < sizeof(ram_data.port.flags)/4; i++)
{
LM_INTMEM_WRITE32(pdev,(XSTORM_CMNG_PER_PORT_VARS_OFFSET(port_id) + OFFSETOF(struct cmng_struct_per_port, flags) + i*4),
buf[i], BAR_XSTRORM_INTMEM);
}
for (vnic = 0; vnic < ARRSIZE(ram_data.vnic.vnic_min_rate); vnic++)
{
buf = (u32_t *)&ram_data.vnic.vnic_min_rate[vnic];
ASSERT_STATIC(0 == sizeof(ram_data.vnic.vnic_min_rate[vnic]) % 4);
for (i = 0; i < sizeof(ram_data.vnic.vnic_min_rate[vnic])/4; i++)
{
LM_INTMEM_WRITE32(pdev,XSTORM_FAIRNESS_PER_VN_VARS_OFFSET((port_id+2*vnic))+i*4,
buf[i], BAR_XSTRORM_INTMEM);
}
}
}
static lm_status_t lm_initialize_nig_entry(
lm_device_t *pdev,
u8_t offset,
u8_t *addr)
{
lm_nig_mirror_entry_t* entry = &pdev->vars.nig_mirror.entries[offset];
DbgBreakIf(entry->refcnt != 0);
mm_memcpy(entry->addr, addr, ARRSIZE(entry->addr));
return LM_STATUS_SUCCESS;
}
static u8_t lm_get_available_nig_entry(lm_device_t *pdev)
{
u8_t i;
lm_nig_mirror_t *nig_mirror = &pdev->vars.nig_mirror;
for (i=0; i<ARRSIZE(nig_mirror->entries); ++i)
{
if (IS_VALID_NIG_IDX(i) &&
(nig_mirror->entries[i].refcnt == 0))
{
return i;
}
}
return INVALID_NIG_OFFSET;
}
static u8_t lm_find_nig_entry_for_addr(
lm_device_t *pdev,
u8_t *addr)
{
u8_t i;
lm_nig_mirror_t *nig_mirror = &pdev->vars.nig_mirror;
lm_nig_mirror_entry_t* cur_entry = NULL;
for (i=0; i<ARRSIZE(nig_mirror->entries); ++i)
{
cur_entry = &nig_mirror->entries[i];
if ( (cur_entry->refcnt > 0) &&
(mm_memcmp(cur_entry->addr, addr, ARRSIZE(cur_entry->addr))) )
{
return i;
}
}
return INVALID_NIG_OFFSET;
}
lm_status_t lm_insert_nig_entry(
lm_device_t *pdev,
u8_t *addr)
{
u8_t offset = 0;
lm_status_t lm_status = LM_STATUS_SUCCESS;
offset = lm_find_nig_entry_for_addr(pdev, addr);
if (offset == INVALID_NIG_OFFSET)
{
offset = lm_get_available_nig_entry(pdev);
if (offset == INVALID_NIG_OFFSET)
{
return LM_STATUS_RESOURCE;
}
lm_status = lm_initialize_nig_entry(pdev, offset, addr);
DbgBreakIf (lm_status != LM_STATUS_SUCCESS);
lm_status = lm_set_mac_in_nig(pdev, addr, LM_CLI_IDX_NDIS, offset);
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
}
NIG_ENTRY_INC_REFCNT(&pdev->vars.nig_mirror.entries[offset]);
return lm_status;
}
lm_status_t lm_remove_nig_entry(
lm_device_t *pdev,
u8_t *addr)
{
u8_t offset = 0;
lm_status_t lm_status = LM_STATUS_SUCCESS;
lm_nig_mirror_entry_t* entry = NULL;
offset = lm_find_nig_entry_for_addr(pdev, addr);
if (offset == INVALID_NIG_OFFSET)
{
DbgBreakIf(offset == INVALID_NIG_OFFSET);
return LM_STATUS_FAILURE;
}
entry = &pdev->vars.nig_mirror.entries[offset];
NIG_ENTRY_DEC_REFCNT(entry);
if (entry->refcnt == 0)
{
lm_status = lm_set_mac_in_nig(pdev, NULL, LM_CLI_IDX_NDIS, offset);
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
mm_mem_zero(entry->addr, sizeof(entry->addr));
}
return lm_status;
}
void lm_setup_fan_failure_detection(struct _lm_device_t *pdev)
{
u32_t val = 0;
lm_status_t lm_status = LM_STATUS_SUCCESS;
u8_t port = 0;
u8_t is_required = FALSE;
u32 offset = 0;
offset = OFFSETOF(shmem_region_t, dev_info.shared_hw_config.config2) ;
LM_SHMEM_READ(pdev, offset, &val);
val &= SHARED_HW_CFG_FAN_FAILURE_MASK;
switch(val)
{
case SHARED_HW_CFG_FAN_FAILURE_PHY_TYPE:
{
for (port = PORT_0; port < PORT_MAX; port++)
{
is_required |= elink_fan_failure_det_req(pdev, pdev->hw_info.shmem_base, pdev->hw_info.shmem_base2, port);
}
}
break;
case SHARED_HW_CFG_FAN_FAILURE_ENABLED:
is_required = TRUE;
break;
case SHARED_HW_CFG_FAN_FAILURE_DISABLED:
default:
break;
}
DbgMessage(pdev, WARN, "lm_setup_fan_failure_detection: cfg=0x%x is_required=%d\n", val, is_required );
if (!is_required)
{
return;
}
lm_status = lm_spio_read( pdev, 5, &val ) ;
if( LM_STATUS_SUCCESS != lm_status )
{
DbgBreakIf(1) ;
}
val = REG_RD(pdev,MISC_REG_SPIO_INT) ;
val |= (1<<(16+5)) ;
REG_WR(pdev,MISC_REG_SPIO_INT, val ) ;
val = REG_RD(pdev,MISC_REG_SPIO_EVENT_EN) ;
val |= (1<<5) ;
REG_WR(pdev,MISC_REG_SPIO_EVENT_EN, val ) ;
}
lm_status_t lm_gpio_read(struct _lm_device_t *pdev, u32_t pin_num, u32_t* value_ptr, u8_t port)
{
u32_t reg_val = 0;
u32_t gpio_port = 0;
u32_t mask = 0;
u32_t swap_val = 0;
u32_t swap_override = 0;
if ( CHK_NULL(pdev) || CHK_NULL(value_ptr) )
{
DbgBreakIf(!pdev);
DbgBreakIf(!value_ptr);
return LM_STATUS_INVALID_PARAMETER ;
}
if (pin_num > MISC_REGISTERS_GPIO_3)
{
DbgMessage(pdev, FATAL , "Invalid pin_num GPIO %d\n", pin_num);
return LM_STATUS_INVALID_PARAMETER;
}
swap_val = REG_RD(pdev, NIG_REG_PORT_SWAP);
swap_override = REG_RD(pdev, NIG_REG_STRAP_OVERRIDE);
gpio_port = (swap_val && swap_override) ^ port;
if (gpio_port > 1)
{
return LM_STATUS_FAILURE;
}
if (gpio_port == 0)
{
switch (pin_num)
{
case 0:
mask = GRC_MISC_REGISTERS_GPIO_PORT0_VAL0;
break;
case 1:
mask = GRC_MISC_REGISTERS_GPIO_PORT0_VAL1;
break;
case 2:
mask = GRC_MISC_REGISTERS_GPIO_PORT0_VAL2;
break;
case 3:
mask = GRC_MISC_REGISTERS_GPIO_PORT0_VAL3;
break;
default:
break;
}
}
if (gpio_port == 1)
{
switch (pin_num)
{
case 0:
mask = GRC_MISC_REGISTERS_GPIO_PORT1_VAL0;
break;
case 1:
mask = GRC_MISC_REGISTERS_GPIO_PORT1_VAL1;
break;
case 2:
mask = GRC_MISC_REGISTERS_GPIO_PORT1_VAL2;
break;
case 3:
mask = GRC_MISC_REGISTERS_GPIO_PORT1_VAL3;
break;
default:
break;
}
}
reg_val = REG_RD(pdev, MISC_REG_GPIO);
DbgMessage(NULL, INFORM, "lm_gpio_read: MISC_REG_GPIO value 0x%x mask 0x%x\n", reg_val, mask);
if ((reg_val & mask) == mask)
{
*value_ptr = 1;
}
else
{
*value_ptr = 0;
}
DbgMessage(NULL, INFORM, "lm_gpio_read: pin %d value is %x\n", pin_num, *value_ptr);
return LM_STATUS_SUCCESS;
}
lm_status_t lm_gpio_write(struct _lm_device_t *pdev, u32_t pin_num, u32_t mode, u8_t port)
{
u32_t gpio_port = 0;
u32_t gpio_shift = 0;
u32_t gpio_mask = 0;
u32_t gpio_reg = 0;
u32_t swap_val = 0;
u32_t swap_override = 0;
if( CHK_NULL(pdev) )
{
DbgBreakIf(!pdev);
return LM_STATUS_INVALID_PARAMETER ;
}
if (pin_num > MISC_REGISTERS_GPIO_3)
{
DbgMessage(pdev, FATAL , "lm_gpio_write: Invalid pin_num GPIO %d\n", pin_num);
return LM_STATUS_INVALID_PARAMETER;
}
swap_val = REG_RD(pdev, NIG_REG_PORT_SWAP);
swap_override = REG_RD(pdev, NIG_REG_STRAP_OVERRIDE);
gpio_port = (swap_val && swap_override) ^ port;
if (gpio_port > 1) {
return LM_STATUS_FAILURE;
}
gpio_shift = pin_num +
(gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
gpio_mask = (1 << gpio_shift);
lm_hw_lock(pdev, HW_LOCK_RESOURCE_GPIO, TRUE);
gpio_reg = (REG_RD(pdev, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT);
switch (mode) {
case MISC_REGISTERS_GPIO_OUTPUT_LOW:
DbgMessage(NULL, WARN, "Set GPIO %d (shift %d) -> output low\n", pin_num, gpio_shift);
gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_CLR_POS);
break;
case MISC_REGISTERS_GPIO_OUTPUT_HIGH:
DbgMessage(NULL, WARN, "Set GPIO %d (shift %d) -> output high\n", pin_num, gpio_shift);
gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_SET_POS);
break;
case MISC_REGISTERS_GPIO_INPUT_HI_Z:
DbgMessage(NULL, WARN, "Set GPIO %d (shift %d) -> input\n", pin_num, gpio_shift);
gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
break;
default:
break;
}
REG_WR(pdev, MISC_REG_GPIO, gpio_reg);
lm_hw_unlock(pdev, HW_LOCK_RESOURCE_GPIO);
return LM_STATUS_SUCCESS;
}
lm_status_t lm_gpio_mult_write(struct _lm_device_t *pdev, u8_t pins, u32_t mode)
{
u32_t gpio_reg = 0;
lm_status_t rc = LM_STATUS_SUCCESS;
if( CHK_NULL(pdev) )
{
DbgBreakIf(!pdev);
return LM_STATUS_INVALID_PARAMETER ;
}
lm_hw_lock(pdev, HW_LOCK_RESOURCE_GPIO, TRUE);
gpio_reg = REG_RD(pdev, MISC_REG_GPIO);
gpio_reg &= ~(pins << MISC_REGISTERS_GPIO_FLOAT_POS);
gpio_reg &= ~(pins << MISC_REGISTERS_GPIO_CLR_POS);
gpio_reg &= ~(pins << MISC_REGISTERS_GPIO_SET_POS);
switch (mode) {
case MISC_REGISTERS_GPIO_OUTPUT_LOW:
DbgMessage(NULL, WARN, "Set GPIO 0x%x -> output low\n", pins);
gpio_reg |= (pins << MISC_REGISTERS_GPIO_CLR_POS);
break;
case MISC_REGISTERS_GPIO_OUTPUT_HIGH:
DbgMessage(NULL, WARN, "Set GPIO 0x%x -> output high\n", pins);
gpio_reg |= (pins << MISC_REGISTERS_GPIO_SET_POS);
break;
case MISC_REGISTERS_GPIO_INPUT_HI_Z:
DbgMessage(NULL, WARN, "Set GPIO 0x%x -> input\n", pins);
gpio_reg |= (pins << MISC_REGISTERS_GPIO_FLOAT_POS);
break;
default:
DbgMessage(pdev, FATAL , "lm_gpio_mult_write: Invalid GPIO mode %d\n", mode);
rc = LM_STATUS_INVALID_PARAMETER;
break;
}
if (rc == LM_STATUS_SUCCESS)
{
REG_WR(pdev, MISC_REG_GPIO, gpio_reg);
}
lm_hw_unlock(pdev, HW_LOCK_RESOURCE_GPIO);
return rc;
}
lm_status_t lm_gpio_int_write(struct _lm_device_t *pdev, u32_t pin_num, u32_t mode, u8_t port)
{
u32_t gpio_port;
u32_t gpio_shift ;
u32_t gpio_mask;
u32_t gpio_reg;
u32_t swap_val = 0;
u32_t swap_override = 0;
swap_val = REG_RD(pdev, NIG_REG_PORT_SWAP);
swap_override = REG_RD(pdev, NIG_REG_STRAP_OVERRIDE);
gpio_port = (swap_val && swap_override ) ^ port;
gpio_shift = pin_num + (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
gpio_mask = (1 << gpio_shift);
if (pin_num > MISC_REGISTERS_GPIO_3)
{
DbgMessage(pdev, FATAL , "lm_gpio_write: Invalid pin_num GPIO %d\n", pin_num);
return LM_STATUS_INVALID_PARAMETER;
}
lm_hw_lock(pdev, HW_LOCK_RESOURCE_GPIO, TRUE);
gpio_reg = REG_RD(pdev, MISC_REG_GPIO_INT);
switch (mode)
{
case MISC_REGISTERS_GPIO_INT_OUTPUT_CLR:
DbgMessage(pdev, INFORM, "Clear GPIO INT %d (shift %d) -> output low\n",
pin_num, gpio_shift);
gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS);
gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS);
break;
case MISC_REGISTERS_GPIO_INT_OUTPUT_SET:
DbgMessage(pdev, INFORM, "Set GPIO INT %d (shift %d) -> output high\n",
pin_num, gpio_shift);
gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS);
gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS);
break;
default:
break;
}
REG_WR(pdev, MISC_REG_GPIO_INT, gpio_reg);
DbgMessage(pdev, INFORM, "lm_gpio_int_write: pin %d value is %x\n",
pin_num, gpio_reg);
lm_hw_unlock(pdev, HW_LOCK_RESOURCE_GPIO);
return 0;
}
lm_status_t lm_spio_read(struct _lm_device_t *pdev, u32_t pin_num, u32_t* value_ptr)
{
u32_t reg_val = 0, mask = 0;
reg_val = REG_RD(pdev, MISC_REG_SPIO);
DbgMessage(pdev, INFORM, "lm_spio_read: MISC_REG_SPIO value is 0x%x\n", reg_val);
switch (pin_num) {
case 0:
mask = MISC_SPIO_EN_VAUX_L;
break;
case 1:
mask = MISC_SPIO_DIS_VAUX_L;
break;
case 2:
mask = MISC_SPIO_SEL_VAUX_L;
break;
case 3:
return LM_STATUS_FAILURE;
case 4:
reg_val |= (MISC_SPIO_SPIO4 << MISC_SPIO_FLOAT_POS);
mask = MISC_SPIO_SPIO4;
break;
case 5:
reg_val |= (MISC_SPIO_SPIO5 << MISC_SPIO_FLOAT_POS);
mask = MISC_SPIO_SPIO5;
break;
case 6:
reg_val |= (MISC_SPIO_UMP_ADDR0 << MISC_SPIO_FLOAT_POS);
mask = MISC_SPIO_UMP_ADDR0;
break;
case 7:
reg_val |= (MISC_SPIO_UMP_ADDR1 << MISC_SPIO_FLOAT_POS);
mask = MISC_SPIO_UMP_ADDR1;
break;
default:
return LM_STATUS_FAILURE;
}
REG_WR(pdev, MISC_REG_SPIO, reg_val);
DbgMessage(NULL, INFORM, "lm_spio_read: writing MISC_REG_SPIO 0x%x\n", reg_val);
reg_val = REG_RD(pdev, MISC_REG_SPIO);
DbgMessage(NULL, INFORM, "lm_spio_read: MISC_REG_SPIO value 0x%x\n", reg_val);
if ((reg_val & mask) == mask)
{
*value_ptr = 1;
}
else
{
*value_ptr = 0;
}
DbgMessage(NULL, INFORM, "lm_spio_read: pin %d value is 0x%x\n", pin_num, *value_ptr);
return LM_STATUS_SUCCESS;
}
lm_status_t lm_spio_write(struct _lm_device_t *pdev, u32_t pin_num, u32_t value)
{
u32_t reg_val = 0;
lm_status_t lm_status = LM_STATUS_SUCCESS ;
if CHK_NULL(pdev)
{
DbgBreakIf(!pdev);
return LM_STATUS_INVALID_PARAMETER ;
}
lm_hw_lock(pdev, HW_LOCK_RESOURCE_GPIO, TRUE);
reg_val = REG_RD(pdev, MISC_REG_SPIO);
DbgMessage(NULL, INFORM, "lm_gpio_write: MISC_REG_SPIO value is 0x%x\n", reg_val);
if (pin_num >= 8 || pin_num == 3) {
lm_status = LM_STATUS_FAILURE;
} else {
u32 pin = 1 << pin_num;
reg_val &= ~(pin << MISC_SPIO_FLOAT_POS);
reg_val &= ~(pin << MISC_SPIO_SET_POS) & ~(pin << MISC_SPIO_CLR_POS);
reg_val |= (value == 1) ? (pin << MISC_SPIO_SET_POS) : (pin << MISC_SPIO_CLR_POS);
}
if( LM_STATUS_SUCCESS == lm_status )
{
REG_WR(pdev, MISC_REG_SPIO, reg_val);
DbgMessage(NULL, INFORM, "lm_spio_write: writing MISC_REG_SPIO 0x%x\n", reg_val);
}
lm_hw_unlock(pdev, HW_LOCK_RESOURCE_GPIO);
return lm_status ;
}
lm_status_t lm_set_led_mode(struct _lm_device_t *pdev, u32_t port_idx, u32_t mode_idx)
{
DbgBreakIf(!pdev);
switch (port_idx) {
case 0:
REG_WR(pdev, NIG_REG_LED_MODE_P0, mode_idx);
break;
case 1:
REG_WR(pdev, NIG_REG_LED_MODE_P1, mode_idx);
break;
default:
DbgMessage(NULL, FATAL, "lm_set_led_mode() unknown port index %d\n", port_idx);
return LM_STATUS_FAILURE;
}
DbgMessage(NULL, INFORM, "lm_set_led_mode() wrote to NIG_REG_LED_MODE (port %d) 0x%x\n", port_idx, mode_idx);
return LM_STATUS_SUCCESS;
}
lm_status_t lm_get_led_mode(struct _lm_device_t *pdev, u32_t port_idx, u32_t* mode_idx_ptr)
{
DbgBreakIf(!pdev);
switch (port_idx) {
case 0:
*mode_idx_ptr = REG_RD(pdev, NIG_REG_LED_MODE_P0);
break;
case 1:
*mode_idx_ptr = REG_RD(pdev, NIG_REG_LED_MODE_P1);
break;
default:
DbgMessage(NULL, FATAL, "lm_get_led_mode() unknown port index %d\n", port_idx);
return LM_STATUS_FAILURE;
}
DbgMessage(NULL, INFORM, "lm_get_led_mode() read from NIG_REG_LED_MODE (port %d) 0x%x\n", port_idx, *mode_idx_ptr);
return LM_STATUS_SUCCESS;
}
lm_status_t lm_override_led_value(struct _lm_device_t *pdev, u32_t port_idx, u32_t led_idx, u32_t value)
{
u32_t reg_val = 0;
u32_t emac_base = (port_idx) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
DbgBreakIf(!pdev);
DbgMessage(NULL, INFORM, "lm_override_led_value() port %d led_idx %d value %d\n", port_idx, led_idx, value);
switch (led_idx) {
case 0:
reg_val = REG_RD(pdev, emac_base + EMAC_REG_EMAC_LED);
reg_val |= EMAC_LED_OVERRIDE;
reg_val = (value==1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) : (reg_val & ~EMAC_LED_10MB_OVERRIDE);
REG_WR(pdev, emac_base+ EMAC_REG_EMAC_LED, reg_val);
break;
case 1:
reg_val = REG_RD(pdev, emac_base + EMAC_REG_EMAC_LED);
reg_val |= EMAC_LED_OVERRIDE;
reg_val = (value==1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) : (reg_val & ~EMAC_LED_100MB_OVERRIDE);
REG_WR(pdev, emac_base+ EMAC_REG_EMAC_LED, reg_val);
break;
case 2:
reg_val = REG_RD(pdev, emac_base + EMAC_REG_EMAC_LED);
reg_val |= EMAC_LED_OVERRIDE;
reg_val = (value==1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) : (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
REG_WR(pdev, emac_base+ EMAC_REG_EMAC_LED, reg_val);
break;
case 3:
reg_val = REG_RD(pdev, emac_base + EMAC_REG_EMAC_LED);
reg_val |= EMAC_LED_OVERRIDE;
reg_val = (value==1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) : (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
REG_WR(pdev, emac_base+ EMAC_REG_EMAC_LED, reg_val);
break;
case 4:
if (port_idx == 0) {
REG_WR(pdev, NIG_REG_LED_10G_P0, value);
} else {
REG_WR(pdev, NIG_REG_LED_10G_P1, value);
}
break;
case 5:
if (port_idx == 0) {
reg_val = REG_RD(pdev, NIG_REG_NIG_EMAC0_EN);
} else {
reg_val = REG_RD(pdev, NIG_REG_NIG_EMAC1_EN);
}
if (reg_val == 1) {
reg_val = REG_RD(pdev, emac_base + EMAC_REG_EMAC_LED);
reg_val |= EMAC_LED_OVERRIDE;
reg_val = (value==1) ? (reg_val | EMAC_LED_TRAFFIC) : (reg_val & ~EMAC_LED_TRAFFIC);
REG_WR(pdev, emac_base+ EMAC_REG_EMAC_LED, reg_val);
} else {
if (port_idx == 0) {
REG_WR(pdev, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0, 1);
REG_WR(pdev, NIG_REG_LED_CONTROL_TRAFFIC_P0, value);
} else {
REG_WR(pdev, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P1, 1);
REG_WR(pdev, NIG_REG_LED_CONTROL_TRAFFIC_P1, value);
}
}
break;
default:
DbgMessage(NULL, FATAL, "lm_override_led_value() unknown led index %d (should be 0-5)\n", led_idx);
return LM_STATUS_FAILURE;
}
return LM_STATUS_SUCCESS;
}
lm_status_t lm_blink_traffic_led(struct _lm_device_t *pdev, u32_t port_idx, u32_t rate)
{
u32_t reg_val = 0;
u32_t emac_base = (port_idx) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
DbgBreakIf(!pdev);
if (port_idx == 0) {
reg_val = REG_RD(pdev, NIG_REG_NIG_EMAC0_EN);
} else {
reg_val = REG_RD(pdev, NIG_REG_NIG_EMAC1_EN);
}
if (reg_val == 1) {
reg_val = REG_RD(pdev, emac_base + EMAC_REG_EMAC_LED);
reg_val |= EMAC_LED_OVERRIDE;
reg_val |= EMAC_LED_TRAFFIC;
reg_val |= EMAC_LED_BLNK_TRAFFIC;
if (rate != 0) {
reg_val |= EMAC_LED_BLNK_RATE_ENA;
reg_val |= (rate << EMAC_LED_BLNK_RATE_BITSHIFT);
}
REG_WR(pdev, emac_base+ EMAC_REG_EMAC_LED, reg_val);
DbgMessage(NULL, INFORM, "lm_blink_traffic_led() port %d write to EMAC_REG_EMAC_LED the value 0x%x\n", port_idx, reg_val);
} else {
if (port_idx == 0) {
REG_WR(pdev, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0, 1);
REG_WR(pdev, NIG_REG_LED_CONTROL_TRAFFIC_P0, 1);
REG_WR(pdev, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0, 1);
DbgMessage(NULL, INFORM, "lm_blink_traffic_led() set BLINK_TRAFFIC_P0 to 1\n");
if (rate != 0) {
REG_WR(pdev, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0, 1);
REG_WR(pdev, NIG_REG_LED_CONTROL_BLINK_RATE_P0, rate);
DbgMessage(NULL, INFORM, "lm_blink_traffic_led() port %d write to NIG_REG_LED_CONTROL_BLINK_RATE_P0 %x\n", port_idx, rate);
}
} else {
REG_WR(pdev, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P1, 1);
REG_WR(pdev, NIG_REG_LED_CONTROL_TRAFFIC_P1, 1);
REG_WR(pdev, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P1, 1);
DbgMessage(NULL, INFORM, "lm_blink_traffic_led() set BLINK_TRAFFIC_P1 to 1\n");
if (rate != 0) {
REG_WR(pdev, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P1, 1);
REG_WR(pdev, NIG_REG_LED_CONTROL_BLINK_RATE_P1, rate);
DbgMessage(NULL, INFORM, "lm_blink_traffic_led() port %d write to NIG_REG_LED_CONTROL_BLINK_RATE_P1 0x%x\n", port_idx, rate);
}
}
}
return LM_STATUS_SUCCESS;
}
lm_status_t lm_get_led_status(struct _lm_device_t *pdev, u32_t port_idx, u32_t led_idx, u32_t* value_ptr)
{
u32_t reg_val = 0;
u32_t emac_base = (port_idx) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
DbgBreakIf(!pdev);
switch (led_idx) {
case 0:
reg_val = REG_RD(pdev, emac_base + EMAC_REG_EMAC_LED);
*value_ptr = ((reg_val & EMAC_LED_10MB) == EMAC_LED_10MB) ? 1 : 0;
break;
case 1:
reg_val = REG_RD(pdev, emac_base + EMAC_REG_EMAC_LED);
*value_ptr = ((reg_val & EMAC_LED_100MB) == EMAC_LED_100MB) ? 1 : 0;
break;
case 2:
reg_val = REG_RD(pdev, emac_base + EMAC_REG_EMAC_LED);
*value_ptr = ((reg_val & EMAC_LED_1000MB) == EMAC_LED_1000MB) ? 1 : 0;
break;
case 3:
reg_val = REG_RD(pdev, emac_base + EMAC_REG_EMAC_LED);
*value_ptr = ((reg_val & EMAC_LED_2500MB) == EMAC_LED_2500MB) ? 1 : 0;
break;
case 4:
if (port_idx == 0) {
*value_ptr = REG_RD(pdev, NIG_REG_LED_10G_P0);
} else {
*value_ptr = REG_RD(pdev, NIG_REG_LED_10G_P1);
}
break;
case 5:
reg_val = REG_RD(pdev, emac_base + EMAC_REG_EMAC_LED);
*value_ptr = ((reg_val & EMAC_LED_TRAFFIC_STAT) == EMAC_LED_TRAFFIC_STAT) ? 1 : 0;
if (port_idx == 0) {
*value_ptr = REG_RD(pdev, NIG_REG_LED_STATUS_ACTIVE_P0);
} else {
*value_ptr = REG_RD(pdev, NIG_REG_LED_STATUS_ACTIVE_P1);
}
break;
default:
DbgMessage(NULL, FATAL, "lm_get_led_status() unknown led index %d (should be 0-5)\n", led_idx);
return LM_STATUS_FAILURE;
}
DbgMessage(NULL, INFORM, "lm_get_led_status() port %d led_idx %d value %d\n", port_idx, led_idx, *value_ptr);
return LM_STATUS_SUCCESS;
}
void
lm_reset_led(struct _lm_device_t *pdev)
{
u8_t port = 0;
if (CHK_NULL(pdev)){
DbgBreakIf(!pdev);
return;
}
port = PORT_ID(pdev);
REG_WR(pdev, NIG_REG_LED_10G_P0 + port*4, 0);
REG_WR(pdev, NIG_REG_LED_MODE_P0 + port*4,SHARED_HW_CFG_LED_MAC1);
}
static u8_t lm_is_57710A0_dbg_intr( struct _lm_device_t * pdev )
{
u32_t val = 0;
if(pdev->params.interrupt_mode != LM_INT_MODE_INTA)
{
DbgMessage(pdev, WARN, "MSI/MSI-X enabled - debugging INTA/B failed\n");
return 0;
}
val = REG_RD(pdev, 0x2004);
#define PCIE_CORE_INT_PENDING_BIT 0X00080000
if(!GET_FLAGS(val, PCIE_CORE_INT_PENDING_BIT))
{
DbgMessage(pdev, WARN, "PCIE core int line not asserted - debugging INTA/B failed\n");
return 0;
}
#define PCIE_CORE_INT_DISABLE_BIT 0X00000400
if(GET_FLAGS(val, PCIE_CORE_INT_DISABLE_BIT))
{
DbgMessage(pdev, WARN, "PCIE core int line not enabled - debugging INTA/B failed\n");
return 0;
}
val = REG_RD(pdev, HC_REG_INT_MASK + 4*PORT_ID(pdev) );
if(val != 0x0001ffff)
{
DbgMessage(pdev, WARN, "IGU int mask != 0x1ffff - might not be related to debugging INTA/B issue\n");
}
return 1;
}
void lm_57710A0_dbg_intr( struct _lm_device_t * pdev )
{
if(IS_CHIP_REV_A0(pdev) && lm_is_57710A0_dbg_intr(pdev))
{
lm_disable_int(pdev);
lm_enable_int(pdev);
}
}
lm_status_t
lm_set_led_wrapper(struct _lm_device_t* pdev,
const u8_t led_mode )
{
u8_t elink_res = ELINK_STATUS_OK;
lm_status_t lm_status = LM_STATUS_SUCCESS;
PHY_HW_LOCK(pdev);
elink_res = elink_set_led( &pdev->params.link, &pdev->vars.link, led_mode, pdev->vars.link.line_speed );
PHY_HW_UNLOCK(pdev);
switch(elink_res)
{
case ELINK_STATUS_OK:
lm_status = LM_STATUS_SUCCESS;
break;
case ELINK_STATUS_ERROR:
default:
lm_status = LM_STATUS_FAILURE;
break;
}
return lm_status;
}
lm_status_t
lm_get_transceiver_data(struct _lm_device_t* pdev,
b10_transceiver_data_t* b10_transceiver_data )
{
u16_t eeprom_data[][2] = { { ELINK_SFP_EEPROM_VENDOR_NAME_ADDR, ELINK_SFP_EEPROM_VENDOR_NAME_SIZE},
{ ELINK_SFP_EEPROM_PART_NO_ADDR, ELINK_SFP_EEPROM_PART_NO_SIZE},
{ ELINK_SFP_EEPROM_SERIAL_ADDR, ELINK_SFP_EEPROM_SERIAL_SIZE},
{ ELINK_SFP_EEPROM_REVISION_ADDR, ELINK_SFP_EEPROM_REVISION_SIZE},
{ ELINK_SFP_EEPROM_DATE_ADDR, ELINK_SFP_EEPROM_DATE_SIZE} } ;
u8_t vendor_name [ELINK_SFP_EEPROM_VENDOR_NAME_SIZE] = {0};
u8_t model_num [ELINK_SFP_EEPROM_PART_NO_SIZE] = {0};
u8_t serial_num [ELINK_SFP_EEPROM_SERIAL_SIZE] = {0};
u8_t revision_num [ELINK_SFP_EEPROM_REVISION_SIZE] = {0};
u8_t mfg_date [ELINK_SFP_EEPROM_DATE_SIZE] = {0};
u8_t* ptr_arr[ARRSIZE(eeprom_data)] = {0};
u8_t idx = 0;
u8_t elink_res = ELINK_STATUS_ERROR;
u8_t ext_phy_type = 0;
lm_status_t lm_status = LM_STATUS_SUCCESS;
if CHK_NULL( b10_transceiver_data )
{
return LM_STATUS_INVALID_PARAMETER;
}
ASSERT_STATIC( sizeof(b10_transceiver_data->vendor_name) == sizeof(vendor_name) ) ;
ASSERT_STATIC( sizeof(b10_transceiver_data->model_num) == sizeof(model_num) ) ;
ASSERT_STATIC( sizeof(b10_transceiver_data->serial_num) == sizeof(serial_num) ) ;
ASSERT_STATIC( sizeof(b10_transceiver_data->revision_num) == sizeof(revision_num) ) ;
ASSERT_STATIC( sizeof(b10_transceiver_data->mfg_date) == sizeof(mfg_date) ) ;
mm_mem_zero( b10_transceiver_data, sizeof( b10_transceiver_data_t ) ) ;
ptr_arr[0] = &vendor_name[0];
ptr_arr[1] = &model_num[0];
ptr_arr[2] = &serial_num[0];
ptr_arr[3] = &revision_num[0];
ptr_arr[4] = &mfg_date[0];
if( pdev->params.link.num_phys > ELINK_MAX_PHYS )
{
DbgBreakIf(1);
return LM_STATUS_FAILURE;
}
for( ext_phy_type = ELINK_EXT_PHY1; ext_phy_type < pdev->params.link.num_phys; ext_phy_type++ )
{
if( ELINK_ETH_PHY_SFPP_10G_FIBER == pdev->params.link.phy[ext_phy_type].media_type ||
ELINK_ETH_PHY_SFP_1G_FIBER == pdev->params.link.phy[ext_phy_type].media_type ||
ELINK_ETH_PHY_DA_TWINAX == pdev->params.link.phy[ext_phy_type].media_type)
{
for( idx = 0; idx < ARRSIZE(eeprom_data) ; idx++ )
{
PHY_HW_LOCK(pdev);
elink_res = elink_read_sfp_module_eeprom( &pdev->params.link.phy[ext_phy_type],
&pdev->params.link,
ELINK_I2C_DEV_ADDR_A0,
eeprom_data[idx][0],
(u8_t)eeprom_data[idx][1],
ptr_arr[idx] ) ;
PHY_HW_UNLOCK(pdev);
if( ELINK_STATUS_OK != elink_res )
{
break;
}
}
break;
}
}
switch(elink_res)
{
case ELINK_STATUS_OK:
{
b10_transceiver_data->ver_num = TRANSCEIVER_DATA_VER_NUM;
mm_memcpy( b10_transceiver_data->vendor_name, &vendor_name[0], sizeof(vendor_name) );
mm_memcpy( b10_transceiver_data->model_num, &model_num[0], sizeof(model_num) );
mm_memcpy( b10_transceiver_data->serial_num, &serial_num[0], sizeof(serial_num) );
mm_memcpy( b10_transceiver_data->revision_num, &revision_num[0], sizeof(revision_num) );
mm_memcpy( b10_transceiver_data->mfg_date, &mfg_date[0], sizeof(mfg_date) );
}
lm_status = LM_STATUS_SUCCESS;
break;
case ELINK_STATUS_TIMEOUT:
lm_status = LM_STATUS_TIMEOUT;
break;
case ELINK_STATUS_ERROR:
default:
lm_status = LM_STATUS_FAILURE;
break;
}
return lm_status;
}
lm_status_t lm_set_mac_in_nig(lm_device_t * pdev, u8_t * mac_addr, lm_cli_idx_t lm_cli_idx, u8_t offset)
{
u32_t reg_offset = 0;
u32_t wb_data[2] = {0};
u8_t enable_mac = 0;
#define MAX_OFFSET_IN_MEM_1 8
if (lm_cli_idx == LM_CLI_IDX_ISCSI)
{
offset = ECORE_LLH_CAM_ISCSI_ETH_LINE;
}
else if (offset == ECORE_LLH_CAM_ISCSI_ETH_LINE)
{
offset = MAX_MAC_OFFSET_IN_NIG;
}
if (CHIP_IS_E1x(pdev) || !IS_MULTI_VNIC(pdev) || IS_MF_SD_MODE(pdev) || offset >= MAX_MAC_OFFSET_IN_NIG)
{
return LM_STATUS_SUCCESS;
}
if (mac_addr)
{
DbgMessage(pdev, WARN, "Setting mac in nig to offset: %d mac_addr[%02x]:[%02x]:[%02x]:[%02x]:[%02x]:[%02x]\n", offset,
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
DbgMessage(pdev, WARN, "[%x]:[%x]\n", mac_addr[6], mac_addr[7]);
if (offset < MAX_OFFSET_IN_MEM_1)
{
reg_offset = (PORT_ID(pdev)? NIG_REG_LLH1_FUNC_MEM: NIG_REG_LLH0_FUNC_MEM) + 8*offset;
}
else
{
reg_offset = (PORT_ID(pdev)? NIG_REG_P1_LLH_FUNC_MEM2: NIG_REG_P0_LLH_FUNC_MEM2) + 8*(offset - MAX_OFFSET_IN_MEM_1);
}
wb_data[0] = ((mac_addr[2] << 24) | (mac_addr[3] << 16) | (mac_addr[4] << 8) | mac_addr[5]);
wb_data[1] = ((mac_addr[0] << 8) | mac_addr[1]);
REG_WR_DMAE_LEN(pdev, reg_offset, wb_data, ARRSIZE(wb_data));
enable_mac = 1;
}
DbgMessage(pdev, WARN, "Enable_mac: %d\n", enable_mac);
if (offset < MAX_OFFSET_IN_MEM_1)
{
reg_offset = (PORT_ID(pdev)? NIG_REG_LLH1_FUNC_MEM_ENABLE : NIG_REG_LLH0_FUNC_MEM_ENABLE) + 4*offset;
}
else
{
reg_offset = (PORT_ID(pdev)? NIG_REG_P1_LLH_FUNC_MEM2_ENABLE : NIG_REG_P0_LLH_FUNC_MEM2_ENABLE) + 4*(offset - MAX_OFFSET_IN_MEM_1);
}
REG_WR(pdev, reg_offset, enable_mac);
return LM_STATUS_SUCCESS;
}
static const u32_t lm_hw_lock_table[8] = {
MISC_REG_DRIVER_CONTROL_1,
MISC_REG_DRIVER_CONTROL_2,
MISC_REG_DRIVER_CONTROL_3,
MISC_REG_DRIVER_CONTROL_4,
MISC_REG_DRIVER_CONTROL_5,
MISC_REG_DRIVER_CONTROL_6,
MISC_REG_DRIVER_CONTROL_7,
MISC_REG_DRIVER_CONTROL_8,
};
lm_status_t lm_hw_lock( lm_device_t* pdev,
const u32_t resource,
const u8_t b_block)
{
u32_t cnt = 0;
u32_t lock_status = 0;
u32_t const resource_bit = (1 << resource);
u8_t const func = FUNC_ID(pdev);
u32_t hw_lock_cntr_reg = 0;
if (resource > HW_LOCK_MAX_RESOURCE_VALUE)
{
DbgMessage(pdev, FATAL, "lm_hw_lock: LM_STATUS_INVALID_PARAMETER resource=0x%x\n", resource);
DbgBreakMsg("lm_hw_lock: LM_STATUS_INVALID_PARAMETER\n");
return LM_STATUS_INVALID_PARAMETER;
}
DbgBreakIf(func >= ARRSIZE(lm_hw_lock_table));
hw_lock_cntr_reg = lm_hw_lock_table[func];
lock_status = REG_RD(pdev, hw_lock_cntr_reg);
if (lock_status & resource_bit)
{
DbgMessage(pdev, FATAL , "lm_hw_lock: LM_STATUS_EXISTING_OBJECT lock_status=0x%x resource_bit=0x%x\n", lock_status, resource_bit);
DbgBreakMsg("lm_hw_lock: LM_STATUS_EXISTING_OBJECT\n");
return LM_STATUS_EXISTING_OBJECT;
}
for (cnt = 0; cnt < 320000; cnt++)
{
REG_WR(pdev, hw_lock_cntr_reg + 4, resource_bit);
lock_status= REG_RD(pdev, hw_lock_cntr_reg);
if (lock_status & resource_bit)
{
return LM_STATUS_SUCCESS;
}
if (!b_block)
{
return LM_STATUS_FAILURE;
}
mm_wait(pdev, 50);
}
DbgMessage(pdev, FATAL , "lm_hw_lock: LM_STATUS_TIMEOUT\n" );
DbgBreakMsg("lm_hw_lock: FAILED LM_STATUS_TIMEOUT\n");
return LM_STATUS_TIMEOUT;
}
lm_status_t lm_hw_unlock_ex(lm_device_t* pdev,
const u32_t resource,
const u8_t b_verify_locked )
{
u32_t lock_status = 0;
u32_t const resource_bit = (1 << resource);
u8_t const func = FUNC_ID(pdev);
u32_t hw_lock_cntr_reg = 0;
if (resource > HW_LOCK_MAX_RESOURCE_VALUE)
{
DbgMessage(pdev, FATAL, "lm_hw_unlock: LM_STATUS_INVALID_PARAMETER resource=0x%x\n", resource);
DbgBreakMsg("lm_hw_unlock: LM_STATUS_INVALID_PARAMETER\n");
return LM_STATUS_INVALID_PARAMETER;
}
DbgBreakIf(func >= ARRSIZE(lm_hw_lock_table));
hw_lock_cntr_reg = lm_hw_lock_table[func];
lock_status = REG_RD(pdev, hw_lock_cntr_reg);
if (!(lock_status & resource_bit))
{
DbgMessage(pdev, FATAL, "lm_hw_unlock: LM_STATUS_OBJECT_NOT_FOUND lock_status=0x%x resource_bit=0x%x\n", lock_status, resource_bit);
if( b_verify_locked )
{
DbgBreakMsg("lm_hw_unlock: LM_STATUS_OBJECT_NOT_FOUND\n");
return LM_STATUS_OBJECT_NOT_FOUND;
}
}
REG_WR(pdev, hw_lock_cntr_reg, resource_bit);
return LM_STATUS_SUCCESS;
}
lm_status_t lm_hw_unlock(lm_device_t* pdev,
const u32_t resource)
{
return lm_hw_unlock_ex( pdev, resource, TRUE);
}
void lm_hw_clear_all_locks(lm_device_t *pdev)
{
u32_t lock_status = 0;
u32_t hw_lock_cntr_reg = 0;
u8_t func = 0;
if (CHIP_IS_E1x(pdev))
{
return;
}
for (func = 0; func < MAX_FUNC_NUM; func++)
{
DbgBreakIf(func >= ARRSIZE(lm_hw_lock_table));
hw_lock_cntr_reg = lm_hw_lock_table[func];
lock_status = REG_RD(pdev, hw_lock_cntr_reg);
if (lock_status != 0)
{
REG_WR(pdev, hw_lock_cntr_reg, lock_status);
}
}
}
u32_t reg_wait_verify_val(struct _lm_device_t * pdev, u32_t reg_offset, u32_t excpected_val, u32_t total_wait_time_ms )
{
u32_t val = 0 ;
u32_t wait_cnt = 0 ;
u32_t wait_cnt_limit = total_wait_time_ms/DEFAULT_WAIT_INTERVAL_MICSEC ;
if( wait_cnt_limit == 0 )
{
wait_cnt_limit = 1;
}
val=REG_RD(pdev,reg_offset);
while( (val != excpected_val) && (wait_cnt++ != wait_cnt_limit) )
{
mm_wait(pdev, DEFAULT_WAIT_INTERVAL_MICSEC) ;
val=REG_RD(pdev,reg_offset);
}
if (val != excpected_val) {
DbgMessage(pdev, WARN, "val = 0x%x, expected val = 0x%x\n", val, excpected_val );
DbgBreakIf(val != excpected_val);
}
return wait_cnt;
}
void lm_disable_pci_dma(struct _lm_device_t *pdev, u8_t b_wait_for_done)
{
u32_t val = 0;
u32_t idx = 0;
const u32_t flags = (PCICFG_DEVICE_STATUS_NO_PEND << 16) ;
if (IS_PFDEV(pdev))
{
if (CHIP_IS_E1x(pdev))
{
val=REG_RD(pdev,GRCBASE_PCICONFIG+PCICFG_COMMAND_OFFSET);
RESET_FLAGS( val, PCICFG_COMMAND_BUS_MASTER );
REG_WR(pdev,GRCBASE_PCICONFIG+PCICFG_COMMAND_OFFSET,val);
}
else
{
REG_WR(pdev, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 0);
}
if (b_wait_for_done)
{
for(idx = 0; idx < 1000; idx++)
{
val=REG_RD(pdev,GRCBASE_PCICONFIG+PCICFG_DEVICE_CONTROL);
if( (val & flags) == 0)
{
break;
}
mm_wait(pdev, 5);
}
}
}
}
void lm_enable_pci_dma(struct _lm_device_t *pdev)
{
u32_t val = 0;
if (IS_PFDEV(pdev))
{
if (CHIP_IS_E1x(pdev))
{
val=REG_RD(pdev,GRCBASE_PCICONFIG+PCICFG_COMMAND_OFFSET);
if( 0 == GET_FLAGS( val, PCICFG_COMMAND_BUS_MASTER ) )
{
SET_FLAGS( val, PCICFG_COMMAND_BUS_MASTER );
REG_WR(pdev,GRCBASE_PCICONFIG+PCICFG_COMMAND_OFFSET,val);
}
}
else
{
REG_WR(pdev, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 1);
}
}
}
void lm_set_pcie_nfe_report(lm_device_t *pdev)
{
if(IS_PFDEV(pdev) && pdev->params.disable_pcie_nfr)
{
u32_t pci_devctl = 0 ;
pci_devctl = REG_RD(pdev,GRCBASE_PCICONFIG + PCICFG_DEVICE_CONTROL);
RESET_FLAGS( pci_devctl, PCICFG_DEVICE_STATUS_NON_FATAL_ERR_DET );
REG_WR(pdev,GRCBASE_PCICONFIG + PCICFG_DEVICE_CONTROL,pci_devctl);
}
}
void
lm_reg_rd_ind_imp(
lm_device_t *pdev,
u32_t offset,
u32_t *ret)
{
DbgBreakIf(offset & 0x3);
mm_write_pci(pdev,PCICFG_GRC_ADDRESS,offset);
mm_read_pci(pdev,PCICFG_GRC_DATA,ret);
}
void
lm_reg_wr_ind_imp(
lm_device_t *pdev,
u32_t offset,
u32_t val)
{
u32_t dummy;
DbgBreakIf(offset & 0x3);
mm_write_pci(pdev,PCICFG_GRC_ADDRESS,offset);
mm_write_pci(pdev,PCICFG_GRC_DATA,val);
lm_reg_rd_ind_imp(pdev,PCICFG_VENDOR_ID_OFFSET,&dummy);
}
void
lm_reg_rd_ind(
lm_device_t *pdev,
u32_t offset,
u32_t *ret)
{
MM_ACQUIRE_IND_REG_LOCK(pdev);
lm_reg_rd_ind_imp(pdev,offset,ret);
MM_RELEASE_IND_REG_LOCK(pdev);
}
void
lm_reg_wr_ind(
lm_device_t *pdev,
u32_t offset,
u32_t val)
{
MM_ACQUIRE_IND_REG_LOCK(pdev);
lm_reg_wr_ind_imp(pdev,offset,val);
MM_RELEASE_IND_REG_LOCK(pdev);
}
void
lm_reg_rd_blk(
lm_device_t *pdev,
u32_t reg_offset,
u32_t *buf_ptr,
u32_t u32t_cnt)
{
u32_t current_offset = 0;
DbgBreakIf(reg_offset & 0x3);
while(u32t_cnt)
{
*buf_ptr = REG_RD(pdev, reg_offset + current_offset);
buf_ptr++;
u32t_cnt--;
current_offset += 4;
}
}
void
lm_reg_rd_blk_ind(
lm_device_t *pdev,
u32_t reg_offset,
u32_t *buf_ptr,
u32_t u32t_cnt,
u8_t acquire_lock_flag)
{
u32_t current_offset = 0;
if(acquire_lock_flag)
{
MM_ACQUIRE_IND_REG_LOCK(pdev);
}
while(u32t_cnt)
{
lm_reg_rd_ind_imp(pdev, reg_offset + current_offset, buf_ptr);
buf_ptr++;
u32t_cnt--;
current_offset += 4;
}
if(acquire_lock_flag)
{
MM_RELEASE_IND_REG_LOCK(pdev);
}
}
void
lm_reg_wr_blk(
lm_device_t *pdev,
u32_t reg_offset,
u32_t *data_ptr,
u32_t u32t_cnt)
{
u32_t current_offset = 0;
DbgBreakIf(reg_offset & 0x3);
while(u32t_cnt)
{
REG_WR(pdev, reg_offset + current_offset, *data_ptr);
data_ptr++;
u32t_cnt--;
current_offset += 4;
}
}
void
lm_reg_wr_blk_ind(
lm_device_t *pdev,
u32_t reg_offset,
u32_t *data_ptr,
u32_t u32t_cnt)
{
u32_t current_offset = 0;
MM_ACQUIRE_IND_REG_LOCK(pdev);
while(u32t_cnt)
{
lm_reg_wr_ind_imp(pdev, reg_offset + current_offset, *data_ptr);
data_ptr++;
u32t_cnt--;
current_offset += 4;
}
MM_RELEASE_IND_REG_LOCK(pdev);
}
void lm_set_waitp(lm_device_t *pdev)
{
REG_WR(pdev,DRV_DUMP_TSTORM_WAITP_ADDRESS,1);
REG_WR(pdev,DRV_DUMP_XSTORM_WAITP_ADDRESS,1);
REG_WR(pdev,DRV_DUMP_CSTORM_WAITP_ADDRESS,1);
REG_WR(pdev,DRV_DUMP_USTORM_WAITP_ADDRESS,1);
}
void lm_collect_idle_storms_dorrbell_asserts( struct _lm_device_t *pdev,
const u8_t b_idle_chk,
const u8_t b_storms_asserts,
const u8_t b_dorrbell_info )
{
#if !(defined(UEFI) || defined(DOS) || defined(__LINUX))
if( b_idle_chk )
{
lm_idle_chk(pdev);
}
if( b_dorrbell_info )
{
lm_get_doorbell_info(pdev);
}
if( b_storms_asserts )
{
lm_get_storms_assert(pdev);
}
#endif
}