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