Home | History | Annotate | Line # | Download | only in ixgbe
if_bypass.c revision 1.3
      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.2  msaitoh 	node.sysctl_data = &featversion;
    138  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    139  1.1  msaitoh 	return (error);
    140  1.1  msaitoh err:
    141  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    142  1.1  msaitoh 	return (error);
    143  1.1  msaitoh 
    144  1.1  msaitoh } /* ixgbe_bp_version */
    145  1.1  msaitoh 
    146  1.1  msaitoh /************************************************************************
    147  1.1  msaitoh  * ixgbe_bp_set_state
    148  1.1  msaitoh  *
    149  1.1  msaitoh  *   Show/Set the Bypass State:
    150  1.1  msaitoh  *	1 = NORMAL
    151  1.1  msaitoh  *	2 = BYPASS
    152  1.1  msaitoh  *	3 = ISOLATE
    153  1.1  msaitoh  *
    154  1.1  msaitoh  *	With no argument the state is displayed,
    155  1.1  msaitoh  *	passing a value will set it.
    156  1.1  msaitoh  ************************************************************************/
    157  1.1  msaitoh static int
    158  1.1  msaitoh ixgbe_bp_set_state(SYSCTLFN_ARGS)
    159  1.1  msaitoh {
    160  1.1  msaitoh 	struct sysctlnode node = *rnode;
    161  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    162  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    163  1.1  msaitoh 	int             error = 0;
    164  1.1  msaitoh 	static int      state = 0;
    165  1.1  msaitoh 
    166  1.1  msaitoh 	/* Get the current state */
    167  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    168  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw,
    169  1.1  msaitoh 	    BYPASS_PAGE_CTL0, &state);
    170  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    171  1.1  msaitoh 	if (error)
    172  1.1  msaitoh 		return (error);
    173  1.1  msaitoh 	state = (state >> BYPASS_STATUS_OFF_SHIFT) & 0x3;
    174  1.1  msaitoh 
    175  1.2  msaitoh 	node.sysctl_data = &state;
    176  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    177  1.1  msaitoh 	if ((error) || (newp == NULL))
    178  1.1  msaitoh 		return (error);
    179  1.1  msaitoh 
    180  1.1  msaitoh 	/* Sanity check new state */
    181  1.1  msaitoh 	switch (state) {
    182  1.1  msaitoh 	case BYPASS_NORM:
    183  1.1  msaitoh 	case BYPASS_BYPASS:
    184  1.1  msaitoh 	case BYPASS_ISOLATE:
    185  1.1  msaitoh 		break;
    186  1.1  msaitoh 	default:
    187  1.1  msaitoh 		return (EINVAL);
    188  1.1  msaitoh 	}
    189  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    190  1.1  msaitoh 	if ((error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    191  1.1  msaitoh 	    BYPASS_MODE_OFF_M, state) != 0))
    192  1.1  msaitoh 		goto out;
    193  1.1  msaitoh 	/* Set AUTO back on so FW can receive events */
    194  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    195  1.1  msaitoh 	    BYPASS_MODE_OFF_M, BYPASS_AUTO);
    196  1.1  msaitoh out:
    197  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    198  1.1  msaitoh 	usec_delay(6000);
    199  1.1  msaitoh 	return (error);
    200  1.1  msaitoh } /* ixgbe_bp_set_state */
    201  1.1  msaitoh 
    202  1.1  msaitoh /************************************************************************
    203  1.1  msaitoh  * The following routines control the operational
    204  1.1  msaitoh  * "rules" of the feature, what behavior will occur
    205  1.1  msaitoh  * when particular events occur.
    206  1.1  msaitoh  * 	Values are:
    207  1.1  msaitoh  *		0 - no change for the event (NOP)
    208  1.1  msaitoh  *		1 - go to Normal operation
    209  1.1  msaitoh  *		2 - go to Bypass operation
    210  1.1  msaitoh  *		3 - go to Isolate operation
    211  1.1  msaitoh  * Calling the entry with no argument just displays
    212  1.1  msaitoh  * the current rule setting.
    213  1.1  msaitoh  ************************************************************************/
    214  1.1  msaitoh 
    215  1.1  msaitoh /************************************************************************
    216  1.1  msaitoh  * ixgbe_bp_timeout
    217  1.1  msaitoh  *
    218  1.1  msaitoh  * This is to set the Rule for the watchdog,
    219  1.1  msaitoh  * not the actual watchdog timeout value.
    220  1.1  msaitoh  ************************************************************************/
    221  1.1  msaitoh static int
    222  1.1  msaitoh ixgbe_bp_timeout(SYSCTLFN_ARGS)
    223  1.1  msaitoh {
    224  1.1  msaitoh 	struct sysctlnode node = *rnode;
    225  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    226  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    227  1.1  msaitoh 	int             error = 0;
    228  1.1  msaitoh 	static int      timeout = 0;
    229  1.1  msaitoh 
    230  1.1  msaitoh 	/* Get the current value */
    231  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    232  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &timeout);
    233  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    234  1.1  msaitoh 	if (error)
    235  1.1  msaitoh 		return (error);
    236  1.1  msaitoh 	timeout = (timeout >> BYPASS_WDTIMEOUT_SHIFT) & 0x3;
    237  1.1  msaitoh 
    238  1.2  msaitoh 	node.sysctl_data = &timeout;
    239  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    240  1.1  msaitoh 	if ((error) || (newp == NULL))
    241  1.1  msaitoh 		return (error);
    242  1.1  msaitoh 
    243  1.1  msaitoh 	/* Sanity check on the setting */
    244  1.1  msaitoh 	switch (timeout) {
    245  1.1  msaitoh 	case BYPASS_NOP:
    246  1.1  msaitoh 	case BYPASS_NORM:
    247  1.1  msaitoh 	case BYPASS_BYPASS:
    248  1.1  msaitoh 	case BYPASS_ISOLATE:
    249  1.1  msaitoh 		break;
    250  1.1  msaitoh 	default:
    251  1.1  msaitoh 		return (EINVAL);
    252  1.1  msaitoh 	}
    253  1.1  msaitoh 
    254  1.1  msaitoh 	/* Set the new state */
    255  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    256  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    257  1.1  msaitoh 	    BYPASS_WDTIMEOUT_M, timeout << BYPASS_WDTIMEOUT_SHIFT);
    258  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    259  1.1  msaitoh 	usec_delay(6000);
    260  1.1  msaitoh 	return (error);
    261  1.1  msaitoh } /* ixgbe_bp_timeout */
    262  1.1  msaitoh 
    263  1.1  msaitoh /************************************************************************
    264  1.1  msaitoh  * ixgbe_bp_main_on
    265  1.1  msaitoh  ************************************************************************/
    266  1.1  msaitoh static int
    267  1.1  msaitoh ixgbe_bp_main_on(SYSCTLFN_ARGS)
    268  1.1  msaitoh {
    269  1.1  msaitoh 	struct sysctlnode node = *rnode;
    270  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    271  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    272  1.1  msaitoh 	int             error = 0;
    273  1.1  msaitoh 	static int      main_on = 0;
    274  1.1  msaitoh 
    275  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    276  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_on);
    277  1.1  msaitoh 	main_on = (main_on >> BYPASS_MAIN_ON_SHIFT) & 0x3;
    278  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    279  1.1  msaitoh 	if (error)
    280  1.1  msaitoh 		return (error);
    281  1.1  msaitoh 
    282  1.2  msaitoh 	node.sysctl_data = &main_on;
    283  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    284  1.1  msaitoh 	if ((error) || (newp == NULL))
    285  1.1  msaitoh 		return (error);
    286  1.1  msaitoh 
    287  1.1  msaitoh 	/* Sanity check on the setting */
    288  1.1  msaitoh 	switch (main_on) {
    289  1.1  msaitoh 	case BYPASS_NOP:
    290  1.1  msaitoh 	case BYPASS_NORM:
    291  1.1  msaitoh 	case BYPASS_BYPASS:
    292  1.1  msaitoh 	case BYPASS_ISOLATE:
    293  1.1  msaitoh 		break;
    294  1.1  msaitoh 	default:
    295  1.1  msaitoh 		return (EINVAL);
    296  1.1  msaitoh 	}
    297  1.1  msaitoh 
    298  1.1  msaitoh 	/* Set the new state */
    299  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    300  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    301  1.1  msaitoh 	    BYPASS_MAIN_ON_M, main_on << BYPASS_MAIN_ON_SHIFT);
    302  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    303  1.1  msaitoh 	usec_delay(6000);
    304  1.1  msaitoh 	return (error);
    305  1.1  msaitoh } /* ixgbe_bp_main_on */
    306  1.1  msaitoh 
    307  1.1  msaitoh /************************************************************************
    308  1.1  msaitoh  * ixgbe_bp_main_off
    309  1.1  msaitoh  ************************************************************************/
    310  1.1  msaitoh static int
    311  1.1  msaitoh ixgbe_bp_main_off(SYSCTLFN_ARGS)
    312  1.1  msaitoh {
    313  1.1  msaitoh 	struct sysctlnode node = *rnode;
    314  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    315  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    316  1.1  msaitoh 	int             error = 0;
    317  1.1  msaitoh 	static int      main_off = 0;
    318  1.1  msaitoh 
    319  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    320  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_off);
    321  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    322  1.1  msaitoh 	if (error)
    323  1.1  msaitoh 		return (error);
    324  1.1  msaitoh 	main_off = (main_off >> BYPASS_MAIN_OFF_SHIFT) & 0x3;
    325  1.1  msaitoh 
    326  1.2  msaitoh 	node.sysctl_data = &main_off;
    327  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    328  1.1  msaitoh 	if ((error) || (newp == NULL))
    329  1.1  msaitoh 		return (error);
    330  1.1  msaitoh 
    331  1.1  msaitoh 	/* Sanity check on the setting */
    332  1.1  msaitoh 	switch (main_off) {
    333  1.1  msaitoh 	case BYPASS_NOP:
    334  1.1  msaitoh 	case BYPASS_NORM:
    335  1.1  msaitoh 	case BYPASS_BYPASS:
    336  1.1  msaitoh 	case BYPASS_ISOLATE:
    337  1.1  msaitoh 		break;
    338  1.1  msaitoh 	default:
    339  1.1  msaitoh 		return (EINVAL);
    340  1.1  msaitoh 	}
    341  1.1  msaitoh 
    342  1.1  msaitoh 	/* Set the new state */
    343  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    344  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    345  1.1  msaitoh 	    BYPASS_MAIN_OFF_M, main_off << BYPASS_MAIN_OFF_SHIFT);
    346  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    347  1.1  msaitoh 	usec_delay(6000);
    348  1.1  msaitoh 	return (error);
    349  1.1  msaitoh } /* ixgbe_bp_main_off */
    350  1.1  msaitoh 
    351  1.1  msaitoh /************************************************************************
    352  1.1  msaitoh  * ixgbe_bp_aux_on
    353  1.1  msaitoh  ************************************************************************/
    354  1.1  msaitoh static int
    355  1.1  msaitoh ixgbe_bp_aux_on(SYSCTLFN_ARGS)
    356  1.1  msaitoh {
    357  1.1  msaitoh 	struct sysctlnode node = *rnode;
    358  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    359  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    360  1.1  msaitoh 	int             error = 0;
    361  1.1  msaitoh 	static int      aux_on = 0;
    362  1.1  msaitoh 
    363  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    364  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_on);
    365  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    366  1.1  msaitoh 	if (error)
    367  1.1  msaitoh 		return (error);
    368  1.1  msaitoh 	aux_on = (aux_on >> BYPASS_AUX_ON_SHIFT) & 0x3;
    369  1.1  msaitoh 
    370  1.2  msaitoh 	node.sysctl_data = &aux_on;
    371  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    372  1.1  msaitoh 	if ((error) || (newp == NULL))
    373  1.1  msaitoh 		return (error);
    374  1.1  msaitoh 
    375  1.1  msaitoh 	/* Sanity check on the setting */
    376  1.1  msaitoh 	switch (aux_on) {
    377  1.1  msaitoh 	case BYPASS_NOP:
    378  1.1  msaitoh 	case BYPASS_NORM:
    379  1.1  msaitoh 	case BYPASS_BYPASS:
    380  1.1  msaitoh 	case BYPASS_ISOLATE:
    381  1.1  msaitoh 		break;
    382  1.1  msaitoh 	default:
    383  1.1  msaitoh 		return (EINVAL);
    384  1.1  msaitoh 	}
    385  1.1  msaitoh 
    386  1.1  msaitoh 	/* Set the new state */
    387  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    388  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    389  1.1  msaitoh 	    BYPASS_AUX_ON_M, aux_on << BYPASS_AUX_ON_SHIFT);
    390  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    391  1.1  msaitoh 	usec_delay(6000);
    392  1.1  msaitoh 	return (error);
    393  1.1  msaitoh } /* ixgbe_bp_aux_on */
    394  1.1  msaitoh 
    395  1.1  msaitoh /************************************************************************
    396  1.1  msaitoh  * ixgbe_bp_aux_off
    397  1.1  msaitoh  ************************************************************************/
    398  1.1  msaitoh static int
    399  1.1  msaitoh ixgbe_bp_aux_off(SYSCTLFN_ARGS)
    400  1.1  msaitoh {
    401  1.1  msaitoh 	struct sysctlnode node = *rnode;
    402  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    403  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    404  1.1  msaitoh 	int             error = 0;
    405  1.1  msaitoh 	static int      aux_off = 0;
    406  1.1  msaitoh 
    407  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    408  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_off);
    409  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    410  1.1  msaitoh 	if (error)
    411  1.1  msaitoh 		return (error);
    412  1.1  msaitoh 	aux_off = (aux_off >> BYPASS_AUX_OFF_SHIFT) & 0x3;
    413  1.1  msaitoh 
    414  1.2  msaitoh 	node.sysctl_data = &aux_off;
    415  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    416  1.1  msaitoh 	if ((error) || (newp == NULL))
    417  1.1  msaitoh 		return (error);
    418  1.1  msaitoh 
    419  1.1  msaitoh 	/* Sanity check on the setting */
    420  1.1  msaitoh 	switch (aux_off) {
    421  1.1  msaitoh 	case BYPASS_NOP:
    422  1.1  msaitoh 	case BYPASS_NORM:
    423  1.1  msaitoh 	case BYPASS_BYPASS:
    424  1.1  msaitoh 	case BYPASS_ISOLATE:
    425  1.1  msaitoh 		break;
    426  1.1  msaitoh 	default:
    427  1.1  msaitoh 		return (EINVAL);
    428  1.1  msaitoh 	}
    429  1.1  msaitoh 
    430  1.1  msaitoh 	/* Set the new state */
    431  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    432  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
    433  1.1  msaitoh 	    BYPASS_AUX_OFF_M, aux_off << BYPASS_AUX_OFF_SHIFT);
    434  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    435  1.1  msaitoh 	usec_delay(6000);
    436  1.1  msaitoh 	return (error);
    437  1.1  msaitoh } /* ixgbe_bp_aux_off */
    438  1.1  msaitoh 
    439  1.1  msaitoh /************************************************************************
    440  1.1  msaitoh  * ixgbe_bp_wd_set - Set the Watchdog timer value
    441  1.1  msaitoh  *
    442  1.1  msaitoh  *   Valid settings are:
    443  1.1  msaitoh  *	- 0 will disable the watchdog
    444  1.1  msaitoh  *	- 1, 2, 3, 4, 8, 16, 32
    445  1.1  msaitoh  *	- anything else is invalid and will be ignored
    446  1.1  msaitoh  ************************************************************************/
    447  1.1  msaitoh static int
    448  1.1  msaitoh ixgbe_bp_wd_set(SYSCTLFN_ARGS)
    449  1.1  msaitoh {
    450  1.1  msaitoh 	struct sysctlnode node = *rnode;
    451  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    452  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    453  1.1  msaitoh 	int             error, tmp;
    454  1.1  msaitoh 	static int      timeout = 0;
    455  1.1  msaitoh 	u32             mask, arg = BYPASS_PAGE_CTL0;
    456  1.1  msaitoh 
    457  1.1  msaitoh 	/* Get the current hardware value */
    458  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    459  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &tmp);
    460  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    461  1.1  msaitoh 	if (error)
    462  1.1  msaitoh 		return (error);
    463  1.1  msaitoh 	/*
    464  1.1  msaitoh 	 * If armed keep the displayed value,
    465  1.1  msaitoh 	 * else change the display to zero.
    466  1.1  msaitoh 	 */
    467  1.1  msaitoh 	if ((tmp & (0x1 << BYPASS_WDT_ENABLE_SHIFT)) == 0)
    468  1.1  msaitoh 		timeout = 0;
    469  1.1  msaitoh 
    470  1.2  msaitoh 	node.sysctl_data = &timeout;
    471  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    472  1.1  msaitoh 	if ((error) || (newp == NULL))
    473  1.1  msaitoh 		return (error);
    474  1.1  msaitoh 
    475  1.1  msaitoh 	mask = BYPASS_WDT_ENABLE_M;
    476  1.1  msaitoh 	switch (timeout) {
    477  1.3  msaitoh 	case 0: /* disables the timer */
    478  1.3  msaitoh 		break;
    479  1.3  msaitoh 	case 1:
    480  1.3  msaitoh 		arg = BYPASS_WDT_1_5 << BYPASS_WDT_TIME_SHIFT;
    481  1.3  msaitoh 		arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    482  1.3  msaitoh 		mask |= BYPASS_WDT_VALUE_M;
    483  1.3  msaitoh 		break;
    484  1.3  msaitoh 	case 2:
    485  1.3  msaitoh 		arg = BYPASS_WDT_2 << BYPASS_WDT_TIME_SHIFT;
    486  1.3  msaitoh 		arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    487  1.3  msaitoh 		mask |= BYPASS_WDT_VALUE_M;
    488  1.3  msaitoh 		break;
    489  1.3  msaitoh 	case 3:
    490  1.3  msaitoh 		arg = BYPASS_WDT_3 << BYPASS_WDT_TIME_SHIFT;
    491  1.3  msaitoh 		arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    492  1.3  msaitoh 		mask |= BYPASS_WDT_VALUE_M;
    493  1.3  msaitoh 		break;
    494  1.3  msaitoh 	case 4:
    495  1.3  msaitoh 		arg = BYPASS_WDT_4 << BYPASS_WDT_TIME_SHIFT;
    496  1.3  msaitoh 		arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    497  1.3  msaitoh 		mask |= BYPASS_WDT_VALUE_M;
    498  1.3  msaitoh 		break;
    499  1.3  msaitoh 	case 8:
    500  1.3  msaitoh 		arg = BYPASS_WDT_8 << BYPASS_WDT_TIME_SHIFT;
    501  1.3  msaitoh 		arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    502  1.3  msaitoh 		mask |= BYPASS_WDT_VALUE_M;
    503  1.3  msaitoh 		break;
    504  1.3  msaitoh 	case 16:
    505  1.3  msaitoh 		arg = BYPASS_WDT_16 << BYPASS_WDT_TIME_SHIFT;
    506  1.3  msaitoh 		arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    507  1.3  msaitoh 		mask |= BYPASS_WDT_VALUE_M;
    508  1.3  msaitoh 		break;
    509  1.3  msaitoh 	case 32:
    510  1.3  msaitoh 		arg = BYPASS_WDT_32 << BYPASS_WDT_TIME_SHIFT;
    511  1.3  msaitoh 		arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
    512  1.3  msaitoh 		mask |= BYPASS_WDT_VALUE_M;
    513  1.3  msaitoh 		break;
    514  1.3  msaitoh 	default:
    515  1.3  msaitoh 		return (EINVAL);
    516  1.1  msaitoh 	}
    517  1.1  msaitoh 	/* Set the new watchdog */
    518  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    519  1.1  msaitoh 	error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, mask, arg);
    520  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    521  1.1  msaitoh 
    522  1.1  msaitoh 	return (error);
    523  1.1  msaitoh } /* ixgbe_bp_wd_set */
    524  1.1  msaitoh 
    525  1.1  msaitoh /************************************************************************
    526  1.1  msaitoh  * ixgbe_bp_wd_reset - Reset the Watchdog timer
    527  1.1  msaitoh  *
    528  1.1  msaitoh  *    To activate this it must be called with any argument.
    529  1.1  msaitoh  ************************************************************************/
    530  1.1  msaitoh static int
    531  1.1  msaitoh ixgbe_bp_wd_reset(SYSCTLFN_ARGS)
    532  1.1  msaitoh {
    533  1.1  msaitoh 	struct sysctlnode node = *rnode;
    534  1.1  msaitoh 	struct adapter  *adapter = (struct adapter *)node.sysctl_data;
    535  1.1  msaitoh 	struct ixgbe_hw *hw = &adapter->hw;
    536  1.1  msaitoh 	u32             sec, year;
    537  1.1  msaitoh 	int             cmd, count = 0, error = 0;
    538  1.1  msaitoh 	int             reset_wd = 0;
    539  1.1  msaitoh 
    540  1.2  msaitoh 	node.sysctl_data = &reset_wd;
    541  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    542  1.1  msaitoh 	if ((error) || (newp == NULL))
    543  1.1  msaitoh 		return (error);
    544  1.1  msaitoh 
    545  1.1  msaitoh 	cmd = BYPASS_PAGE_CTL1 | BYPASS_WE | BYPASS_CTL1_WDT_PET;
    546  1.1  msaitoh 
    547  1.1  msaitoh 	/* Resync the FW time while writing to CTL1 anyway */
    548  1.1  msaitoh 	ixgbe_get_bypass_time(&year, &sec);
    549  1.1  msaitoh 
    550  1.1  msaitoh 	cmd |= (sec & BYPASS_CTL1_TIME_M) | BYPASS_CTL1_VALID;
    551  1.1  msaitoh 	cmd |= BYPASS_CTL1_OFFTRST;
    552  1.1  msaitoh 
    553  1.1  msaitoh 	ixgbe_bypass_wd_mutex_enter(adapter);
    554  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, cmd, &reset_wd);
    555  1.1  msaitoh 
    556  1.1  msaitoh 	/* Read until it matches what we wrote, or we time out */
    557  1.1  msaitoh 	do {
    558  1.1  msaitoh 		if (count++ > 10) {
    559  1.1  msaitoh 			error = IXGBE_BYPASS_FW_WRITE_FAILURE;
    560  1.1  msaitoh 			break;
    561  1.1  msaitoh 		}
    562  1.1  msaitoh 		if (hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL1, &reset_wd)) {
    563  1.1  msaitoh 			error = IXGBE_ERR_INVALID_ARGUMENT;
    564  1.1  msaitoh 			break;
    565  1.1  msaitoh 		}
    566  1.1  msaitoh 	} while (!hw->mac.ops.bypass_valid_rd(cmd, reset_wd));
    567  1.1  msaitoh 
    568  1.1  msaitoh 	reset_wd = 0;
    569  1.1  msaitoh 	ixgbe_bypass_wd_mutex_clear(adapter);
    570  1.1  msaitoh 	return (error);
    571  1.1  msaitoh } /* ixgbe_bp_wd_reset */
    572  1.1  msaitoh 
    573  1.1  msaitoh /************************************************************************
    574  1.1  msaitoh  * ixgbe_bp_log - Display the bypass log
    575  1.1  msaitoh  *
    576  1.1  msaitoh  *   You must pass a non-zero arg to sysctl
    577  1.1  msaitoh  ************************************************************************/
    578  1.1  msaitoh static int
    579  1.1  msaitoh ixgbe_bp_log(SYSCTLFN_ARGS)
    580  1.1  msaitoh {
    581  1.1  msaitoh 	struct sysctlnode          node = *rnode;
    582  1.1  msaitoh 	struct adapter           *adapter = (struct adapter *)node.sysctl_data;
    583  1.1  msaitoh 	struct ixgbe_hw            *hw = &adapter->hw;
    584  1.1  msaitoh 	u32                        cmd, base, head;
    585  1.1  msaitoh 	u32                        log_off, count = 0;
    586  1.1  msaitoh 	static int                 status = 0;
    587  1.1  msaitoh 	u8                         data;
    588  1.1  msaitoh 	struct ixgbe_bypass_eeprom eeprom[BYPASS_MAX_LOGS];
    589  1.1  msaitoh 	int                        i, error = 0;
    590  1.1  msaitoh 
    591  1.2  msaitoh 	node.sysctl_data = &status;
    592  1.1  msaitoh 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    593  1.1  msaitoh 	if ((error) || (newp == NULL))
    594  1.1  msaitoh 		return (error);
    595  1.1  msaitoh 
    596  1.1  msaitoh 	/* Keep the log display single-threaded */
    597  1.1  msaitoh 	while (atomic_cas_uint(&adapter->bypass.log, 0, 1) == 0)
    598  1.1  msaitoh 		usec_delay(3000);
    599  1.1  msaitoh 
    600  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    601  1.1  msaitoh 
    602  1.1  msaitoh 	/* Find Current head of the log eeprom offset */
    603  1.1  msaitoh 	cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
    604  1.1  msaitoh 	cmd |= (0x1 << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
    605  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, cmd, &status);
    606  1.1  msaitoh 	if (error)
    607  1.1  msaitoh 		goto unlock_err;
    608  1.1  msaitoh 
    609  1.1  msaitoh 	/* wait for the write to stick */
    610  1.1  msaitoh 	msec_delay(100);
    611  1.1  msaitoh 
    612  1.1  msaitoh 	/* Now read the results */
    613  1.1  msaitoh 	cmd &= ~BYPASS_WE;
    614  1.1  msaitoh 	error = hw->mac.ops.bypass_rw(hw, cmd, &status);
    615  1.1  msaitoh 	if (error)
    616  1.1  msaitoh 		goto unlock_err;
    617  1.1  msaitoh 
    618  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    619  1.1  msaitoh 
    620  1.1  msaitoh 	base = status & BYPASS_CTL2_DATA_M;
    621  1.1  msaitoh 	head = (status & BYPASS_CTL2_HEAD_M) >> BYPASS_CTL2_HEAD_SHIFT;
    622  1.1  msaitoh 
    623  1.1  msaitoh 	/* address of the first log */
    624  1.1  msaitoh 	log_off = base + (head * 5);
    625  1.1  msaitoh 
    626  1.1  msaitoh 	/* extract all the log entries */
    627  1.1  msaitoh 	while (count < BYPASS_MAX_LOGS) {
    628  1.1  msaitoh 		eeprom[count].logs = 0;
    629  1.1  msaitoh 		eeprom[count].actions = 0;
    630  1.1  msaitoh 
    631  1.1  msaitoh 		/* Log 5 bytes store in on u32 and a u8 */
    632  1.1  msaitoh 		for (i = 0; i < 4; i++) {
    633  1.1  msaitoh 			ixgbe_bypass_mutex_enter(adapter);
    634  1.1  msaitoh 			error = hw->mac.ops.bypass_rd_eep(hw, log_off + i,
    635  1.1  msaitoh 			    &data);
    636  1.1  msaitoh 			ixgbe_bypass_mutex_clear(adapter);
    637  1.1  msaitoh 			if (error)
    638  1.3  msaitoh 				return (EINVAL);
    639  1.1  msaitoh 			eeprom[count].logs += data << (8 * i);
    640  1.1  msaitoh 		}
    641  1.1  msaitoh 
    642  1.1  msaitoh 		ixgbe_bypass_mutex_enter(adapter);
    643  1.1  msaitoh 		error = hw->mac.ops.bypass_rd_eep(hw,
    644  1.1  msaitoh 		    log_off + i, &eeprom[count].actions);
    645  1.1  msaitoh 		ixgbe_bypass_mutex_clear(adapter);
    646  1.1  msaitoh 		if (error)
    647  1.3  msaitoh 			return (EINVAL);
    648  1.1  msaitoh 
    649  1.1  msaitoh 		/* Quit if not a unread log */
    650  1.1  msaitoh 		if (!(eeprom[count].logs & BYPASS_LOG_CLEAR_M))
    651  1.1  msaitoh 			break;
    652  1.1  msaitoh 		/*
    653  1.1  msaitoh 		 * Log looks good so store the address where it's
    654  1.1  msaitoh 		 * Unread Log bit is so we can clear it after safely
    655  1.1  msaitoh 		 * pulling out all of the log data.
    656  1.1  msaitoh 		 */
    657  1.1  msaitoh 		eeprom[count].clear_off = log_off;
    658  1.1  msaitoh 
    659  1.1  msaitoh 		count++;
    660  1.1  msaitoh 		head = head ? head - 1 : BYPASS_MAX_LOGS;
    661  1.1  msaitoh 		log_off = base + (head * 5);
    662  1.1  msaitoh 	}
    663  1.1  msaitoh 
    664  1.1  msaitoh 	/* reverse order (oldest first) for output */
    665  1.1  msaitoh 	while (count--) {
    666  1.1  msaitoh 		int year;
    667  1.1  msaitoh 		u32 mon, days, hours, min, sec;
    668  1.1  msaitoh 		u32 time = eeprom[count].logs & BYPASS_LOG_TIME_M;
    669  1.1  msaitoh 		u32 event = (eeprom[count].logs & BYPASS_LOG_EVENT_M) >>
    670  1.1  msaitoh 		    BYPASS_LOG_EVENT_SHIFT;
    671  1.1  msaitoh 		u8 action =  eeprom[count].actions & BYPASS_LOG_ACTION_M;
    672  1.1  msaitoh 		u16 day_mon[2][13] = {
    673  1.1  msaitoh 		  {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
    674  1.1  msaitoh 		  {0, 31, 59, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
    675  1.1  msaitoh 		};
    676  1.1  msaitoh 		const char *event_str[] = {"unknown", "main on", "aux on",
    677  1.1  msaitoh 		    "main off", "aux off", "WDT", "user" };
    678  1.1  msaitoh 		const char *action_str[] = {"ignore", "normal", "bypass",
    679  1.1  msaitoh 					    "isolate",};
    680  1.1  msaitoh 
    681  1.1  msaitoh 		/* verify vaild data  1 - 6 */
    682  1.1  msaitoh 		if (event < BYPASS_EVENT_MAIN_ON || event > BYPASS_EVENT_USR)
    683  1.1  msaitoh 			event = 0;
    684  1.1  msaitoh 
    685  1.1  msaitoh 		/*
    686  1.1  msaitoh 		 * time is in sec's this year, so convert to something
    687  1.1  msaitoh 		 * printable.
    688  1.1  msaitoh 		 */
    689  1.1  msaitoh 		ixgbe_get_bypass_time(&year, &sec);
    690  1.1  msaitoh 		days = time / SEC_PER_DAY;
    691  1.1  msaitoh 		for (i = 11; days < day_mon[LEAP_YR(year)][i]; i--)
    692  1.1  msaitoh 			continue;
    693  1.1  msaitoh 		mon = i + 1;    /* display month as 1-12 */
    694  1.1  msaitoh 		time -= (day_mon[LEAP_YR(year)][i] * SEC_PER_DAY);
    695  1.1  msaitoh 		days = (time / SEC_PER_DAY) + 1;  /* first day is 1 */
    696  1.1  msaitoh 		time %= SEC_PER_DAY;
    697  1.1  msaitoh 		hours = time / (60 * 60);
    698  1.1  msaitoh 		time %= (60 * 60);
    699  1.1  msaitoh 		min = time / 60;
    700  1.1  msaitoh 		sec = time % 60;
    701  1.1  msaitoh 		device_printf(adapter->dev,
    702  1.1  msaitoh 		    "UT %02d/%02d %02d:%02d:%02d %8.8s -> %7.7s\n",
    703  1.1  msaitoh 		    mon, days, hours, min, sec, event_str[event],
    704  1.1  msaitoh 		    action_str[action]);
    705  1.1  msaitoh 		cmd = BYPASS_PAGE_CTL2 | BYPASS_WE | BYPASS_CTL2_RW;
    706  1.1  msaitoh 		cmd |= ((eeprom[count].clear_off + 3)
    707  1.1  msaitoh 		    << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
    708  1.1  msaitoh 		cmd |= ((eeprom[count].logs & ~BYPASS_LOG_CLEAR_M) >> 24);
    709  1.1  msaitoh 
    710  1.1  msaitoh 		ixgbe_bypass_mutex_enter(adapter);
    711  1.1  msaitoh 
    712  1.1  msaitoh 		error = hw->mac.ops.bypass_rw(hw, cmd, &status);
    713  1.1  msaitoh 
    714  1.1  msaitoh 		/* wait for the write to stick */
    715  1.1  msaitoh 		msec_delay(100);
    716  1.1  msaitoh 
    717  1.1  msaitoh 		ixgbe_bypass_mutex_clear(adapter);
    718  1.1  msaitoh 
    719  1.1  msaitoh 		if (error)
    720  1.3  msaitoh 			return (EINVAL);
    721  1.1  msaitoh 	}
    722  1.1  msaitoh 
    723  1.1  msaitoh 	status = 0; /* reset */
    724  1.1  msaitoh 	/* Another log command can now run */
    725  1.1  msaitoh 	while (atomic_cas_uint(&adapter->bypass.log, 1, 0) == 0)
    726  1.1  msaitoh 		usec_delay(3000);
    727  1.1  msaitoh 	return(error);
    728  1.1  msaitoh 
    729  1.1  msaitoh unlock_err:
    730  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    731  1.1  msaitoh 	status = 0; /* reset */
    732  1.1  msaitoh 	while (atomic_cas_uint(&adapter->bypass.log, 1, 0) == 0)
    733  1.1  msaitoh 		usec_delay(3000);
    734  1.3  msaitoh 	return (EINVAL);
    735  1.1  msaitoh } /* ixgbe_bp_log */
    736  1.1  msaitoh 
    737  1.1  msaitoh /************************************************************************
    738  1.1  msaitoh  * ixgbe_bypass_init - Set up infrastructure for the bypass feature
    739  1.1  msaitoh  *
    740  1.1  msaitoh  *   Do time and sysctl initialization here.  This feature is
    741  1.1  msaitoh  *   only enabled for the first port of a bypass adapter.
    742  1.1  msaitoh  ************************************************************************/
    743  1.1  msaitoh void
    744  1.1  msaitoh ixgbe_bypass_init(struct adapter *adapter)
    745  1.1  msaitoh {
    746  1.1  msaitoh 	struct ixgbe_hw        *hw = &adapter->hw;
    747  1.1  msaitoh 	device_t               dev = adapter->dev;
    748  1.1  msaitoh 	u32                    mask, value, sec, year;
    749  1.1  msaitoh 	struct                 sysctllog **log;
    750  1.1  msaitoh 	const struct sysctlnode *rnode, *cnode;
    751  1.1  msaitoh 
    752  1.1  msaitoh 	if (!(adapter->feat_cap & IXGBE_FEATURE_BYPASS))
    753  1.1  msaitoh 		return;
    754  1.1  msaitoh 
    755  1.1  msaitoh 	/* First set up time for the hardware */
    756  1.1  msaitoh 	ixgbe_get_bypass_time(&year, &sec);
    757  1.1  msaitoh 
    758  1.1  msaitoh 	mask = BYPASS_CTL1_TIME_M
    759  1.1  msaitoh 	     | BYPASS_CTL1_VALID_M
    760  1.1  msaitoh 	     | BYPASS_CTL1_OFFTRST_M;
    761  1.1  msaitoh 
    762  1.1  msaitoh 	value = (sec & BYPASS_CTL1_TIME_M)
    763  1.1  msaitoh 	      | BYPASS_CTL1_VALID
    764  1.1  msaitoh 	      | BYPASS_CTL1_OFFTRST;
    765  1.1  msaitoh 
    766  1.1  msaitoh 	ixgbe_bypass_mutex_enter(adapter);
    767  1.1  msaitoh 	hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL1, mask, value);
    768  1.1  msaitoh 	ixgbe_bypass_mutex_clear(adapter);
    769  1.1  msaitoh 
    770  1.1  msaitoh 	/* Now set up the SYSCTL infrastructure */
    771  1.1  msaitoh 	log = &adapter->sysctllog;
    772  1.2  msaitoh 	if ((rnode = ixgbe_sysctl_instance(adapter)) == NULL) {
    773  1.1  msaitoh 		aprint_error_dev(dev, "could not create sysctl root\n");
    774  1.1  msaitoh 		return;
    775  1.1  msaitoh 	}
    776  1.1  msaitoh 
    777  1.1  msaitoh 	/*
    778  1.1  msaitoh 	 * The log routine is kept separate from the other
    779  1.1  msaitoh 	 * children so a general display command like:
    780  1.1  msaitoh 	 * `sysctl dev.ix.0.bypass` will not show the log.
    781  1.1  msaitoh 	 */
    782  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    783  1.1  msaitoh 	    CTLTYPE_INT, "bypass_log", SYSCTL_DESCR("Bypass Log"),
    784  1.1  msaitoh 	    ixgbe_bp_log, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    785  1.1  msaitoh 
    786  1.1  msaitoh 	/* All other setting are hung from the 'bypass' node */
    787  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &rnode, 0,
    788  1.1  msaitoh 	    CTLTYPE_NODE, "bypass", SYSCTL_DESCR("Bypass"),
    789  1.1  msaitoh 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
    790  1.1  msaitoh 
    791  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READONLY,
    792  1.1  msaitoh 	    CTLTYPE_INT, "version", SYSCTL_DESCR("Bypass Version"),
    793  1.1  msaitoh 	    ixgbe_bp_version, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    794  1.1  msaitoh 
    795  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    796  1.1  msaitoh 	    CTLTYPE_INT, "state", SYSCTL_DESCR("Bypass State"),
    797  1.1  msaitoh 	    ixgbe_bp_set_state, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    798  1.1  msaitoh 
    799  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    800  1.1  msaitoh 	    CTLTYPE_INT, "timeout", SYSCTL_DESCR("Bypass Timeout"),
    801  1.1  msaitoh 	    ixgbe_bp_timeout, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    802  1.1  msaitoh 
    803  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    804  1.1  msaitoh 	    CTLTYPE_INT, "main_on", SYSCTL_DESCR("Bypass Main On"),
    805  1.1  msaitoh 	    ixgbe_bp_main_on, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    806  1.1  msaitoh 
    807  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    808  1.1  msaitoh 	    CTLTYPE_INT, "main_off", SYSCTL_DESCR("Bypass Main Off"),
    809  1.1  msaitoh 	    ixgbe_bp_main_off, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    810  1.1  msaitoh 
    811  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    812  1.1  msaitoh 	    CTLTYPE_INT, "aux_on", SYSCTL_DESCR("Bypass Aux On"),
    813  1.1  msaitoh 	    ixgbe_bp_aux_on, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    814  1.1  msaitoh 
    815  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    816  1.1  msaitoh 	    CTLTYPE_INT, "aux_off", SYSCTL_DESCR("Bypass Aux Off"),
    817  1.1  msaitoh 	    ixgbe_bp_aux_off, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    818  1.1  msaitoh 
    819  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    820  1.1  msaitoh 	    CTLTYPE_INT, "wd_set", SYSCTL_DESCR("Set BP Watchdog"),
    821  1.1  msaitoh 	    ixgbe_bp_wd_set, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    822  1.1  msaitoh 
    823  1.1  msaitoh 	sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
    824  1.1  msaitoh 	    CTLTYPE_INT, "wd_reset", SYSCTL_DESCR("Bypass WD Reset"),
    825  1.1  msaitoh 	    ixgbe_bp_wd_reset, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL);
    826  1.1  msaitoh 
    827  1.1  msaitoh 	adapter->feat_en |= IXGBE_FEATURE_BYPASS;
    828  1.1  msaitoh 
    829  1.1  msaitoh 	return;
    830  1.1  msaitoh } /* ixgbe_bypass_init */
    831  1.1  msaitoh 
    832