Home | History | Annotate | Line # | Download | only in ixgbe
if_bypass.c revision 1.1
      1  1.1  msaitoh /******************************************************************************
      2  1.1  msaitoh 
      3  1.1  msaitoh   Copyright (c) 2001-2017, Intel Corporation
      4  1.1  msaitoh   All rights reserved.
      5  1.1  msaitoh 
      6  1.1  msaitoh   Redistribution and use in source and binary forms, with or without
      7  1.1  msaitoh   modification, are permitted provided that the following conditions are met:
      8  1.1  msaitoh 
      9  1.1  msaitoh    1. Redistributions of source code must retain the above copyright notice,
     10  1.1  msaitoh       this list of conditions and the following disclaimer.
     11  1.1  msaitoh 
     12  1.1  msaitoh    2. Redistributions in binary form must reproduce the above copyright
     13  1.1  msaitoh       notice, this list of conditions and the following disclaimer in the
     14  1.1  msaitoh       documentation and/or other materials provided with the distribution.
     15  1.1  msaitoh 
     16  1.1  msaitoh    3. Neither the name of the Intel Corporation nor the names of its
     17  1.1  msaitoh       contributors may be used to endorse or promote products derived from
     18  1.1  msaitoh       this software without specific prior written permission.
     19  1.1  msaitoh 
     20  1.1  msaitoh   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     21  1.1  msaitoh   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     22  1.1  msaitoh   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     23  1.1  msaitoh   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     24  1.1  msaitoh   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  1.1  msaitoh   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  1.1  msaitoh   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  1.1  msaitoh   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  1.1  msaitoh   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  1.1  msaitoh   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  1.1  msaitoh   POSSIBILITY OF SUCH DAMAGE.
     31  1.1  msaitoh 
     32  1.1  msaitoh ******************************************************************************/
     33  1.1  msaitoh /*$FreeBSD: head/sys/dev/ixgbe/if_bypass.c 320688 2017-07-05 17:27:03Z erj $*/
     34  1.1  msaitoh 
     35  1.1  msaitoh 
     36  1.1  msaitoh #include "ixgbe.h"
     37  1.1  msaitoh 
     38  1.1  msaitoh /************************************************************************
     39  1.1  msaitoh  * ixgbe_bypass_mutex_enter
     40  1.1  msaitoh  *
     41  1.1  msaitoh  *   Mutex support for the bypass feature. Using a dual lock
     42  1.1  msaitoh  *   to facilitate a privileged access to the watchdog update
     43  1.1  msaitoh  *   over other threads.
     44  1.1  msaitoh  ************************************************************************/
     45  1.1  msaitoh static void
     46  1.1  msaitoh ixgbe_bypass_mutex_enter(struct adapter *adapter)
     47  1.1  msaitoh {
     48  1.1  msaitoh 	while (atomic_cas_uint(&adapter->bypass.low, 0, 1) == 0)
     49  1.1  msaitoh 		usec_delay(3000);
     50  1.1  msaitoh 	while (atomic_cas_uint(&adapter->bypass.high, 0, 1) == 0)
     51  1.1  msaitoh 		usec_delay(3000);
     52  1.1  msaitoh 	return;
     53  1.1  msaitoh } /* ixgbe_bypass_mutex_enter */
     54  1.1  msaitoh 
     55  1.1  msaitoh /************************************************************************
     56  1.1  msaitoh  * ixgbe_bypass_mutex_clear
     57  1.1  msaitoh  ************************************************************************/
     58  1.1  msaitoh static void
     59  1.1  msaitoh ixgbe_bypass_mutex_clear(struct adapter *adapter)
     60  1.1  msaitoh {
     61  1.1  msaitoh 	while (atomic_cas_uint(&adapter->bypass.high, 1, 0) == 0)
     62  1.1  msaitoh 		usec_delay(6000);
     63  1.1  msaitoh 	while (atomic_cas_uint(&adapter->bypass.low, 1, 0) == 0)
     64  1.1  msaitoh 		usec_delay(6000);
     65  1.1  msaitoh 	return;
     66  1.1  msaitoh } /* ixgbe_bypass_mutex_clear */
     67  1.1  msaitoh 
     68  1.1  msaitoh /************************************************************************
     69  1.1  msaitoh  * ixgbe_bypass_wd_mutex_enter
     70  1.1  msaitoh  *
     71  1.1  msaitoh  *   Watchdog entry is allowed to simply grab the high priority
     72  1.1  msaitoh  ************************************************************************/
     73  1.1  msaitoh static void
     74  1.1  msaitoh ixgbe_bypass_wd_mutex_enter(struct adapter *adapter)
     75  1.1  msaitoh {
     76  1.1  msaitoh 	while (atomic_cas_uint(&adapter->bypass.high, 0, 1) == 0)
     77  1.1  msaitoh 		usec_delay(3000);
     78  1.1  msaitoh 	return;
     79  1.1  msaitoh } /* ixgbe_bypass_wd_mutex_enter */
     80  1.1  msaitoh 
     81  1.1  msaitoh /************************************************************************
     82  1.1  msaitoh  * ixgbe_bypass_wd_mutex_clear
     83  1.1  msaitoh  ************************************************************************/
     84  1.1  msaitoh static void
     85  1.1  msaitoh ixgbe_bypass_wd_mutex_clear(struct adapter *adapter)
     86  1.1  msaitoh {
     87  1.1  msaitoh 	while (atomic_cas_uint(&adapter->bypass.high, 1, 0) == 0)
     88  1.1  msaitoh 		usec_delay(6000);
     89  1.1  msaitoh 	return;
     90  1.1  msaitoh } /* ixgbe_bypass_wd_mutex_clear */
     91  1.1  msaitoh 
     92  1.1  msaitoh /************************************************************************
     93  1.1  msaitoh  * ixgbe_get_bypass_time
     94  1.1  msaitoh  ************************************************************************/
     95  1.1  msaitoh static void
     96  1.1  msaitoh ixgbe_get_bypass_time(u32 *year, u32 *sec)
     97  1.1  msaitoh {
     98  1.1  msaitoh 	struct timespec current;
     99  1.1  msaitoh 
    100  1.1  msaitoh 	*year = 1970;           /* time starts at 01/01/1970 */
    101  1.1  msaitoh 	nanotime(&current);
    102  1.1  msaitoh 	*sec = current.tv_sec;
    103  1.1  msaitoh 
    104  1.1  msaitoh 	while(*sec > SEC_THIS_YEAR(*year)) {
    105  1.1  msaitoh 		*sec -= SEC_THIS_YEAR(*year);
    106  1.1  msaitoh 		(*year)++;
    107  1.1  msaitoh 	}
    108  1.1  msaitoh } /* ixgbe_get_bypass_time */
    109  1.1  msaitoh 
    110  1.1  msaitoh /************************************************************************
    111  1.1  msaitoh  * ixgbe_bp_version
    112  1.1  msaitoh  *
    113  1.1  msaitoh  *   Display the feature version
    114  1.1  msaitoh  ************************************************************************/
    115  1.1  msaitoh static int
    116  1.1  msaitoh ixgbe_bp_version(SYSCTLFN_ARGS)
    117  1.1  msaitoh {
    118  1.1  msaitoh 	struct sysctlnode node = *rnode;
    119  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    120  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    121  1.1  msaitoh 	int             error = 0;
    122  1.1  msaitoh 	static int      featversion = 0;
    123  1.1  msaitoh 	u32             cmd;
    124  1.1  msaitoh 
    125  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    126  1.1  msaitoh 	cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
    127  1.1  msaitoh 	cmd |= (BYPASS_EEPROM_VER_ADD << BYPASS_CTL2_OFFSET_SHIFT) &
    128  1.1  msaitoh 	    BYPASS_CTL2_OFFSET_M;
    129  1.1  msaitoh 	if ((error = hw->mac.ops.bypass_rw(hw, cmd, &featversion) != 0))
    130  1.1  msaitoh 		goto err;
    131  1.1  msaitoh 	msec_delay(100);
    132  1.1  msaitoh 	cmd &= ~BYPASS_WE;
    133  1.1  msaitoh 	if ((error = hw->mac.ops.bypass_rw(hw, cmd, &featversion) != 0))
    134  1.1  msaitoh 		goto err;
    135  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    136  1.1  msaitoh 	featversion &= BYPASS_CTL2_DATA_M;
    137  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    138  1.1  msaitoh 	return (error);
    139  1.1  msaitoh err:
    140  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    141  1.1  msaitoh 	return (error);
    142  1.1  msaitoh 
    143  1.1  msaitoh } /* ixgbe_bp_version */
    144  1.1  msaitoh 
    145  1.1  msaitoh /************************************************************************
    146  1.1  msaitoh  * ixgbe_bp_set_state
    147  1.1  msaitoh  *
    148  1.1  msaitoh  *   Show/Set the Bypass State:
    149  1.1  msaitoh  *	1 = NORMAL
    150  1.1  msaitoh  *	2 = BYPASS
    151  1.1  msaitoh  *	3 = ISOLATE
    152  1.1  msaitoh  *
    153  1.1  msaitoh  *	With no argument the state is displayed,
    154  1.1  msaitoh  *	passing a value will set it.
    155  1.1  msaitoh  ************************************************************************/
    156  1.1  msaitoh static int
    157  1.1  msaitoh ixgbe_bp_set_state(SYSCTLFN_ARGS)
    158  1.1  msaitoh {
    159  1.1  msaitoh 	struct sysctlnode node = *rnode;
    160  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    161  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    162  1.1  msaitoh 	int             error = 0;
    163  1.1  msaitoh 	static int      state = 0;
    164  1.1  msaitoh 
    165  1.1  msaitoh 	/* Get the current state */
    166  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    167  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw,
    168  1.1  msaitoh 	    BYPASS_PAGE_CTL0, &state);
    169  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    170  1.1  msaitoh 	if (error)
    171  1.1  msaitoh 		return (error);
    172  1.1  msaitoh 	state = (state >> BYPASS_STATUS_OFF_SHIFT) & 0x3;
    173  1.1  msaitoh 
    174  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    175  1.1  msaitoh 	if ((error) || (newp == NULL))
    176  1.1  msaitoh 		return (error);
    177  1.1  msaitoh 
    178  1.1  msaitoh 	/* Sanity check new state */
    179  1.1  msaitoh 	switch (state) {
    180  1.1  msaitoh 	case BYPASS_NORM:
    181  1.1  msaitoh 	case BYPASS_BYPASS:
    182  1.1  msaitoh 	case BYPASS_ISOLATE:
    183  1.1  msaitoh 		break;
    184  1.1  msaitoh 	default:
    185  1.1  msaitoh 		return (EINVAL);
    186  1.1  msaitoh 	}
    187  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    188  1.1  msaitoh 	if ((error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    189  1.1  msaitoh 	    BYPASS_MODE_OFF_M, state) != 0))
    190  1.1  msaitoh 		goto out;
    191  1.1  msaitoh 	/* Set AUTO back on so FW can receive events */
    192  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    193  1.1  msaitoh 	    BYPASS_MODE_OFF_M, BYPASS_AUTO);
    194  1.1  msaitoh out:
    195  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    196  1.1  msaitoh 	usec_delay(6000);
    197  1.1  msaitoh 	return (error);
    198  1.1  msaitoh } /* ixgbe_bp_set_state */
    199  1.1  msaitoh 
    200  1.1  msaitoh /************************************************************************
    201  1.1  msaitoh  * The following routines control the operational
    202  1.1  msaitoh  * "rules" of the feature, what behavior will occur
    203  1.1  msaitoh  * when particular events occur.
    204  1.1  msaitoh  * 	Values are:
    205  1.1  msaitoh  *		0 - no change for the event (NOP)
    206  1.1  msaitoh  *		1 - go to Normal operation
    207  1.1  msaitoh  *		2 - go to Bypass operation
    208  1.1  msaitoh  *		3 - go to Isolate operation
    209  1.1  msaitoh  * Calling the entry with no argument just displays
    210  1.1  msaitoh  * the current rule setting.
    211  1.1  msaitoh  ************************************************************************/
    212  1.1  msaitoh 
    213  1.1  msaitoh /************************************************************************
    214  1.1  msaitoh  * ixgbe_bp_timeout
    215  1.1  msaitoh  *
    216  1.1  msaitoh  * This is to set the Rule for the watchdog,
    217  1.1  msaitoh  * not the actual watchdog timeout value.
    218  1.1  msaitoh  ************************************************************************/
    219  1.1  msaitoh static int
    220  1.1  msaitoh ixgbe_bp_timeout(SYSCTLFN_ARGS)
    221  1.1  msaitoh {
    222  1.1  msaitoh 	struct sysctlnode node = *rnode;
    223  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    224  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    225  1.1  msaitoh 	int             error = 0;
    226  1.1  msaitoh 	static int      timeout = 0;
    227  1.1  msaitoh 
    228  1.1  msaitoh 	/* Get the current value */
    229  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    230  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &timeout);
    231  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    232  1.1  msaitoh 	if (error)
    233  1.1  msaitoh 		return (error);
    234  1.1  msaitoh 	timeout = (timeout >> BYPASS_WDTIMEOUT_SHIFT) & 0x3;
    235  1.1  msaitoh 
    236  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    237  1.1  msaitoh 	if ((error) || (newp == NULL))
    238  1.1  msaitoh 		return (error);
    239  1.1  msaitoh 
    240  1.1  msaitoh 	/* Sanity check on the setting */
    241  1.1  msaitoh 	switch (timeout) {
    242  1.1  msaitoh 	case BYPASS_NOP:
    243  1.1  msaitoh 	case BYPASS_NORM:
    244  1.1  msaitoh 	case BYPASS_BYPASS:
    245  1.1  msaitoh 	case BYPASS_ISOLATE:
    246  1.1  msaitoh 		break;
    247  1.1  msaitoh 	default:
    248  1.1  msaitoh 		return (EINVAL);
    249  1.1  msaitoh 	}
    250  1.1  msaitoh 
    251  1.1  msaitoh 	/* Set the new state */
    252  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    253  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    254  1.1  msaitoh 	    BYPASS_WDTIMEOUT_M, timeout << BYPASS_WDTIMEOUT_SHIFT);
    255  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    256  1.1  msaitoh 	usec_delay(6000);
    257  1.1  msaitoh 	return (error);
    258  1.1  msaitoh } /* ixgbe_bp_timeout */
    259  1.1  msaitoh 
    260  1.1  msaitoh /************************************************************************
    261  1.1  msaitoh  * ixgbe_bp_main_on
    262  1.1  msaitoh  ************************************************************************/
    263  1.1  msaitoh static int
    264  1.1  msaitoh ixgbe_bp_main_on(SYSCTLFN_ARGS)
    265  1.1  msaitoh {
    266  1.1  msaitoh 	struct sysctlnode node = *rnode;
    267  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    268  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    269  1.1  msaitoh 	int             error = 0;
    270  1.1  msaitoh 	static int      main_on = 0;
    271  1.1  msaitoh 
    272  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    273  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_on);
    274  1.1  msaitoh 	main_on = (main_on >> BYPASS_MAIN_ON_SHIFT) & 0x3;
    275  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    276  1.1  msaitoh 	if (error)
    277  1.1  msaitoh 		return (error);
    278  1.1  msaitoh 
    279  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    280  1.1  msaitoh 	if ((error) || (newp == NULL))
    281  1.1  msaitoh 		return (error);
    282  1.1  msaitoh 
    283  1.1  msaitoh 	/* Sanity check on the setting */
    284  1.1  msaitoh 	switch (main_on) {
    285  1.1  msaitoh 	case BYPASS_NOP:
    286  1.1  msaitoh 	case BYPASS_NORM:
    287  1.1  msaitoh 	case BYPASS_BYPASS:
    288  1.1  msaitoh 	case BYPASS_ISOLATE:
    289  1.1  msaitoh 		break;
    290  1.1  msaitoh 	default:
    291  1.1  msaitoh 		return (EINVAL);
    292  1.1  msaitoh 	}
    293  1.1  msaitoh 
    294  1.1  msaitoh 	/* Set the new state */
    295  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    296  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    297  1.1  msaitoh 	    BYPASS_MAIN_ON_M, main_on << BYPASS_MAIN_ON_SHIFT);
    298  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    299  1.1  msaitoh 	usec_delay(6000);
    300  1.1  msaitoh 	return (error);
    301  1.1  msaitoh } /* ixgbe_bp_main_on */
    302  1.1  msaitoh 
    303  1.1  msaitoh /************************************************************************
    304  1.1  msaitoh  * ixgbe_bp_main_off
    305  1.1  msaitoh  ************************************************************************/
    306  1.1  msaitoh static int
    307  1.1  msaitoh ixgbe_bp_main_off(SYSCTLFN_ARGS)
    308  1.1  msaitoh {
    309  1.1  msaitoh 	struct sysctlnode node = *rnode;
    310  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    311  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    312  1.1  msaitoh 	int             error = 0;
    313  1.1  msaitoh 	static int      main_off = 0;
    314  1.1  msaitoh 
    315  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    316  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_off);
    317  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    318  1.1  msaitoh 	if (error)
    319  1.1  msaitoh 		return (error);
    320  1.1  msaitoh 	main_off = (main_off >> BYPASS_MAIN_OFF_SHIFT) & 0x3;
    321  1.1  msaitoh 
    322  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    323  1.1  msaitoh 	if ((error) || (newp == NULL))
    324  1.1  msaitoh 		return (error);
    325  1.1  msaitoh 
    326  1.1  msaitoh 	/* Sanity check on the setting */
    327  1.1  msaitoh 	switch (main_off) {
    328  1.1  msaitoh 	case BYPASS_NOP:
    329  1.1  msaitoh 	case BYPASS_NORM:
    330  1.1  msaitoh 	case BYPASS_BYPASS:
    331  1.1  msaitoh 	case BYPASS_ISOLATE:
    332  1.1  msaitoh 		break;
    333  1.1  msaitoh 	default:
    334  1.1  msaitoh 		return (EINVAL);
    335  1.1  msaitoh 	}
    336  1.1  msaitoh 
    337  1.1  msaitoh 	/* Set the new state */
    338  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    339  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    340  1.1  msaitoh 	    BYPASS_MAIN_OFF_M, main_off << BYPASS_MAIN_OFF_SHIFT);
    341  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    342  1.1  msaitoh 	usec_delay(6000);
    343  1.1  msaitoh 	return (error);
    344  1.1  msaitoh } /* ixgbe_bp_main_off */
    345  1.1  msaitoh 
    346  1.1  msaitoh /************************************************************************
    347  1.1  msaitoh  * ixgbe_bp_aux_on
    348  1.1  msaitoh  ************************************************************************/
    349  1.1  msaitoh static int
    350  1.1  msaitoh ixgbe_bp_aux_on(SYSCTLFN_ARGS)
    351  1.1  msaitoh {
    352  1.1  msaitoh 	struct sysctlnode node = *rnode;
    353  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    354  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    355  1.1  msaitoh 	int             error = 0;
    356  1.1  msaitoh 	static int      aux_on = 0;
    357  1.1  msaitoh 
    358  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    359  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_on);
    360  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    361  1.1  msaitoh 	if (error)
    362  1.1  msaitoh 		return (error);
    363  1.1  msaitoh 	aux_on = (aux_on >> BYPASS_AUX_ON_SHIFT) & 0x3;
    364  1.1  msaitoh 
    365  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    366  1.1  msaitoh 	if ((error) || (newp == NULL))
    367  1.1  msaitoh 		return (error);
    368  1.1  msaitoh 
    369  1.1  msaitoh 	/* Sanity check on the setting */
    370  1.1  msaitoh 	switch (aux_on) {
    371  1.1  msaitoh 	case BYPASS_NOP:
    372  1.1  msaitoh 	case BYPASS_NORM:
    373  1.1  msaitoh 	case BYPASS_BYPASS:
    374  1.1  msaitoh 	case BYPASS_ISOLATE:
    375  1.1  msaitoh 		break;
    376  1.1  msaitoh 	default:
    377  1.1  msaitoh 		return (EINVAL);
    378  1.1  msaitoh 	}
    379  1.1  msaitoh 
    380  1.1  msaitoh 	/* Set the new state */
    381  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    382  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    383  1.1  msaitoh 	    BYPASS_AUX_ON_M, aux_on << BYPASS_AUX_ON_SHIFT);
    384  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    385  1.1  msaitoh 	usec_delay(6000);
    386  1.1  msaitoh 	return (error);
    387  1.1  msaitoh } /* ixgbe_bp_aux_on */
    388  1.1  msaitoh 
    389  1.1  msaitoh /************************************************************************
    390  1.1  msaitoh  * ixgbe_bp_aux_off
    391  1.1  msaitoh  ************************************************************************/
    392  1.1  msaitoh static int
    393  1.1  msaitoh ixgbe_bp_aux_off(SYSCTLFN_ARGS)
    394  1.1  msaitoh {
    395  1.1  msaitoh 	struct sysctlnode node = *rnode;
    396  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    397  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    398  1.1  msaitoh 	int             error = 0;
    399  1.1  msaitoh 	static int      aux_off = 0;
    400  1.1  msaitoh 
    401  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    402  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_off);
    403  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    404  1.1  msaitoh 	if (error)
    405  1.1  msaitoh 		return (error);
    406  1.1  msaitoh 	aux_off = (aux_off >> BYPASS_AUX_OFF_SHIFT) & 0x3;
    407  1.1  msaitoh 
    408  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    409  1.1  msaitoh 	if ((error) || (newp == NULL))
    410  1.1  msaitoh 		return (error);
    411  1.1  msaitoh 
    412  1.1  msaitoh 	/* Sanity check on the setting */
    413  1.1  msaitoh 	switch (aux_off) {
    414  1.1  msaitoh 	case BYPASS_NOP:
    415  1.1  msaitoh 	case BYPASS_NORM:
    416  1.1  msaitoh 	case BYPASS_BYPASS:
    417  1.1  msaitoh 	case BYPASS_ISOLATE:
    418  1.1  msaitoh 		break;
    419  1.1  msaitoh 	default:
    420  1.1  msaitoh 		return (EINVAL);
    421  1.1  msaitoh 	}
    422  1.1  msaitoh 
    423  1.1  msaitoh 	/* Set the new state */
    424  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    425  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    426  1.1  msaitoh 	    BYPASS_AUX_OFF_M, aux_off << BYPASS_AUX_OFF_SHIFT);
    427  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    428  1.1  msaitoh 	usec_delay(6000);
    429  1.1  msaitoh 	return (error);
    430  1.1  msaitoh } /* ixgbe_bp_aux_off */
    431  1.1  msaitoh 
    432  1.1  msaitoh /************************************************************************
    433  1.1  msaitoh  * ixgbe_bp_wd_set - Set the Watchdog timer value
    434  1.1  msaitoh  *
    435  1.1  msaitoh  *   Valid settings are:
    436  1.1  msaitoh  *	- 0 will disable the watchdog
    437  1.1  msaitoh  *	- 1, 2, 3, 4, 8, 16, 32
    438  1.1  msaitoh  *	- anything else is invalid and will be ignored
    439  1.1  msaitoh  ************************************************************************/
    440  1.1  msaitoh static int
    441  1.1  msaitoh ixgbe_bp_wd_set(SYSCTLFN_ARGS)
    442  1.1  msaitoh {
    443  1.1  msaitoh 	struct sysctlnode node = *rnode;
    444  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    445  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    446  1.1  msaitoh 	int             error, tmp;
    447  1.1  msaitoh 	static int      timeout = 0;
    448  1.1  msaitoh 	u32             mask, arg = BYPASS_PAGE_CTL0;
    449  1.1  msaitoh 
    450  1.1  msaitoh 	/* Get the current hardware value */
    451  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    452  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &tmp);
    453  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    454  1.1  msaitoh 	if (error)
    455  1.1  msaitoh 		return (error);
    456  1.1  msaitoh 	/*
    457  1.1  msaitoh 	 * If armed keep the displayed value,
    458  1.1  msaitoh 	 * else change the display to zero.
    459  1.1  msaitoh 	 */
    460  1.1  msaitoh 	if ((tmp & (0x1 << BYPASS_WDT_ENABLE_SHIFT)) == 0)
    461  1.1  msaitoh 		timeout = 0;
    462  1.1  msaitoh 
    463  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    464  1.1  msaitoh 	if ((error) || (newp == NULL))
    465  1.1  msaitoh 		return (error);
    466  1.1  msaitoh 
    467  1.1  msaitoh 	mask = BYPASS_WDT_ENABLE_M;
    468  1.1  msaitoh 	switch (timeout) {
    469  1.1  msaitoh 		case 0: /* disables the timer */
    470  1.1  msaitoh 			break;
    471  1.1  msaitoh 		case 1:
    472  1.1  msaitoh 			arg = BYPASS_WDT_1_5 << BYPASS_WDT_TIME_SHIFT;
    473  1.1  msaitoh 			arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    474  1.1  msaitoh 			mask |= BYPASS_WDT_VALUE_M;
    475  1.1  msaitoh 			break;
    476  1.1  msaitoh 		case 2:
    477  1.1  msaitoh 			arg = BYPASS_WDT_2 << BYPASS_WDT_TIME_SHIFT;
    478  1.1  msaitoh 			arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    479  1.1  msaitoh 			mask |= BYPASS_WDT_VALUE_M;
    480  1.1  msaitoh 			break;
    481  1.1  msaitoh 		case 3:
    482  1.1  msaitoh 			arg = BYPASS_WDT_3 << BYPASS_WDT_TIME_SHIFT;
    483  1.1  msaitoh 			arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    484  1.1  msaitoh 			mask |= BYPASS_WDT_VALUE_M;
    485  1.1  msaitoh 			break;
    486  1.1  msaitoh 		case 4:
    487  1.1  msaitoh 			arg = BYPASS_WDT_4 << BYPASS_WDT_TIME_SHIFT;
    488  1.1  msaitoh 			arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    489  1.1  msaitoh 			mask |= BYPASS_WDT_VALUE_M;
    490  1.1  msaitoh 			break;
    491  1.1  msaitoh 		case 8:
    492  1.1  msaitoh 			arg = BYPASS_WDT_8 << BYPASS_WDT_TIME_SHIFT;
    493  1.1  msaitoh 			arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    494  1.1  msaitoh 			mask |= BYPASS_WDT_VALUE_M;
    495  1.1  msaitoh 			break;
    496  1.1  msaitoh 		case 16:
    497  1.1  msaitoh 			arg = BYPASS_WDT_16 << BYPASS_WDT_TIME_SHIFT;
    498  1.1  msaitoh 			arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    499  1.1  msaitoh 			mask |= BYPASS_WDT_VALUE_M;
    500  1.1  msaitoh 			break;
    501  1.1  msaitoh 		case 32:
    502  1.1  msaitoh 			arg = BYPASS_WDT_32 << BYPASS_WDT_TIME_SHIFT;
    503  1.1  msaitoh 			arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    504  1.1  msaitoh 			mask |= BYPASS_WDT_VALUE_M;
    505  1.1  msaitoh 			break;
    506  1.1  msaitoh 		default:
    507  1.1  msaitoh 			return (EINVAL);
    508  1.1  msaitoh 	}
    509  1.1  msaitoh 	/* Set the new watchdog */
    510  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    511  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, mask, arg);
    512  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    513  1.1  msaitoh 
    514  1.1  msaitoh 	return (error);
    515  1.1  msaitoh } /* ixgbe_bp_wd_set */
    516  1.1  msaitoh 
    517  1.1  msaitoh /************************************************************************
    518  1.1  msaitoh  * ixgbe_bp_wd_reset - Reset the Watchdog timer
    519  1.1  msaitoh  *
    520  1.1  msaitoh  *    To activate this it must be called with any argument.
    521  1.1  msaitoh  ************************************************************************/
    522  1.1  msaitoh static int
    523  1.1  msaitoh ixgbe_bp_wd_reset(SYSCTLFN_ARGS)
    524  1.1  msaitoh {
    525  1.1  msaitoh 	struct sysctlnode node = *rnode;
    526  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    527  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    528  1.1  msaitoh 	u32             sec, year;
    529  1.1  msaitoh 	int             cmd, count = 0, error = 0;
    530  1.1  msaitoh 	int             reset_wd = 0;
    531  1.1  msaitoh 
    532  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    533  1.1  msaitoh 	if ((error) || (newp == NULL))
    534  1.1  msaitoh 		return (error);
    535  1.1  msaitoh 
    536  1.1  msaitoh 	cmd = BYPASS_PAGE_CTL1 | BYPASS_WE | BYPASS_CTL1_WDT_PET;
    537  1.1  msaitoh 
    538  1.1  msaitoh 	/* Resync the FW time while writing to CTL1 anyway */
    539  1.1  msaitoh 	ixgbe_get_bypass_time(&year, &sec);
    540  1.1  msaitoh 
    541  1.1  msaitoh 	cmd |= (sec & BYPASS_CTL1_TIME_M) | BYPASS_CTL1_VALID;
    542  1.1  msaitoh 	cmd |= BYPASS_CTL1_OFFTRST;
    543  1.1  msaitoh 
    544  1.1  msaitoh 	ixgbe_bypass_wd_mutex_enter(adapter);
    545  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, cmd, &reset_wd);
    546  1.1  msaitoh 
    547  1.1  msaitoh 	/* Read until it matches what we wrote, or we time out */
    548  1.1  msaitoh 	do {
    549  1.1  msaitoh 		if (count++ > 10) {
    550  1.1  msaitoh 			error = IXGBE_BYPASS_FW_WRITE_FAILURE;
    551  1.1  msaitoh 			break;
    552  1.1  msaitoh 		}
    553  1.1  msaitoh 		if (hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL1, &reset_wd)) {
    554  1.1  msaitoh 			error = IXGBE_ERR_INVALID_ARGUMENT;
    555  1.1  msaitoh 			break;
    556  1.1  msaitoh 		}
    557  1.1  msaitoh 	} while (!hw->mac.ops.bypass_valid_rd(cmd, reset_wd));
    558  1.1  msaitoh 
    559  1.1  msaitoh 	reset_wd = 0;
    560  1.1  msaitoh 	ixgbe_bypass_wd_mutex_clear(adapter);
    561  1.1  msaitoh 	return (error);
    562  1.1  msaitoh } /* ixgbe_bp_wd_reset */
    563  1.1  msaitoh 
    564  1.1  msaitoh /************************************************************************
    565  1.1  msaitoh  * ixgbe_bp_log - Display the bypass log
    566  1.1  msaitoh  *
    567  1.1  msaitoh  *   You must pass a non-zero arg to sysctl
    568  1.1  msaitoh  ************************************************************************/
    569  1.1  msaitoh static int
    570  1.1  msaitoh ixgbe_bp_log(SYSCTLFN_ARGS)
    571  1.1  msaitoh {
    572  1.1  msaitoh 	struct sysctlnode          node = *rnode;
    573  1.1  msaitoh 	struct adapter           *adapter = (struct adapter *)node.sysctl_data;
    574  1.1  msaitoh 	struct ixgbe_hw            *hw = &adapter->hw;
    575  1.1  msaitoh 	u32                        cmd, base, head;
    576  1.1  msaitoh 	u32                        log_off, count = 0;
    577  1.1  msaitoh 	static int                 status = 0;
    578  1.1  msaitoh 	u8                         data;
    579  1.1  msaitoh 	struct ixgbe_bypass_eeprom eeprom[BYPASS_MAX_LOGS];
    580  1.1  msaitoh 	int                        i, error = 0;
    581  1.1  msaitoh 
    582  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    583  1.1  msaitoh 	if ((error) || (newp == NULL))
    584  1.1  msaitoh 		return (error);
    585  1.1  msaitoh 
    586  1.1  msaitoh 	/* Keep the log display single-threaded */
    587  1.1  msaitoh 	while (atomic_cas_uint(&adapter->bypass.log, 0, 1) == 0)
    588  1.1  msaitoh 		usec_delay(3000);
    589  1.1  msaitoh 
    590  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    591  1.1  msaitoh 
    592  1.1  msaitoh 	/* Find Current head of the log eeprom offset */
    593  1.1  msaitoh 	cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
    594  1.1  msaitoh 	cmd |= (0x1 << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
    595  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, cmd, &status);
    596  1.1  msaitoh 	if (error)
    597  1.1  msaitoh 		goto unlock_err;
    598  1.1  msaitoh 
    599  1.1  msaitoh 	/* wait for the write to stick */
    600  1.1  msaitoh 	msec_delay(100);
    601  1.1  msaitoh 
    602  1.1  msaitoh 	/* Now read the results */
    603  1.1  msaitoh 	cmd &= ~BYPASS_WE;
    604  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, cmd, &status);
    605  1.1  msaitoh 	if (error)
    606  1.1  msaitoh 		goto unlock_err;
    607  1.1  msaitoh 
    608  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    609  1.1  msaitoh 
    610  1.1  msaitoh 	base = status & BYPASS_CTL2_DATA_M;
    611  1.1  msaitoh 	head = (status & BYPASS_CTL2_HEAD_M) >> BYPASS_CTL2_HEAD_SHIFT;
    612  1.1  msaitoh 
    613  1.1  msaitoh 	/* address of the first log */
    614  1.1  msaitoh 	log_off = base + (head * 5);
    615  1.1  msaitoh 
    616  1.1  msaitoh 	/* extract all the log entries */
    617  1.1  msaitoh 	while (count < BYPASS_MAX_LOGS) {
    618  1.1  msaitoh 		eeprom[count].logs = 0;
    619  1.1  msaitoh 		eeprom[count].actions = 0;
    620  1.1  msaitoh 
    621  1.1  msaitoh 		/* Log 5 bytes store in on u32 and a u8 */
    622  1.1  msaitoh 		for (i = 0; i < 4; i++) {
    623  1.1  msaitoh 			ixgbe_bypass_mutex_enter(adapter);
    624  1.1  msaitoh 			error = hw->mac.ops.bypass_rd_eep(hw, log_off + i,
    625  1.1  msaitoh 			    &data);
    626  1.1  msaitoh 			ixgbe_bypass_mutex_clear(adapter);
    627  1.1  msaitoh 			if (error)
    628  1.1  msaitoh 				return (-EINVAL);
    629  1.1  msaitoh 			eeprom[count].logs += data << (8 * i);
    630  1.1  msaitoh 		}
    631  1.1  msaitoh 
    632  1.1  msaitoh 		ixgbe_bypass_mutex_enter(adapter);
    633  1.1  msaitoh 		error = hw->mac.ops.bypass_rd_eep(hw,
    634  1.1  msaitoh 		    log_off + i, &eeprom[count].actions);
    635  1.1  msaitoh 		ixgbe_bypass_mutex_clear(adapter);
    636  1.1  msaitoh 		if (error)
    637  1.1  msaitoh 			return (-EINVAL);
    638  1.1  msaitoh 
    639  1.1  msaitoh 		/* Quit if not a unread log */
    640  1.1  msaitoh 		if (!(eeprom[count].logs & BYPASS_LOG_CLEAR_M))
    641  1.1  msaitoh 			break;
    642  1.1  msaitoh 		/*
    643  1.1  msaitoh 		 * Log looks good so store the address where it's
    644  1.1  msaitoh 		 * Unread Log bit is so we can clear it after safely
    645  1.1  msaitoh 		 * pulling out all of the log data.
    646  1.1  msaitoh 		 */
    647  1.1  msaitoh 		eeprom[count].clear_off = log_off;
    648  1.1  msaitoh 
    649  1.1  msaitoh 		count++;
    650  1.1  msaitoh 		head = head ? head - 1 : BYPASS_MAX_LOGS;
    651  1.1  msaitoh 		log_off = base + (head * 5);
    652  1.1  msaitoh 	}
    653  1.1  msaitoh 
    654  1.1  msaitoh 	/* reverse order (oldest first) for output */
    655  1.1  msaitoh 	while (count--) {
    656  1.1  msaitoh 		int year;
    657  1.1  msaitoh 		u32 mon, days, hours, min, sec;
    658  1.1  msaitoh 		u32 time = eeprom[count].logs & BYPASS_LOG_TIME_M;
    659  1.1  msaitoh 		u32 event = (eeprom[count].logs & BYPASS_LOG_EVENT_M) >>
    660  1.1  msaitoh 		    BYPASS_LOG_EVENT_SHIFT;
    661  1.1  msaitoh 		u8 action =  eeprom[count].actions & BYPASS_LOG_ACTION_M;
    662  1.1  msaitoh 		u16 day_mon[2][13] = {
    663  1.1  msaitoh 		  {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
    664  1.1  msaitoh 		  {0, 31, 59, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
    665  1.1  msaitoh 		};
    666  1.1  msaitoh 		const char *event_str[] = {"unknown", "main on", "aux on",
    667  1.1  msaitoh 		    "main off", "aux off", "WDT", "user" };
    668  1.1  msaitoh 		const char *action_str[] = {"ignore", "normal", "bypass",
    669  1.1  msaitoh 					    "isolate",};
    670  1.1  msaitoh 
    671  1.1  msaitoh 		/* verify vaild data  1 - 6 */
    672  1.1  msaitoh 		if (event < BYPASS_EVENT_MAIN_ON || event > BYPASS_EVENT_USR)
    673  1.1  msaitoh 			event = 0;
    674  1.1  msaitoh 
    675  1.1  msaitoh 		/*
    676  1.1  msaitoh 		 * time is in sec's this year, so convert to something
    677  1.1  msaitoh 		 * printable.
    678  1.1  msaitoh 		 */
    679  1.1  msaitoh 		ixgbe_get_bypass_time(&year, &sec);
    680  1.1  msaitoh 		days = time / SEC_PER_DAY;
    681  1.1  msaitoh 		for (i = 11; days < day_mon[LEAP_YR(year)][i]; i--)
    682  1.1  msaitoh 			continue;
    683  1.1  msaitoh 		mon = i + 1;    /* display month as 1-12 */
    684  1.1  msaitoh 		time -= (day_mon[LEAP_YR(year)][i] * SEC_PER_DAY);
    685  1.1  msaitoh 		days = (time / SEC_PER_DAY) + 1;  /* first day is 1 */
    686  1.1  msaitoh 		time %= SEC_PER_DAY;
    687  1.1  msaitoh 		hours = time / (60 * 60);
    688  1.1  msaitoh 		time %= (60 * 60);
    689  1.1  msaitoh 		min = time / 60;
    690  1.1  msaitoh 		sec = time % 60;
    691  1.1  msaitoh 		device_printf(adapter->dev,
    692  1.1  msaitoh 		    "UT %02d/%02d %02d:%02d:%02d %8.8s -> %7.7s\n",
    693  1.1  msaitoh 		    mon, days, hours, min, sec, event_str[event],
    694  1.1  msaitoh 		    action_str[action]);
    695  1.1  msaitoh 		cmd = BYPASS_PAGE_CTL2 | BYPASS_WE | BYPASS_CTL2_RW;
    696  1.1  msaitoh 		cmd |= ((eeprom[count].clear_off + 3)
    697  1.1  msaitoh 		    << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
    698  1.1  msaitoh 		cmd |= ((eeprom[count].logs & ~BYPASS_LOG_CLEAR_M) >> 24);
    699  1.1  msaitoh 
    700  1.1  msaitoh 		ixgbe_bypass_mutex_enter(adapter);
    701  1.1  msaitoh 
    702  1.1  msaitoh 		error = hw->mac.ops.bypass_rw(hw, cmd, &status);
    703  1.1  msaitoh 
    704  1.1  msaitoh 		/* wait for the write to stick */
    705  1.1  msaitoh 		msec_delay(100);
    706  1.1  msaitoh 
    707  1.1  msaitoh 		ixgbe_bypass_mutex_clear(adapter);
    708  1.1  msaitoh 
    709  1.1  msaitoh 		if (error)
    710  1.1  msaitoh 			return (-EINVAL);
    711  1.1  msaitoh 	}
    712  1.1  msaitoh 
    713  1.1  msaitoh 	status = 0; /* reset */
    714  1.1  msaitoh 	/* Another log command can now run */
    715  1.1  msaitoh 	while (atomic_cas_uint(&adapter->bypass.log, 1, 0) == 0)
    716  1.1  msaitoh 		usec_delay(3000);
    717  1.1  msaitoh 	return(error);
    718  1.1  msaitoh 
    719  1.1  msaitoh unlock_err:
    720  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    721  1.1  msaitoh 	status = 0; /* reset */
    722  1.1  msaitoh 	while (atomic_cas_uint(&adapter->bypass.log, 1, 0) == 0)
    723  1.1  msaitoh 		usec_delay(3000);
    724  1.1  msaitoh 	return (-EINVAL);
    725  1.1  msaitoh } /* ixgbe_bp_log */
    726  1.1  msaitoh 
    727  1.1  msaitoh /************************************************************************
    728  1.1  msaitoh  * ixgbe_bypass_init - Set up infrastructure for the bypass feature
    729  1.1  msaitoh  *
    730  1.1  msaitoh  *   Do time and sysctl initialization here.  This feature is
    731  1.1  msaitoh  *   only enabled for the first port of a bypass adapter.
    732  1.1  msaitoh  ************************************************************************/
    733  1.1  msaitoh void
    734  1.1  msaitoh ixgbe_bypass_init(struct adapter *adapter)
    735  1.1  msaitoh {
    736  1.1  msaitoh 	struct ixgbe_hw        *hw = &adapter->hw;
    737  1.1  msaitoh 	device_t               dev = adapter->dev;
    738  1.1  msaitoh 	u32                    mask, value, sec, year;
    739  1.1  msaitoh 	struct                 sysctllog **log;
    740  1.1  msaitoh 	const struct sysctlnode *rnode, *cnode;
    741  1.1  msaitoh 
    742  1.1  msaitoh 	if (!(adapter->feat_cap & IXGBE_FEATURE_BYPASS))
    743  1.1  msaitoh 		return;
    744  1.1  msaitoh 
    745  1.1  msaitoh 	/* First set up time for the hardware */
    746  1.1  msaitoh 	ixgbe_get_bypass_time(&year, &sec);
    747  1.1  msaitoh 
    748  1.1  msaitoh 	mask = BYPASS_CTL1_TIME_M
    749  1.1  msaitoh 	     | BYPASS_CTL1_VALID_M
    750  1.1  msaitoh 	     | BYPASS_CTL1_OFFTRST_M;
    751  1.1  msaitoh 
    752  1.1  msaitoh 	value = (sec & BYPASS_CTL1_TIME_M)
    753  1.1  msaitoh 	      | BYPASS_CTL1_VALID
    754  1.1  msaitoh 	      | BYPASS_CTL1_OFFTRST;
    755  1.1  msaitoh 
    756  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    757  1.1  msaitoh 	hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL1, mask, value);
    758  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    759  1.1  msaitoh 
    760  1.1  msaitoh 	/* Now set up the SYSCTL infrastructure */
    761  1.1  msaitoh 	log = &adapter->sysctllog;
    762  1.1  msaitoh 	if ((rnode = adapter->sysctltop) == NULL) {
    763  1.1  msaitoh 		aprint_error_dev(dev, "could not create sysctl root\n");
    764  1.1  msaitoh 		return;
    765  1.1  msaitoh 	}
    766  1.1  msaitoh 
    767  1.1  msaitoh 	/*
    768  1.1  msaitoh 	 * The log routine is kept separate from the other
    769  1.1  msaitoh 	 * children so a general display command like:
    770  1.1  msaitoh 	 * `sysctl dev.ix.0.bypass` will not show the log.
    771  1.1  msaitoh 	 */
    772  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    773  1.1  msaitoh 	    CTLTYPE_INT, "bypass_log", SYSCTL_DESCR("Bypass Log"),
    774  1.1  msaitoh 	    ixgbe_bp_log, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    775  1.1  msaitoh 
    776  1.1  msaitoh 	/* All other setting are hung from the 'bypass' node */
    777  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &rnode, 0,
    778  1.1  msaitoh 	    CTLTYPE_NODE, "bypass", SYSCTL_DESCR("Bypass"),
    779  1.1  msaitoh 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
    780  1.1  msaitoh 
    781  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READONLY,
    782  1.1  msaitoh 	    CTLTYPE_INT, "version", SYSCTL_DESCR("Bypass Version"),
    783  1.1  msaitoh 	    ixgbe_bp_version, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    784  1.1  msaitoh 
    785  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    786  1.1  msaitoh 	    CTLTYPE_INT, "state", SYSCTL_DESCR("Bypass State"),
    787  1.1  msaitoh 	    ixgbe_bp_set_state, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    788  1.1  msaitoh 
    789  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    790  1.1  msaitoh 	    CTLTYPE_INT, "timeout", SYSCTL_DESCR("Bypass Timeout"),
    791  1.1  msaitoh 	    ixgbe_bp_timeout, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    792  1.1  msaitoh 
    793  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    794  1.1  msaitoh 	    CTLTYPE_INT, "main_on", SYSCTL_DESCR("Bypass Main On"),
    795  1.1  msaitoh 	    ixgbe_bp_main_on, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    796  1.1  msaitoh 
    797  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    798  1.1  msaitoh 	    CTLTYPE_INT, "main_off", SYSCTL_DESCR("Bypass Main Off"),
    799  1.1  msaitoh 	    ixgbe_bp_main_off, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    800  1.1  msaitoh 
    801  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    802  1.1  msaitoh 	    CTLTYPE_INT, "aux_on", SYSCTL_DESCR("Bypass Aux On"),
    803  1.1  msaitoh 	    ixgbe_bp_aux_on, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    804  1.1  msaitoh 
    805  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    806  1.1  msaitoh 	    CTLTYPE_INT, "aux_off", SYSCTL_DESCR("Bypass Aux Off"),
    807  1.1  msaitoh 	    ixgbe_bp_aux_off, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    808  1.1  msaitoh 
    809  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    810  1.1  msaitoh 	    CTLTYPE_INT, "wd_set", SYSCTL_DESCR("Set BP Watchdog"),
    811  1.1  msaitoh 	    ixgbe_bp_wd_set, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    812  1.1  msaitoh 
    813  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    814  1.1  msaitoh 	    CTLTYPE_INT, "wd_reset", SYSCTL_DESCR("Bypass WD Reset"),
    815  1.1  msaitoh 	    ixgbe_bp_wd_reset, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    816  1.1  msaitoh 
    817  1.1  msaitoh 	adapter->feat_en |= IXGBE_FEATURE_BYPASS;
    818  1.1  msaitoh 
    819  1.1  msaitoh 	return;
    820  1.1  msaitoh } /* ixgbe_bypass_init */
    821  1.1  msaitoh 
    822