Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ixgbe/if_bypass.c
Show First 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | ixgbe_bp_set_state(SYSCTL_HANDLER_ARGS) | ||||
int error = 0; | int error = 0; | ||||
static int state = 0; | static int state = 0; | ||||
/* Get the current state */ | /* Get the current state */ | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(adapter); | ||||
error = hw->mac.ops.bypass_rw(hw, | error = hw->mac.ops.bypass_rw(hw, | ||||
BYPASS_PAGE_CTL0, &state); | BYPASS_PAGE_CTL0, &state); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(adapter); | ||||
if (error) | if (error != 0) | ||||
return (error); | return (error); | ||||
state = (state >> BYPASS_STATUS_OFF_SHIFT) & 0x3; | state = (state >> BYPASS_STATUS_OFF_SHIFT) & 0x3; | ||||
error = sysctl_handle_int(oidp, &state, 0, req); | error = sysctl_handle_int(oidp, &state, 0, req); | ||||
if ((error) || (req->newptr == NULL)) | if ((error != 0) || (req->newptr == NULL)) | ||||
return (error); | return (error); | ||||
/* Sanity check new state */ | /* Sanity check new state */ | ||||
switch (state) { | switch (state) { | ||||
case BYPASS_NORM: | case BYPASS_NORM: | ||||
case BYPASS_BYPASS: | case BYPASS_BYPASS: | ||||
case BYPASS_ISOLATE: | case BYPASS_ISOLATE: | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 250 Lines • ▼ Show 20 Lines | |||||
************************************************************************/ | ************************************************************************/ | ||||
static int | static int | ||||
ixgbe_bp_wd_set(SYSCTL_HANDLER_ARGS) | ixgbe_bp_wd_set(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct adapter *adapter = (struct adapter *) arg1; | struct adapter *adapter = (struct adapter *) arg1; | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &adapter->hw; | ||||
int error, tmp; | int error, tmp; | ||||
static int timeout = 0; | static int timeout = 0; | ||||
u32 mask, arg = BYPASS_PAGE_CTL0; | u32 mask, arg; | ||||
/* Get the current hardware value */ | /* Get the current hardware value */ | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(adapter); | ||||
error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &tmp); | error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &tmp); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(adapter); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
/* | /* | ||||
* If armed keep the displayed value, | * If armed keep the displayed value, | ||||
* else change the display to zero. | * else change the display to zero. | ||||
*/ | */ | ||||
if ((tmp & (0x1 << BYPASS_WDT_ENABLE_SHIFT)) == 0) | if ((tmp & (0x1 << BYPASS_WDT_ENABLE_SHIFT)) == 0) | ||||
timeout = 0; | timeout = 0; | ||||
error = sysctl_handle_int(oidp, &timeout, 0, req); | error = sysctl_handle_int(oidp, &timeout, 0, req); | ||||
if ((error) || (req->newptr == NULL)) | if ((error) || (req->newptr == NULL)) | ||||
return (error); | return (error); | ||||
mask = BYPASS_WDT_ENABLE_M; | arg = 0x1 << BYPASS_WDT_ENABLE_SHIFT; | ||||
mask = BYPASS_WDT_ENABLE_M | BYPASS_WDT_VALUE_M; | |||||
switch (timeout) { | switch (timeout) { | ||||
case 0: /* disables the timer */ | case 0: /* disables the timer */ | ||||
arg = BYPASS_PAGE_CTL0; | |||||
mask = BYPASS_WDT_ENABLE_M; | |||||
break; | break; | ||||
case 1: | case 1: | ||||
arg = BYPASS_WDT_1_5 << BYPASS_WDT_TIME_SHIFT; | arg |= BYPASS_WDT_1_5 << BYPASS_WDT_TIME_SHIFT; | ||||
arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; | |||||
mask |= BYPASS_WDT_VALUE_M; | |||||
break; | break; | ||||
case 2: | case 2: | ||||
arg = BYPASS_WDT_2 << BYPASS_WDT_TIME_SHIFT; | arg |= BYPASS_WDT_2 << BYPASS_WDT_TIME_SHIFT; | ||||
arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; | |||||
mask |= BYPASS_WDT_VALUE_M; | |||||
break; | break; | ||||
case 3: | case 3: | ||||
arg = BYPASS_WDT_3 << BYPASS_WDT_TIME_SHIFT; | arg |= BYPASS_WDT_3 << BYPASS_WDT_TIME_SHIFT; | ||||
arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; | |||||
mask |= BYPASS_WDT_VALUE_M; | |||||
break; | break; | ||||
case 4: | case 4: | ||||
arg = BYPASS_WDT_4 << BYPASS_WDT_TIME_SHIFT; | arg |= BYPASS_WDT_4 << BYPASS_WDT_TIME_SHIFT; | ||||
arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; | |||||
mask |= BYPASS_WDT_VALUE_M; | |||||
break; | break; | ||||
case 8: | case 8: | ||||
arg = BYPASS_WDT_8 << BYPASS_WDT_TIME_SHIFT; | arg |= BYPASS_WDT_8 << BYPASS_WDT_TIME_SHIFT; | ||||
arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; | |||||
mask |= BYPASS_WDT_VALUE_M; | |||||
break; | break; | ||||
case 16: | case 16: | ||||
arg = BYPASS_WDT_16 << BYPASS_WDT_TIME_SHIFT; | arg |= BYPASS_WDT_16 << BYPASS_WDT_TIME_SHIFT; | ||||
arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; | |||||
mask |= BYPASS_WDT_VALUE_M; | |||||
break; | break; | ||||
case 32: | case 32: | ||||
arg = BYPASS_WDT_32 << BYPASS_WDT_TIME_SHIFT; | arg |= BYPASS_WDT_32 << BYPASS_WDT_TIME_SHIFT; | ||||
arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT; | |||||
mask |= BYPASS_WDT_VALUE_M; | |||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
/* Set the new watchdog */ | /* Set the new watchdog */ | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(adapter); | ||||
error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, mask, arg); | error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, mask, arg); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(adapter); | ||||
return (error); | return (error); | ||||
} /* ixgbe_bp_wd_set */ | } /* ixgbe_bp_wd_set */ | ||||
Show All 27 Lines | ixgbe_bp_wd_reset(SYSCTL_HANDLER_ARGS) | ||||
error = hw->mac.ops.bypass_rw(hw, cmd, &reset_wd); | error = hw->mac.ops.bypass_rw(hw, cmd, &reset_wd); | ||||
/* Read until it matches what we wrote, or we time out */ | /* Read until it matches what we wrote, or we time out */ | ||||
do { | do { | ||||
if (count++ > 10) { | if (count++ > 10) { | ||||
error = IXGBE_BYPASS_FW_WRITE_FAILURE; | error = IXGBE_BYPASS_FW_WRITE_FAILURE; | ||||
break; | break; | ||||
} | } | ||||
if (hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL1, &reset_wd)) { | error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL1, &reset_wd); | ||||
if (error != 0) { | |||||
error = IXGBE_ERR_INVALID_ARGUMENT; | error = IXGBE_ERR_INVALID_ARGUMENT; | ||||
break; | break; | ||||
} | } | ||||
} while (!hw->mac.ops.bypass_valid_rd(cmd, reset_wd)); | } while (!hw->mac.ops.bypass_valid_rd(cmd, reset_wd)); | ||||
reset_wd = 0; | reset_wd = 0; | ||||
ixgbe_bypass_wd_mutex_clear(adapter); | ixgbe_bypass_wd_mutex_clear(adapter); | ||||
return (error); | return (error); | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | while (count < BYPASS_MAX_LOGS) { | ||||
/* Log 5 bytes store in on u32 and a u8 */ | /* Log 5 bytes store in on u32 and a u8 */ | ||||
for (i = 0; i < 4; i++) { | for (i = 0; i < 4; i++) { | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(adapter); | ||||
error = hw->mac.ops.bypass_rd_eep(hw, log_off + i, | error = hw->mac.ops.bypass_rd_eep(hw, log_off + i, | ||||
&data); | &data); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(adapter); | ||||
if (error) | if (error) | ||||
return (-EINVAL); | return (EINVAL); | ||||
eeprom[count].logs += data << (8 * i); | eeprom[count].logs += data << (8 * i); | ||||
} | } | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(adapter); | ||||
error = hw->mac.ops.bypass_rd_eep(hw, | error = hw->mac.ops.bypass_rd_eep(hw, | ||||
log_off + i, &eeprom[count].actions); | log_off + i, &eeprom[count].actions); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(adapter); | ||||
if (error) | if (error) | ||||
return (-EINVAL); | return (EINVAL); | ||||
/* Quit if not a unread log */ | /* Quit if not a unread log */ | ||||
if (!(eeprom[count].logs & BYPASS_LOG_CLEAR_M)) | if (!(eeprom[count].logs & BYPASS_LOG_CLEAR_M)) | ||||
break; | break; | ||||
/* | /* | ||||
* Log looks good so store the address where it's | * Log looks good so store the address where it's | ||||
* Unread Log bit is so we can clear it after safely | * Unread Log bit is so we can clear it after safely | ||||
* pulling out all of the log data. | * pulling out all of the log data. | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | while (count--) { | ||||
error = hw->mac.ops.bypass_rw(hw, cmd, &status); | error = hw->mac.ops.bypass_rw(hw, cmd, &status); | ||||
/* wait for the write to stick */ | /* wait for the write to stick */ | ||||
msec_delay(100); | msec_delay(100); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(adapter); | ||||
if (error) | if (error) | ||||
return (-EINVAL); | return (EINVAL); | ||||
} | } | ||||
status = 0; /* reset */ | status = 0; /* reset */ | ||||
/* Another log command can now run */ | /* Another log command can now run */ | ||||
while (atomic_cmpset_int(&adapter->bypass.log, 1, 0) == 0) | while (atomic_cmpset_int(&adapter->bypass.log, 1, 0) == 0) | ||||
usec_delay(3000); | usec_delay(3000); | ||||
return(error); | return (error); | ||||
unlock_err: | unlock_err: | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(adapter); | ||||
status = 0; /* reset */ | status = 0; /* reset */ | ||||
while (atomic_cmpset_int(&adapter->bypass.log, 1, 0) == 0) | while (atomic_cmpset_int(&adapter->bypass.log, 1, 0) == 0) | ||||
usec_delay(3000); | usec_delay(3000); | ||||
return (-EINVAL); | return (EINVAL); | ||||
} /* ixgbe_bp_log */ | } /* ixgbe_bp_log */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bypass_init - Set up infrastructure for the bypass feature | * ixgbe_bypass_init - Set up infrastructure for the bypass feature | ||||
* | * | ||||
* Do time and sysctl initialization here. This feature is | * Do time and sysctl initialization here. This feature is | ||||
* only enabled for the first port of a bypass adapter. | * only enabled for the first port of a bypass adapter. | ||||
************************************************************************/ | ************************************************************************/ | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | ||||
OID_AUTO, "wd_set", CTLTYPE_INT | CTLFLAG_RW, | OID_AUTO, "wd_set", CTLTYPE_INT | CTLFLAG_RW, | ||||
adapter, 0, ixgbe_bp_wd_set, "I", "Set BP Watchdog"); | adapter, 0, ixgbe_bp_wd_set, "I", "Set BP Watchdog"); | ||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | ||||
OID_AUTO, "wd_reset", CTLTYPE_INT | CTLFLAG_WR, | OID_AUTO, "wd_reset", CTLTYPE_INT | CTLFLAG_WR, | ||||
adapter, 0, ixgbe_bp_wd_reset, "S", "Bypass WD Reset"); | adapter, 0, ixgbe_bp_wd_reset, "S", "Bypass WD Reset"); | ||||
adapter->feat_en |= IXGBE_FEATURE_BYPASS; | adapter->feat_en |= IXGBE_FEATURE_BYPASS; | ||||
return; | |||||
} /* ixgbe_bypass_init */ | } /* ixgbe_bypass_init */ | ||||