1 /******************************************************************************
3 Copyright (c) 2001-2017, Intel Corporation
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 3. Neither the name of the Intel Corporation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
32 ******************************************************************************/
38 /************************************************************************
39 * ixgbe_bypass_mutex_enter
41 * Mutex support for the bypass feature. Using a dual lock
42 * to facilitate a privileged access to the watchdog update
44 ************************************************************************/
46 ixgbe_bypass_mutex_enter(struct adapter *adapter)
48 while (atomic_cmpset_int(&adapter->bypass.low, 0, 1) == 0)
50 while (atomic_cmpset_int(&adapter->bypass.high, 0, 1) == 0)
53 } /* ixgbe_bypass_mutex_enter */
55 /************************************************************************
56 * ixgbe_bypass_mutex_clear
57 ************************************************************************/
59 ixgbe_bypass_mutex_clear(struct adapter *adapter)
61 while (atomic_cmpset_int(&adapter->bypass.high, 1, 0) == 0)
63 while (atomic_cmpset_int(&adapter->bypass.low, 1, 0) == 0)
66 } /* ixgbe_bypass_mutex_clear */
68 /************************************************************************
69 * ixgbe_bypass_wd_mutex_enter
71 * Watchdog entry is allowed to simply grab the high priority
72 ************************************************************************/
74 ixgbe_bypass_wd_mutex_enter(struct adapter *adapter)
76 while (atomic_cmpset_int(&adapter->bypass.high, 0, 1) == 0)
79 } /* ixgbe_bypass_wd_mutex_enter */
81 /************************************************************************
82 * ixgbe_bypass_wd_mutex_clear
83 ************************************************************************/
85 ixgbe_bypass_wd_mutex_clear(struct adapter *adapter)
87 while (atomic_cmpset_int(&adapter->bypass.high, 1, 0) == 0)
90 } /* ixgbe_bypass_wd_mutex_clear */
92 /************************************************************************
93 * ixgbe_get_bypass_time
94 ************************************************************************/
96 ixgbe_get_bypass_time(u32 *year, u32 *sec)
98 struct timespec current;
100 *year = 1970; /* time starts at 01/01/1970 */
102 *sec = current.tv_sec;
104 while(*sec > SEC_THIS_YEAR(*year)) {
105 *sec -= SEC_THIS_YEAR(*year);
108 } /* ixgbe_get_bypass_time */
110 /************************************************************************
113 * Display the feature version
114 ************************************************************************/
116 ixgbe_bp_version(SYSCTL_HANDLER_ARGS)
118 struct adapter *adapter = (struct adapter *) arg1;
119 struct ixgbe_hw *hw = &adapter->hw;
121 static int version = 0;
124 ixgbe_bypass_mutex_enter(adapter);
125 cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
126 cmd |= (BYPASS_EEPROM_VER_ADD << BYPASS_CTL2_OFFSET_SHIFT) &
127 BYPASS_CTL2_OFFSET_M;
128 if ((error = hw->mac.ops.bypass_rw(hw, cmd, &version) != 0))
132 if ((error = hw->mac.ops.bypass_rw(hw, cmd, &version) != 0))
134 ixgbe_bypass_mutex_clear(adapter);
135 version &= BYPASS_CTL2_DATA_M;
136 error = sysctl_handle_int(oidp, &version, 0, req);
139 ixgbe_bypass_mutex_clear(adapter);
142 } /* ixgbe_bp_version */
144 /************************************************************************
147 * Show/Set the Bypass State:
152 * With no argument the state is displayed,
153 * passing a value will set it.
154 ************************************************************************/
156 ixgbe_bp_set_state(SYSCTL_HANDLER_ARGS)
158 struct adapter *adapter = (struct adapter *) arg1;
159 struct ixgbe_hw *hw = &adapter->hw;
161 static int state = 0;
163 /* Get the current state */
164 ixgbe_bypass_mutex_enter(adapter);
165 error = hw->mac.ops.bypass_rw(hw,
166 BYPASS_PAGE_CTL0, &state);
167 ixgbe_bypass_mutex_clear(adapter);
170 state = (state >> BYPASS_STATUS_OFF_SHIFT) & 0x3;
172 error = sysctl_handle_int(oidp, &state, 0, req);
173 if ((error) || (req->newptr == NULL))
176 /* Sanity check new state */
185 ixgbe_bypass_mutex_enter(adapter);
186 if ((error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
187 BYPASS_MODE_OFF_M, state) != 0))
189 /* Set AUTO back on so FW can receive events */
190 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
191 BYPASS_MODE_OFF_M, BYPASS_AUTO);
193 ixgbe_bypass_mutex_clear(adapter);
196 } /* ixgbe_bp_set_state */
198 /************************************************************************
199 * The following routines control the operational
200 * "rules" of the feature, what behavior will occur
201 * when particular events occur.
203 * 0 - no change for the event (NOP)
204 * 1 - go to Normal operation
205 * 2 - go to Bypass operation
206 * 3 - go to Isolate operation
207 * Calling the entry with no argument just displays
208 * the current rule setting.
209 ************************************************************************/
211 /************************************************************************
214 * This is to set the Rule for the watchdog,
215 * not the actual watchdog timeout value.
216 ************************************************************************/
218 ixgbe_bp_timeout(SYSCTL_HANDLER_ARGS)
220 struct adapter *adapter = (struct adapter *) arg1;
221 struct ixgbe_hw *hw = &adapter->hw;
223 static int timeout = 0;
225 /* Get the current value */
226 ixgbe_bypass_mutex_enter(adapter);
227 error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &timeout);
228 ixgbe_bypass_mutex_clear(adapter);
231 timeout = (timeout >> BYPASS_WDTIMEOUT_SHIFT) & 0x3;
233 error = sysctl_handle_int(oidp, &timeout, 0, req);
234 if ((error) || (req->newptr == NULL))
237 /* Sanity check on the setting */
248 /* Set the new state */
249 ixgbe_bypass_mutex_enter(adapter);
250 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
251 BYPASS_WDTIMEOUT_M, timeout << BYPASS_WDTIMEOUT_SHIFT);
252 ixgbe_bypass_mutex_clear(adapter);
255 } /* ixgbe_bp_timeout */
257 /************************************************************************
259 ************************************************************************/
261 ixgbe_bp_main_on(SYSCTL_HANDLER_ARGS)
263 struct adapter *adapter = (struct adapter *) arg1;
264 struct ixgbe_hw *hw = &adapter->hw;
266 static int main_on = 0;
268 ixgbe_bypass_mutex_enter(adapter);
269 error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_on);
270 main_on = (main_on >> BYPASS_MAIN_ON_SHIFT) & 0x3;
271 ixgbe_bypass_mutex_clear(adapter);
275 error = sysctl_handle_int(oidp, &main_on, 0, req);
276 if ((error) || (req->newptr == NULL))
279 /* Sanity check on the setting */
290 /* Set the new state */
291 ixgbe_bypass_mutex_enter(adapter);
292 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
293 BYPASS_MAIN_ON_M, main_on << BYPASS_MAIN_ON_SHIFT);
294 ixgbe_bypass_mutex_clear(adapter);
297 } /* ixgbe_bp_main_on */
299 /************************************************************************
301 ************************************************************************/
303 ixgbe_bp_main_off(SYSCTL_HANDLER_ARGS)
305 struct adapter *adapter = (struct adapter *) arg1;
306 struct ixgbe_hw *hw = &adapter->hw;
308 static int main_off = 0;
310 ixgbe_bypass_mutex_enter(adapter);
311 error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_off);
312 ixgbe_bypass_mutex_clear(adapter);
315 main_off = (main_off >> BYPASS_MAIN_OFF_SHIFT) & 0x3;
317 error = sysctl_handle_int(oidp, &main_off, 0, req);
318 if ((error) || (req->newptr == NULL))
321 /* Sanity check on the setting */
332 /* Set the new state */
333 ixgbe_bypass_mutex_enter(adapter);
334 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
335 BYPASS_MAIN_OFF_M, main_off << BYPASS_MAIN_OFF_SHIFT);
336 ixgbe_bypass_mutex_clear(adapter);
339 } /* ixgbe_bp_main_off */
341 /************************************************************************
343 ************************************************************************/
345 ixgbe_bp_aux_on(SYSCTL_HANDLER_ARGS)
347 struct adapter *adapter = (struct adapter *) arg1;
348 struct ixgbe_hw *hw = &adapter->hw;
350 static int aux_on = 0;
352 ixgbe_bypass_mutex_enter(adapter);
353 error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_on);
354 ixgbe_bypass_mutex_clear(adapter);
357 aux_on = (aux_on >> BYPASS_AUX_ON_SHIFT) & 0x3;
359 error = sysctl_handle_int(oidp, &aux_on, 0, req);
360 if ((error) || (req->newptr == NULL))
363 /* Sanity check on the setting */
374 /* Set the new state */
375 ixgbe_bypass_mutex_enter(adapter);
376 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
377 BYPASS_AUX_ON_M, aux_on << BYPASS_AUX_ON_SHIFT);
378 ixgbe_bypass_mutex_clear(adapter);
381 } /* ixgbe_bp_aux_on */
383 /************************************************************************
385 ************************************************************************/
387 ixgbe_bp_aux_off(SYSCTL_HANDLER_ARGS)
389 struct adapter *adapter = (struct adapter *) arg1;
390 struct ixgbe_hw *hw = &adapter->hw;
392 static int aux_off = 0;
394 ixgbe_bypass_mutex_enter(adapter);
395 error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_off);
396 ixgbe_bypass_mutex_clear(adapter);
399 aux_off = (aux_off >> BYPASS_AUX_OFF_SHIFT) & 0x3;
401 error = sysctl_handle_int(oidp, &aux_off, 0, req);
402 if ((error) || (req->newptr == NULL))
405 /* Sanity check on the setting */
416 /* Set the new state */
417 ixgbe_bypass_mutex_enter(adapter);
418 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
419 BYPASS_AUX_OFF_M, aux_off << BYPASS_AUX_OFF_SHIFT);
420 ixgbe_bypass_mutex_clear(adapter);
423 } /* ixgbe_bp_aux_off */
425 /************************************************************************
426 * ixgbe_bp_wd_set - Set the Watchdog timer value
428 * Valid settings are:
429 * - 0 will disable the watchdog
430 * - 1, 2, 3, 4, 8, 16, 32
431 * - anything else is invalid and will be ignored
432 ************************************************************************/
434 ixgbe_bp_wd_set(SYSCTL_HANDLER_ARGS)
436 struct adapter *adapter = (struct adapter *) arg1;
437 struct ixgbe_hw *hw = &adapter->hw;
439 static int timeout = 0;
440 u32 mask, arg = BYPASS_PAGE_CTL0;
442 /* Get the current hardware value */
443 ixgbe_bypass_mutex_enter(adapter);
444 error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &tmp);
445 ixgbe_bypass_mutex_clear(adapter);
449 * If armed keep the displayed value,
450 * else change the display to zero.
452 if ((tmp & (0x1 << BYPASS_WDT_ENABLE_SHIFT)) == 0)
455 error = sysctl_handle_int(oidp, &timeout, 0, req);
456 if ((error) || (req->newptr == NULL))
459 mask = BYPASS_WDT_ENABLE_M;
461 case 0: /* disables the timer */
464 arg = BYPASS_WDT_1_5 << BYPASS_WDT_TIME_SHIFT;
465 arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
466 mask |= BYPASS_WDT_VALUE_M;
469 arg = BYPASS_WDT_2 << BYPASS_WDT_TIME_SHIFT;
470 arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
471 mask |= BYPASS_WDT_VALUE_M;
474 arg = BYPASS_WDT_3 << BYPASS_WDT_TIME_SHIFT;
475 arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
476 mask |= BYPASS_WDT_VALUE_M;
479 arg = BYPASS_WDT_4 << BYPASS_WDT_TIME_SHIFT;
480 arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
481 mask |= BYPASS_WDT_VALUE_M;
484 arg = BYPASS_WDT_8 << BYPASS_WDT_TIME_SHIFT;
485 arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
486 mask |= BYPASS_WDT_VALUE_M;
489 arg = BYPASS_WDT_16 << BYPASS_WDT_TIME_SHIFT;
490 arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
491 mask |= BYPASS_WDT_VALUE_M;
494 arg = BYPASS_WDT_32 << BYPASS_WDT_TIME_SHIFT;
495 arg |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
496 mask |= BYPASS_WDT_VALUE_M;
501 /* Set the new watchdog */
502 ixgbe_bypass_mutex_enter(adapter);
503 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, mask, arg);
504 ixgbe_bypass_mutex_clear(adapter);
507 } /* ixgbe_bp_wd_set */
509 /************************************************************************
510 * ixgbe_bp_wd_reset - Reset the Watchdog timer
512 * To activate this it must be called with any argument.
513 ************************************************************************/
515 ixgbe_bp_wd_reset(SYSCTL_HANDLER_ARGS)
517 struct adapter *adapter = (struct adapter *) arg1;
518 struct ixgbe_hw *hw = &adapter->hw;
520 int cmd, count = 0, error = 0;
523 error = sysctl_handle_int(oidp, &reset_wd, 0, req);
524 if ((error) || (req->newptr == NULL))
527 cmd = BYPASS_PAGE_CTL1 | BYPASS_WE | BYPASS_CTL1_WDT_PET;
529 /* Resync the FW time while writing to CTL1 anyway */
530 ixgbe_get_bypass_time(&year, &sec);
532 cmd |= (sec & BYPASS_CTL1_TIME_M) | BYPASS_CTL1_VALID;
533 cmd |= BYPASS_CTL1_OFFTRST;
535 ixgbe_bypass_wd_mutex_enter(adapter);
536 error = hw->mac.ops.bypass_rw(hw, cmd, &reset_wd);
538 /* Read until it matches what we wrote, or we time out */
541 error = IXGBE_BYPASS_FW_WRITE_FAILURE;
544 if (hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL1, &reset_wd)) {
545 error = IXGBE_ERR_INVALID_ARGUMENT;
548 } while (!hw->mac.ops.bypass_valid_rd(cmd, reset_wd));
551 ixgbe_bypass_wd_mutex_clear(adapter);
553 } /* ixgbe_bp_wd_reset */
555 /************************************************************************
556 * ixgbe_bp_log - Display the bypass log
558 * You must pass a non-zero arg to sysctl
559 ************************************************************************/
561 ixgbe_bp_log(SYSCTL_HANDLER_ARGS)
563 struct adapter *adapter = (struct adapter *) arg1;
564 struct ixgbe_hw *hw = &adapter->hw;
566 u32 log_off, count = 0;
567 static int status = 0;
569 struct ixgbe_bypass_eeprom eeprom[BYPASS_MAX_LOGS];
572 error = sysctl_handle_int(oidp, &status, 0, req);
573 if ((error) || (req->newptr == NULL))
576 /* Keep the log display single-threaded */
577 while (atomic_cmpset_int(&adapter->bypass.log, 0, 1) == 0)
580 ixgbe_bypass_mutex_enter(adapter);
582 /* Find Current head of the log eeprom offset */
583 cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
584 cmd |= (0x1 << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
585 error = hw->mac.ops.bypass_rw(hw, cmd, &status);
589 /* wait for the write to stick */
592 /* Now read the results */
594 error = hw->mac.ops.bypass_rw(hw, cmd, &status);
598 ixgbe_bypass_mutex_clear(adapter);
600 base = status & BYPASS_CTL2_DATA_M;
601 head = (status & BYPASS_CTL2_HEAD_M) >> BYPASS_CTL2_HEAD_SHIFT;
603 /* address of the first log */
604 log_off = base + (head * 5);
606 /* extract all the log entries */
607 while (count < BYPASS_MAX_LOGS) {
608 eeprom[count].logs = 0;
609 eeprom[count].actions = 0;
611 /* Log 5 bytes store in on u32 and a u8 */
612 for (i = 0; i < 4; i++) {
613 ixgbe_bypass_mutex_enter(adapter);
614 error = hw->mac.ops.bypass_rd_eep(hw, log_off + i,
616 ixgbe_bypass_mutex_clear(adapter);
619 eeprom[count].logs += data << (8 * i);
622 ixgbe_bypass_mutex_enter(adapter);
623 error = hw->mac.ops.bypass_rd_eep(hw,
624 log_off + i, &eeprom[count].actions);
625 ixgbe_bypass_mutex_clear(adapter);
629 /* Quit if not a unread log */
630 if (!(eeprom[count].logs & BYPASS_LOG_CLEAR_M))
633 * Log looks good so store the address where it's
634 * Unread Log bit is so we can clear it after safely
635 * pulling out all of the log data.
637 eeprom[count].clear_off = log_off;
640 head = head ? head - 1 : BYPASS_MAX_LOGS;
641 log_off = base + (head * 5);
644 /* reverse order (oldest first) for output */
647 u32 mon, days, hours, min, sec;
648 u32 time = eeprom[count].logs & BYPASS_LOG_TIME_M;
649 u32 event = (eeprom[count].logs & BYPASS_LOG_EVENT_M) >>
650 BYPASS_LOG_EVENT_SHIFT;
651 u8 action = eeprom[count].actions & BYPASS_LOG_ACTION_M;
652 u16 day_mon[2][13] = {
653 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
654 {0, 31, 59, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
656 char *event_str[] = {"unknown", "main on", "aux on",
657 "main off", "aux off", "WDT", "user" };
658 char *action_str[] = {"ignore", "normal", "bypass", "isolate",};
660 /* verify vaild data 1 - 6 */
661 if (event < BYPASS_EVENT_MAIN_ON || event > BYPASS_EVENT_USR)
665 * time is in sec's this year, so convert to something
668 ixgbe_get_bypass_time(&year, &sec);
669 days = time / SEC_PER_DAY;
670 for (i = 11; days < day_mon[LEAP_YR(year)][i]; i--)
672 mon = i + 1; /* display month as 1-12 */
673 time -= (day_mon[LEAP_YR(year)][i] * SEC_PER_DAY);
674 days = (time / SEC_PER_DAY) + 1; /* first day is 1 */
676 hours = time / (60 * 60);
680 device_printf(adapter->dev,
681 "UT %02d/%02d %02d:%02d:%02d %8.8s -> %7.7s\n",
682 mon, days, hours, min, sec, event_str[event],
684 cmd = BYPASS_PAGE_CTL2 | BYPASS_WE | BYPASS_CTL2_RW;
685 cmd |= ((eeprom[count].clear_off + 3)
686 << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
687 cmd |= ((eeprom[count].logs & ~BYPASS_LOG_CLEAR_M) >> 24);
689 ixgbe_bypass_mutex_enter(adapter);
691 error = hw->mac.ops.bypass_rw(hw, cmd, &status);
693 /* wait for the write to stick */
696 ixgbe_bypass_mutex_clear(adapter);
702 status = 0; /* reset */
703 /* Another log command can now run */
704 while (atomic_cmpset_int(&adapter->bypass.log, 1, 0) == 0)
709 ixgbe_bypass_mutex_clear(adapter);
710 status = 0; /* reset */
711 while (atomic_cmpset_int(&adapter->bypass.log, 1, 0) == 0)
716 /************************************************************************
717 * ixgbe_bypass_init - Set up infrastructure for the bypass feature
719 * Do time and sysctl initialization here. This feature is
720 * only enabled for the first port of a bypass adapter.
721 ************************************************************************/
723 ixgbe_bypass_init(struct adapter *adapter)
725 struct ixgbe_hw *hw = &adapter->hw;
726 device_t dev = adapter->dev;
727 struct sysctl_oid *bp_node;
728 struct sysctl_oid_list *bp_list;
729 u32 mask, value, sec, year;
731 if (!(adapter->feat_cap & IXGBE_FEATURE_BYPASS))
734 /* First set up time for the hardware */
735 ixgbe_get_bypass_time(&year, &sec);
737 mask = BYPASS_CTL1_TIME_M
738 | BYPASS_CTL1_VALID_M
739 | BYPASS_CTL1_OFFTRST_M;
741 value = (sec & BYPASS_CTL1_TIME_M)
743 | BYPASS_CTL1_OFFTRST;
745 ixgbe_bypass_mutex_enter(adapter);
746 hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL1, mask, value);
747 ixgbe_bypass_mutex_clear(adapter);
749 /* Now set up the SYSCTL infrastructure */
752 * The log routine is kept separate from the other
753 * children so a general display command like:
754 * `sysctl dev.ix.0.bypass` will not show the log.
756 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
757 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
758 OID_AUTO, "bypass_log", CTLTYPE_INT | CTLFLAG_RW,
759 adapter, 0, ixgbe_bp_log, "I", "Bypass Log");
761 /* All other setting are hung from the 'bypass' node */
762 bp_node = SYSCTL_ADD_NODE(device_get_sysctl_ctx(dev),
763 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
764 OID_AUTO, "bypass", CTLFLAG_RD, NULL, "Bypass");
766 bp_list = SYSCTL_CHILDREN(bp_node);
768 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
769 OID_AUTO, "version", CTLTYPE_INT | CTLFLAG_RD,
770 adapter, 0, ixgbe_bp_version, "I", "Bypass Version");
772 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
773 OID_AUTO, "state", CTLTYPE_INT | CTLFLAG_RW,
774 adapter, 0, ixgbe_bp_set_state, "I", "Bypass State");
776 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
777 OID_AUTO, "timeout", CTLTYPE_INT | CTLFLAG_RW,
778 adapter, 0, ixgbe_bp_timeout, "I", "Bypass Timeout");
780 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
781 OID_AUTO, "main_on", CTLTYPE_INT | CTLFLAG_RW,
782 adapter, 0, ixgbe_bp_main_on, "I", "Bypass Main On");
784 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
785 OID_AUTO, "main_off", CTLTYPE_INT | CTLFLAG_RW,
786 adapter, 0, ixgbe_bp_main_off, "I", "Bypass Main Off");
788 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
789 OID_AUTO, "aux_on", CTLTYPE_INT | CTLFLAG_RW,
790 adapter, 0, ixgbe_bp_aux_on, "I", "Bypass Aux On");
792 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
793 OID_AUTO, "aux_off", CTLTYPE_INT | CTLFLAG_RW,
794 adapter, 0, ixgbe_bp_aux_off, "I", "Bypass Aux Off");
796 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
797 OID_AUTO, "wd_set", CTLTYPE_INT | CTLFLAG_RW,
798 adapter, 0, ixgbe_bp_wd_set, "I", "Set BP Watchdog");
800 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
801 OID_AUTO, "wd_reset", CTLTYPE_INT | CTLFLAG_WR,
802 adapter, 0, ixgbe_bp_wd_reset, "S", "Bypass WD Reset");
804 adapter->feat_en |= IXGBE_FEATURE_BYPASS;
807 } /* ixgbe_bypass_init */