Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ixgbe/if_bypass.c
Show All 37 Lines | |||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bypass_mutex_enter | * ixgbe_bypass_mutex_enter | ||||
* | * | ||||
* Mutex support for the bypass feature. Using a dual lock | * Mutex support for the bypass feature. Using a dual lock | ||||
* to facilitate a privileged access to the watchdog update | * to facilitate a privileged access to the watchdog update | ||||
* over other threads. | * over other threads. | ||||
************************************************************************/ | ************************************************************************/ | ||||
static void | static void | ||||
ixgbe_bypass_mutex_enter(struct adapter *adapter) | ixgbe_bypass_mutex_enter(struct ixgbe_softc *sc) | ||||
{ | { | ||||
while (atomic_cmpset_int(&adapter->bypass.low, 0, 1) == 0) | while (atomic_cmpset_int(&sc->bypass.low, 0, 1) == 0) | ||||
usec_delay(3000); | usec_delay(3000); | ||||
while (atomic_cmpset_int(&adapter->bypass.high, 0, 1) == 0) | while (atomic_cmpset_int(&sc->bypass.high, 0, 1) == 0) | ||||
usec_delay(3000); | usec_delay(3000); | ||||
return; | return; | ||||
} /* ixgbe_bypass_mutex_enter */ | } /* ixgbe_bypass_mutex_enter */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bypass_mutex_clear | * ixgbe_bypass_mutex_clear | ||||
************************************************************************/ | ************************************************************************/ | ||||
static void | static void | ||||
ixgbe_bypass_mutex_clear(struct adapter *adapter) | ixgbe_bypass_mutex_clear(struct ixgbe_softc *sc) | ||||
{ | { | ||||
while (atomic_cmpset_int(&adapter->bypass.high, 1, 0) == 0) | while (atomic_cmpset_int(&sc->bypass.high, 1, 0) == 0) | ||||
usec_delay(6000); | usec_delay(6000); | ||||
while (atomic_cmpset_int(&adapter->bypass.low, 1, 0) == 0) | while (atomic_cmpset_int(&sc->bypass.low, 1, 0) == 0) | ||||
usec_delay(6000); | usec_delay(6000); | ||||
return; | return; | ||||
} /* ixgbe_bypass_mutex_clear */ | } /* ixgbe_bypass_mutex_clear */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bypass_wd_mutex_enter | * ixgbe_bypass_wd_mutex_enter | ||||
* | * | ||||
* Watchdog entry is allowed to simply grab the high priority | * Watchdog entry is allowed to simply grab the high priority | ||||
************************************************************************/ | ************************************************************************/ | ||||
static void | static void | ||||
ixgbe_bypass_wd_mutex_enter(struct adapter *adapter) | ixgbe_bypass_wd_mutex_enter(struct ixgbe_softc *sc) | ||||
{ | { | ||||
while (atomic_cmpset_int(&adapter->bypass.high, 0, 1) == 0) | while (atomic_cmpset_int(&sc->bypass.high, 0, 1) == 0) | ||||
usec_delay(3000); | usec_delay(3000); | ||||
return; | return; | ||||
} /* ixgbe_bypass_wd_mutex_enter */ | } /* ixgbe_bypass_wd_mutex_enter */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bypass_wd_mutex_clear | * ixgbe_bypass_wd_mutex_clear | ||||
************************************************************************/ | ************************************************************************/ | ||||
static void | static void | ||||
ixgbe_bypass_wd_mutex_clear(struct adapter *adapter) | ixgbe_bypass_wd_mutex_clear(struct ixgbe_softc *sc) | ||||
{ | { | ||||
while (atomic_cmpset_int(&adapter->bypass.high, 1, 0) == 0) | while (atomic_cmpset_int(&sc->bypass.high, 1, 0) == 0) | ||||
usec_delay(6000); | usec_delay(6000); | ||||
return; | return; | ||||
} /* ixgbe_bypass_wd_mutex_clear */ | } /* ixgbe_bypass_wd_mutex_clear */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_get_bypass_time | * ixgbe_get_bypass_time | ||||
************************************************************************/ | ************************************************************************/ | ||||
static void | static void | ||||
Show All 14 Lines | |||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bp_version | * ixgbe_bp_version | ||||
* | * | ||||
* Display the feature version | * Display the feature version | ||||
************************************************************************/ | ************************************************************************/ | ||||
static int | static int | ||||
ixgbe_bp_version(SYSCTL_HANDLER_ARGS) | ixgbe_bp_version(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct adapter *adapter = (struct adapter *) arg1; | struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1; | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &sc->hw; | ||||
int error = 0; | int error = 0; | ||||
static int version = 0; | static int version = 0; | ||||
u32 cmd; | u32 cmd; | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
cmd = BYPASS_PAGE_CTL2 | BYPASS_WE; | cmd = BYPASS_PAGE_CTL2 | BYPASS_WE; | ||||
cmd |= (BYPASS_EEPROM_VER_ADD << BYPASS_CTL2_OFFSET_SHIFT) & | cmd |= (BYPASS_EEPROM_VER_ADD << BYPASS_CTL2_OFFSET_SHIFT) & | ||||
BYPASS_CTL2_OFFSET_M; | BYPASS_CTL2_OFFSET_M; | ||||
if ((error = hw->mac.ops.bypass_rw(hw, cmd, &version) != 0)) | if ((error = hw->mac.ops.bypass_rw(hw, cmd, &version) != 0)) | ||||
goto err; | goto err; | ||||
msec_delay(100); | msec_delay(100); | ||||
cmd &= ~BYPASS_WE; | cmd &= ~BYPASS_WE; | ||||
if ((error = hw->mac.ops.bypass_rw(hw, cmd, &version) != 0)) | if ((error = hw->mac.ops.bypass_rw(hw, cmd, &version) != 0)) | ||||
goto err; | goto err; | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
version &= BYPASS_CTL2_DATA_M; | version &= BYPASS_CTL2_DATA_M; | ||||
error = sysctl_handle_int(oidp, &version, 0, req); | error = sysctl_handle_int(oidp, &version, 0, req); | ||||
return (error); | return (error); | ||||
err: | err: | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
return (error); | return (error); | ||||
} /* ixgbe_bp_version */ | } /* ixgbe_bp_version */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bp_set_state | * ixgbe_bp_set_state | ||||
* | * | ||||
* Show/Set the Bypass State: | * Show/Set the Bypass State: | ||||
* 1 = NORMAL | * 1 = NORMAL | ||||
* 2 = BYPASS | * 2 = BYPASS | ||||
* 3 = ISOLATE | * 3 = ISOLATE | ||||
* | * | ||||
* With no argument the state is displayed, | * With no argument the state is displayed, | ||||
* passing a value will set it. | * passing a value will set it. | ||||
************************************************************************/ | ************************************************************************/ | ||||
static int | static int | ||||
ixgbe_bp_set_state(SYSCTL_HANDLER_ARGS) | ixgbe_bp_set_state(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct adapter *adapter = (struct adapter *) arg1; | struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1; | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &sc->hw; | ||||
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(sc); | ||||
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(sc); | ||||
if (error != 0) | 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 != 0) || (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; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
if ((error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | if ((error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | ||||
BYPASS_MODE_OFF_M, state) != 0)) | BYPASS_MODE_OFF_M, state) != 0)) | ||||
goto out; | goto out; | ||||
/* Set AUTO back on so FW can receive events */ | /* Set AUTO back on so FW can receive events */ | ||||
error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | ||||
BYPASS_MODE_OFF_M, BYPASS_AUTO); | BYPASS_MODE_OFF_M, BYPASS_AUTO); | ||||
out: | out: | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
usec_delay(6000); | usec_delay(6000); | ||||
return (error); | return (error); | ||||
} /* ixgbe_bp_set_state */ | } /* ixgbe_bp_set_state */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* The following routines control the operational | * The following routines control the operational | ||||
* "rules" of the feature, what behavior will occur | * "rules" of the feature, what behavior will occur | ||||
* when particular events occur. | * when particular events occur. | ||||
Show All 10 Lines | |||||
* ixgbe_bp_timeout | * ixgbe_bp_timeout | ||||
* | * | ||||
* This is to set the Rule for the watchdog, | * This is to set the Rule for the watchdog, | ||||
* not the actual watchdog timeout value. | * not the actual watchdog timeout value. | ||||
************************************************************************/ | ************************************************************************/ | ||||
static int | static int | ||||
ixgbe_bp_timeout(SYSCTL_HANDLER_ARGS) | ixgbe_bp_timeout(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct adapter *adapter = (struct adapter *) arg1; | struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1; | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &sc->hw; | ||||
int error = 0; | int error = 0; | ||||
static int timeout = 0; | static int timeout = 0; | ||||
/* Get the current value */ | /* Get the current value */ | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &timeout); | error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &timeout); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
timeout = (timeout >> BYPASS_WDTIMEOUT_SHIFT) & 0x3; | timeout = (timeout >> BYPASS_WDTIMEOUT_SHIFT) & 0x3; | ||||
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); | ||||
/* Sanity check on the setting */ | /* Sanity check on the setting */ | ||||
switch (timeout) { | switch (timeout) { | ||||
case BYPASS_NOP: | case BYPASS_NOP: | ||||
case BYPASS_NORM: | case BYPASS_NORM: | ||||
case BYPASS_BYPASS: | case BYPASS_BYPASS: | ||||
case BYPASS_ISOLATE: | case BYPASS_ISOLATE: | ||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
/* Set the new state */ | /* Set the new state */ | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | ||||
BYPASS_WDTIMEOUT_M, timeout << BYPASS_WDTIMEOUT_SHIFT); | BYPASS_WDTIMEOUT_M, timeout << BYPASS_WDTIMEOUT_SHIFT); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
usec_delay(6000); | usec_delay(6000); | ||||
return (error); | return (error); | ||||
} /* ixgbe_bp_timeout */ | } /* ixgbe_bp_timeout */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bp_main_on | * ixgbe_bp_main_on | ||||
************************************************************************/ | ************************************************************************/ | ||||
static int | static int | ||||
ixgbe_bp_main_on(SYSCTL_HANDLER_ARGS) | ixgbe_bp_main_on(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct adapter *adapter = (struct adapter *) arg1; | struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1; | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &sc->hw; | ||||
int error = 0; | int error = 0; | ||||
static int main_on = 0; | static int main_on = 0; | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_on); | error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_on); | ||||
main_on = (main_on >> BYPASS_MAIN_ON_SHIFT) & 0x3; | main_on = (main_on >> BYPASS_MAIN_ON_SHIFT) & 0x3; | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
error = sysctl_handle_int(oidp, &main_on, 0, req); | error = sysctl_handle_int(oidp, &main_on, 0, req); | ||||
if ((error) || (req->newptr == NULL)) | if ((error) || (req->newptr == NULL)) | ||||
return (error); | return (error); | ||||
/* Sanity check on the setting */ | /* Sanity check on the setting */ | ||||
switch (main_on) { | switch (main_on) { | ||||
case BYPASS_NOP: | case BYPASS_NOP: | ||||
case BYPASS_NORM: | case BYPASS_NORM: | ||||
case BYPASS_BYPASS: | case BYPASS_BYPASS: | ||||
case BYPASS_ISOLATE: | case BYPASS_ISOLATE: | ||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
/* Set the new state */ | /* Set the new state */ | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | ||||
BYPASS_MAIN_ON_M, main_on << BYPASS_MAIN_ON_SHIFT); | BYPASS_MAIN_ON_M, main_on << BYPASS_MAIN_ON_SHIFT); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
usec_delay(6000); | usec_delay(6000); | ||||
return (error); | return (error); | ||||
} /* ixgbe_bp_main_on */ | } /* ixgbe_bp_main_on */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bp_main_off | * ixgbe_bp_main_off | ||||
************************************************************************/ | ************************************************************************/ | ||||
static int | static int | ||||
ixgbe_bp_main_off(SYSCTL_HANDLER_ARGS) | ixgbe_bp_main_off(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct adapter *adapter = (struct adapter *) arg1; | struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1; | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &sc->hw; | ||||
int error = 0; | int error = 0; | ||||
static int main_off = 0; | static int main_off = 0; | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_off); | error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_off); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
main_off = (main_off >> BYPASS_MAIN_OFF_SHIFT) & 0x3; | main_off = (main_off >> BYPASS_MAIN_OFF_SHIFT) & 0x3; | ||||
error = sysctl_handle_int(oidp, &main_off, 0, req); | error = sysctl_handle_int(oidp, &main_off, 0, req); | ||||
if ((error) || (req->newptr == NULL)) | if ((error) || (req->newptr == NULL)) | ||||
return (error); | return (error); | ||||
/* Sanity check on the setting */ | /* Sanity check on the setting */ | ||||
switch (main_off) { | switch (main_off) { | ||||
case BYPASS_NOP: | case BYPASS_NOP: | ||||
case BYPASS_NORM: | case BYPASS_NORM: | ||||
case BYPASS_BYPASS: | case BYPASS_BYPASS: | ||||
case BYPASS_ISOLATE: | case BYPASS_ISOLATE: | ||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
/* Set the new state */ | /* Set the new state */ | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | ||||
BYPASS_MAIN_OFF_M, main_off << BYPASS_MAIN_OFF_SHIFT); | BYPASS_MAIN_OFF_M, main_off << BYPASS_MAIN_OFF_SHIFT); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
usec_delay(6000); | usec_delay(6000); | ||||
return (error); | return (error); | ||||
} /* ixgbe_bp_main_off */ | } /* ixgbe_bp_main_off */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bp_aux_on | * ixgbe_bp_aux_on | ||||
************************************************************************/ | ************************************************************************/ | ||||
static int | static int | ||||
ixgbe_bp_aux_on(SYSCTL_HANDLER_ARGS) | ixgbe_bp_aux_on(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct adapter *adapter = (struct adapter *) arg1; | struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1; | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &sc->hw; | ||||
int error = 0; | int error = 0; | ||||
static int aux_on = 0; | static int aux_on = 0; | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_on); | error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_on); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
aux_on = (aux_on >> BYPASS_AUX_ON_SHIFT) & 0x3; | aux_on = (aux_on >> BYPASS_AUX_ON_SHIFT) & 0x3; | ||||
error = sysctl_handle_int(oidp, &aux_on, 0, req); | error = sysctl_handle_int(oidp, &aux_on, 0, req); | ||||
if ((error) || (req->newptr == NULL)) | if ((error) || (req->newptr == NULL)) | ||||
return (error); | return (error); | ||||
/* Sanity check on the setting */ | /* Sanity check on the setting */ | ||||
switch (aux_on) { | switch (aux_on) { | ||||
case BYPASS_NOP: | case BYPASS_NOP: | ||||
case BYPASS_NORM: | case BYPASS_NORM: | ||||
case BYPASS_BYPASS: | case BYPASS_BYPASS: | ||||
case BYPASS_ISOLATE: | case BYPASS_ISOLATE: | ||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
/* Set the new state */ | /* Set the new state */ | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | ||||
BYPASS_AUX_ON_M, aux_on << BYPASS_AUX_ON_SHIFT); | BYPASS_AUX_ON_M, aux_on << BYPASS_AUX_ON_SHIFT); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
usec_delay(6000); | usec_delay(6000); | ||||
return (error); | return (error); | ||||
} /* ixgbe_bp_aux_on */ | } /* ixgbe_bp_aux_on */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bp_aux_off | * ixgbe_bp_aux_off | ||||
************************************************************************/ | ************************************************************************/ | ||||
static int | static int | ||||
ixgbe_bp_aux_off(SYSCTL_HANDLER_ARGS) | ixgbe_bp_aux_off(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct adapter *adapter = (struct adapter *) arg1; | struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1; | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &sc->hw; | ||||
int error = 0; | int error = 0; | ||||
static int aux_off = 0; | static int aux_off = 0; | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_off); | error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_off); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
aux_off = (aux_off >> BYPASS_AUX_OFF_SHIFT) & 0x3; | aux_off = (aux_off >> BYPASS_AUX_OFF_SHIFT) & 0x3; | ||||
error = sysctl_handle_int(oidp, &aux_off, 0, req); | error = sysctl_handle_int(oidp, &aux_off, 0, req); | ||||
if ((error) || (req->newptr == NULL)) | if ((error) || (req->newptr == NULL)) | ||||
return (error); | return (error); | ||||
/* Sanity check on the setting */ | /* Sanity check on the setting */ | ||||
switch (aux_off) { | switch (aux_off) { | ||||
case BYPASS_NOP: | case BYPASS_NOP: | ||||
case BYPASS_NORM: | case BYPASS_NORM: | ||||
case BYPASS_BYPASS: | case BYPASS_BYPASS: | ||||
case BYPASS_ISOLATE: | case BYPASS_ISOLATE: | ||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
/* Set the new state */ | /* Set the new state */ | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, | ||||
BYPASS_AUX_OFF_M, aux_off << BYPASS_AUX_OFF_SHIFT); | BYPASS_AUX_OFF_M, aux_off << BYPASS_AUX_OFF_SHIFT); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
usec_delay(6000); | usec_delay(6000); | ||||
return (error); | return (error); | ||||
} /* ixgbe_bp_aux_off */ | } /* ixgbe_bp_aux_off */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bp_wd_set - Set the Watchdog timer value | * ixgbe_bp_wd_set - Set the Watchdog timer value | ||||
* | * | ||||
* Valid settings are: | * Valid settings are: | ||||
* - 0 will disable the watchdog | * - 0 will disable the watchdog | ||||
* - 1, 2, 3, 4, 8, 16, 32 | * - 1, 2, 3, 4, 8, 16, 32 | ||||
* - anything else is invalid and will be ignored | * - anything else is invalid and will be ignored | ||||
************************************************************************/ | ************************************************************************/ | ||||
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 ixgbe_softc *sc = (struct ixgbe_softc *) arg1; | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &sc->hw; | ||||
int error, tmp; | int error, tmp; | ||||
static int timeout = 0; | static int timeout = 0; | ||||
u32 mask, arg; | u32 mask, arg; | ||||
/* Get the current hardware value */ | /* Get the current hardware value */ | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
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(sc); | ||||
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; | ||||
Show All 30 Lines | ixgbe_bp_wd_set(SYSCTL_HANDLER_ARGS) | ||||
case 32: | case 32: | ||||
arg |= BYPASS_WDT_32 << BYPASS_WDT_TIME_SHIFT; | arg |= BYPASS_WDT_32 << BYPASS_WDT_TIME_SHIFT; | ||||
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(sc); | ||||
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(sc); | ||||
return (error); | return (error); | ||||
} /* ixgbe_bp_wd_set */ | } /* ixgbe_bp_wd_set */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bp_wd_reset - Reset the Watchdog timer | * ixgbe_bp_wd_reset - Reset the Watchdog timer | ||||
* | * | ||||
* To activate this it must be called with any argument. | * To activate this it must be called with any argument. | ||||
************************************************************************/ | ************************************************************************/ | ||||
static int | static int | ||||
ixgbe_bp_wd_reset(SYSCTL_HANDLER_ARGS) | ixgbe_bp_wd_reset(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct adapter *adapter = (struct adapter *) arg1; | struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1; | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &sc->hw; | ||||
u32 sec, year; | u32 sec, year; | ||||
int cmd, count = 0, error = 0; | int cmd, count = 0, error = 0; | ||||
int reset_wd = 0; | int reset_wd = 0; | ||||
error = sysctl_handle_int(oidp, &reset_wd, 0, req); | error = sysctl_handle_int(oidp, &reset_wd, 0, req); | ||||
if ((error) || (req->newptr == NULL)) | if ((error) || (req->newptr == NULL)) | ||||
return (error); | return (error); | ||||
cmd = BYPASS_PAGE_CTL1 | BYPASS_WE | BYPASS_CTL1_WDT_PET; | cmd = BYPASS_PAGE_CTL1 | BYPASS_WE | BYPASS_CTL1_WDT_PET; | ||||
/* Resync the FW time while writing to CTL1 anyway */ | /* Resync the FW time while writing to CTL1 anyway */ | ||||
ixgbe_get_bypass_time(&year, &sec); | ixgbe_get_bypass_time(&year, &sec); | ||||
cmd |= (sec & BYPASS_CTL1_TIME_M) | BYPASS_CTL1_VALID; | cmd |= (sec & BYPASS_CTL1_TIME_M) | BYPASS_CTL1_VALID; | ||||
cmd |= BYPASS_CTL1_OFFTRST; | cmd |= BYPASS_CTL1_OFFTRST; | ||||
ixgbe_bypass_wd_mutex_enter(adapter); | ixgbe_bypass_wd_mutex_enter(sc); | ||||
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; | ||||
} | } | ||||
error = 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) { | 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(sc); | ||||
return (error); | return (error); | ||||
} /* ixgbe_bp_wd_reset */ | } /* ixgbe_bp_wd_reset */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_bp_log - Display the bypass log | * ixgbe_bp_log - Display the bypass log | ||||
* | * | ||||
* You must pass a non-zero arg to sysctl | * You must pass a non-zero arg to sysctl | ||||
************************************************************************/ | ************************************************************************/ | ||||
static int | static int | ||||
ixgbe_bp_log(SYSCTL_HANDLER_ARGS) | ixgbe_bp_log(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct adapter *adapter = (struct adapter *) arg1; | struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1; | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &sc->hw; | ||||
u32 cmd, base, head; | u32 cmd, base, head; | ||||
u32 log_off, count = 0; | u32 log_off, count = 0; | ||||
static int status = 0; | static int status = 0; | ||||
u8 data; | u8 data; | ||||
struct ixgbe_bypass_eeprom eeprom[BYPASS_MAX_LOGS]; | struct ixgbe_bypass_eeprom eeprom[BYPASS_MAX_LOGS]; | ||||
int i, error = 0; | int i, error = 0; | ||||
error = sysctl_handle_int(oidp, &status, 0, req); | error = sysctl_handle_int(oidp, &status, 0, req); | ||||
if ((error) || (req->newptr == NULL)) | if ((error) || (req->newptr == NULL)) | ||||
return (error); | return (error); | ||||
/* Keep the log display single-threaded */ | /* Keep the log display single-threaded */ | ||||
while (atomic_cmpset_int(&adapter->bypass.log, 0, 1) == 0) | while (atomic_cmpset_int(&sc->bypass.log, 0, 1) == 0) | ||||
usec_delay(3000); | usec_delay(3000); | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
/* Find Current head of the log eeprom offset */ | /* Find Current head of the log eeprom offset */ | ||||
cmd = BYPASS_PAGE_CTL2 | BYPASS_WE; | cmd = BYPASS_PAGE_CTL2 | BYPASS_WE; | ||||
cmd |= (0x1 << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M; | cmd |= (0x1 << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M; | ||||
error = hw->mac.ops.bypass_rw(hw, cmd, &status); | error = hw->mac.ops.bypass_rw(hw, cmd, &status); | ||||
if (error) | if (error) | ||||
goto unlock_err; | goto unlock_err; | ||||
/* wait for the write to stick */ | /* wait for the write to stick */ | ||||
msec_delay(100); | msec_delay(100); | ||||
/* Now read the results */ | /* Now read the results */ | ||||
cmd &= ~BYPASS_WE; | cmd &= ~BYPASS_WE; | ||||
error = hw->mac.ops.bypass_rw(hw, cmd, &status); | error = hw->mac.ops.bypass_rw(hw, cmd, &status); | ||||
if (error) | if (error) | ||||
goto unlock_err; | goto unlock_err; | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
base = status & BYPASS_CTL2_DATA_M; | base = status & BYPASS_CTL2_DATA_M; | ||||
head = (status & BYPASS_CTL2_HEAD_M) >> BYPASS_CTL2_HEAD_SHIFT; | head = (status & BYPASS_CTL2_HEAD_M) >> BYPASS_CTL2_HEAD_SHIFT; | ||||
/* address of the first log */ | /* address of the first log */ | ||||
log_off = base + (head * 5); | log_off = base + (head * 5); | ||||
/* extract all the log entries */ | /* extract all the log entries */ | ||||
while (count < BYPASS_MAX_LOGS) { | while (count < BYPASS_MAX_LOGS) { | ||||
eeprom[count].logs = 0; | eeprom[count].logs = 0; | ||||
eeprom[count].actions = 0; | eeprom[count].actions = 0; | ||||
/* 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(sc); | ||||
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(sc); | ||||
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(sc); | ||||
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(sc); | ||||
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 | ||||
Show All 38 Lines | while (count--) { | ||||
mon = i + 1; /* display month as 1-12 */ | mon = i + 1; /* display month as 1-12 */ | ||||
time -= (day_mon[LEAP_YR(year)][i] * SEC_PER_DAY); | time -= (day_mon[LEAP_YR(year)][i] * SEC_PER_DAY); | ||||
days = (time / SEC_PER_DAY) + 1; /* first day is 1 */ | days = (time / SEC_PER_DAY) + 1; /* first day is 1 */ | ||||
time %= SEC_PER_DAY; | time %= SEC_PER_DAY; | ||||
hours = time / (60 * 60); | hours = time / (60 * 60); | ||||
time %= (60 * 60); | time %= (60 * 60); | ||||
min = time / 60; | min = time / 60; | ||||
sec = time % 60; | sec = time % 60; | ||||
device_printf(adapter->dev, | device_printf(sc->dev, | ||||
"UT %02d/%02d %02d:%02d:%02d %8.8s -> %7.7s\n", | "UT %02d/%02d %02d:%02d:%02d %8.8s -> %7.7s\n", | ||||
mon, days, hours, min, sec, event_str[event], | mon, days, hours, min, sec, event_str[event], | ||||
action_str[action]); | action_str[action]); | ||||
cmd = BYPASS_PAGE_CTL2 | BYPASS_WE | BYPASS_CTL2_RW; | cmd = BYPASS_PAGE_CTL2 | BYPASS_WE | BYPASS_CTL2_RW; | ||||
cmd |= ((eeprom[count].clear_off + 3) | cmd |= ((eeprom[count].clear_off + 3) | ||||
<< BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M; | << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M; | ||||
cmd |= ((eeprom[count].logs & ~BYPASS_LOG_CLEAR_M) >> 24); | cmd |= ((eeprom[count].logs & ~BYPASS_LOG_CLEAR_M) >> 24); | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
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(sc); | ||||
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(&sc->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(sc); | ||||
status = 0; /* reset */ | status = 0; /* reset */ | ||||
while (atomic_cmpset_int(&adapter->bypass.log, 1, 0) == 0) | while (atomic_cmpset_int(&sc->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. | ||||
************************************************************************/ | ************************************************************************/ | ||||
void | void | ||||
ixgbe_bypass_init(struct adapter *adapter) | ixgbe_bypass_init(struct ixgbe_softc *sc) | ||||
{ | { | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &sc->hw; | ||||
device_t dev = adapter->dev; | device_t dev = sc->dev; | ||||
struct sysctl_oid *bp_node; | struct sysctl_oid *bp_node; | ||||
struct sysctl_oid_list *bp_list; | struct sysctl_oid_list *bp_list; | ||||
u32 mask, value, sec, year; | u32 mask, value, sec, year; | ||||
if (!(adapter->feat_cap & IXGBE_FEATURE_BYPASS)) | if (!(sc->feat_cap & IXGBE_FEATURE_BYPASS)) | ||||
return; | return; | ||||
/* First set up time for the hardware */ | /* First set up time for the hardware */ | ||||
ixgbe_get_bypass_time(&year, &sec); | ixgbe_get_bypass_time(&year, &sec); | ||||
mask = BYPASS_CTL1_TIME_M | mask = BYPASS_CTL1_TIME_M | ||||
| BYPASS_CTL1_VALID_M | | BYPASS_CTL1_VALID_M | ||||
| BYPASS_CTL1_OFFTRST_M; | | BYPASS_CTL1_OFFTRST_M; | ||||
value = (sec & BYPASS_CTL1_TIME_M) | value = (sec & BYPASS_CTL1_TIME_M) | ||||
| BYPASS_CTL1_VALID | | BYPASS_CTL1_VALID | ||||
| BYPASS_CTL1_OFFTRST; | | BYPASS_CTL1_OFFTRST; | ||||
ixgbe_bypass_mutex_enter(adapter); | ixgbe_bypass_mutex_enter(sc); | ||||
hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL1, mask, value); | hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL1, mask, value); | ||||
ixgbe_bypass_mutex_clear(adapter); | ixgbe_bypass_mutex_clear(sc); | ||||
/* Now set up the SYSCTL infrastructure */ | /* Now set up the SYSCTL infrastructure */ | ||||
/* | /* | ||||
* The log routine is kept separate from the other | * The log routine is kept separate from the other | ||||
* children so a general display command like: | * children so a general display command like: | ||||
* `sysctl dev.ix.0.bypass` will not show the log. | * `sysctl dev.ix.0.bypass` will not show the log. | ||||
*/ | */ | ||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), | ||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), | SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), | ||||
OID_AUTO, "bypass_log", | OID_AUTO, "bypass_log", | ||||
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
adapter, 0, ixgbe_bp_log, "I", "Bypass Log"); | sc, 0, ixgbe_bp_log, "I", "Bypass Log"); | ||||
/* All other setting are hung from the 'bypass' node */ | /* All other setting are hung from the 'bypass' node */ | ||||
bp_node = SYSCTL_ADD_NODE(device_get_sysctl_ctx(dev), | bp_node = SYSCTL_ADD_NODE(device_get_sysctl_ctx(dev), | ||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), | SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), | ||||
OID_AUTO, "bypass", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Bypass"); | OID_AUTO, "bypass", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Bypass"); | ||||
bp_list = SYSCTL_CHILDREN(bp_node); | bp_list = SYSCTL_CHILDREN(bp_node); | ||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | ||||
OID_AUTO, "version", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, | OID_AUTO, "version", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, | ||||
adapter, 0, ixgbe_bp_version, "I", "Bypass Version"); | sc, 0, ixgbe_bp_version, "I", "Bypass Version"); | ||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | ||||
OID_AUTO, "state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | OID_AUTO, "state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
adapter, 0, ixgbe_bp_set_state, "I", "Bypass State"); | sc, 0, ixgbe_bp_set_state, "I", "Bypass State"); | ||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | ||||
OID_AUTO, "timeout", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | OID_AUTO, "timeout", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
adapter, 0, ixgbe_bp_timeout, "I", "Bypass Timeout"); | sc, 0, ixgbe_bp_timeout, "I", "Bypass Timeout"); | ||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | ||||
OID_AUTO, "main_on", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | OID_AUTO, "main_on", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
adapter, 0, ixgbe_bp_main_on, "I", "Bypass Main On"); | sc, 0, ixgbe_bp_main_on, "I", "Bypass Main On"); | ||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | ||||
OID_AUTO, "main_off", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | OID_AUTO, "main_off", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
adapter, 0, ixgbe_bp_main_off, "I", "Bypass Main Off"); | sc, 0, ixgbe_bp_main_off, "I", "Bypass Main Off"); | ||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | ||||
OID_AUTO, "aux_on", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | OID_AUTO, "aux_on", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
adapter, 0, ixgbe_bp_aux_on, "I", "Bypass Aux On"); | sc, 0, ixgbe_bp_aux_on, "I", "Bypass Aux On"); | ||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | ||||
OID_AUTO, "aux_off", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | OID_AUTO, "aux_off", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
adapter, 0, ixgbe_bp_aux_off, "I", "Bypass Aux Off"); | sc, 0, ixgbe_bp_aux_off, "I", "Bypass Aux Off"); | ||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list, | ||||
OID_AUTO, "wd_set", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | OID_AUTO, "wd_set", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
adapter, 0, ixgbe_bp_wd_set, "I", "Set BP Watchdog"); | sc, 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 | CTLFLAG_NEEDGIANT, | OID_AUTO, "wd_reset", CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_NEEDGIANT, | ||||
adapter, 0, ixgbe_bp_wd_reset, "S", "Bypass WD Reset"); | sc, 0, ixgbe_bp_wd_reset, "S", "Bypass WD Reset"); | ||||
adapter->feat_en |= IXGBE_FEATURE_BYPASS; | sc->feat_en |= IXGBE_FEATURE_BYPASS; | ||||
} /* ixgbe_bypass_init */ | } /* ixgbe_bypass_init */ | ||||