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 ******************************************************************************/
37 /************************************************************************
38 * ixgbe_bypass_mutex_enter
40 * Mutex support for the bypass feature. Using a dual lock
41 * to facilitate a privileged access to the watchdog update
43 ************************************************************************/
45 ixgbe_bypass_mutex_enter(struct ixgbe_softc *sc)
47 while (atomic_cmpset_int(&sc->bypass.low, 0, 1) == 0)
49 while (atomic_cmpset_int(&sc->bypass.high, 0, 1) == 0)
52 } /* ixgbe_bypass_mutex_enter */
54 /************************************************************************
55 * ixgbe_bypass_mutex_clear
56 ************************************************************************/
58 ixgbe_bypass_mutex_clear(struct ixgbe_softc *sc)
60 while (atomic_cmpset_int(&sc->bypass.high, 1, 0) == 0)
62 while (atomic_cmpset_int(&sc->bypass.low, 1, 0) == 0)
65 } /* ixgbe_bypass_mutex_clear */
67 /************************************************************************
68 * ixgbe_bypass_wd_mutex_enter
70 * Watchdog entry is allowed to simply grab the high priority
71 ************************************************************************/
73 ixgbe_bypass_wd_mutex_enter(struct ixgbe_softc *sc)
75 while (atomic_cmpset_int(&sc->bypass.high, 0, 1) == 0)
78 } /* ixgbe_bypass_wd_mutex_enter */
80 /************************************************************************
81 * ixgbe_bypass_wd_mutex_clear
82 ************************************************************************/
84 ixgbe_bypass_wd_mutex_clear(struct ixgbe_softc *sc)
86 while (atomic_cmpset_int(&sc->bypass.high, 1, 0) == 0)
89 } /* ixgbe_bypass_wd_mutex_clear */
91 /************************************************************************
92 * ixgbe_get_bypass_time
93 ************************************************************************/
95 ixgbe_get_bypass_time(u32 *year, u32 *sec)
97 struct timespec current;
99 *year = 1970; /* time starts at 01/01/1970 */
101 *sec = current.tv_sec;
103 while(*sec > SEC_THIS_YEAR(*year)) {
104 *sec -= SEC_THIS_YEAR(*year);
107 } /* ixgbe_get_bypass_time */
109 /************************************************************************
112 * Display the feature version
113 ************************************************************************/
115 ixgbe_bp_version(SYSCTL_HANDLER_ARGS)
117 struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1;
118 struct ixgbe_hw *hw = &sc->hw;
120 static int version = 0;
123 ixgbe_bypass_mutex_enter(sc);
124 cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
125 cmd |= (BYPASS_EEPROM_VER_ADD << BYPASS_CTL2_OFFSET_SHIFT) &
126 BYPASS_CTL2_OFFSET_M;
127 if ((error = hw->mac.ops.bypass_rw(hw, cmd, &version) != 0))
131 if ((error = hw->mac.ops.bypass_rw(hw, cmd, &version) != 0))
133 ixgbe_bypass_mutex_clear(sc);
134 version &= BYPASS_CTL2_DATA_M;
135 error = sysctl_handle_int(oidp, &version, 0, req);
138 ixgbe_bypass_mutex_clear(sc);
141 } /* ixgbe_bp_version */
143 /************************************************************************
146 * Show/Set the Bypass State:
151 * With no argument the state is displayed,
152 * passing a value will set it.
153 ************************************************************************/
155 ixgbe_bp_set_state(SYSCTL_HANDLER_ARGS)
157 struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1;
158 struct ixgbe_hw *hw = &sc->hw;
160 static int state = 0;
162 /* Get the current state */
163 ixgbe_bypass_mutex_enter(sc);
164 error = hw->mac.ops.bypass_rw(hw,
165 BYPASS_PAGE_CTL0, &state);
166 ixgbe_bypass_mutex_clear(sc);
169 state = (state >> BYPASS_STATUS_OFF_SHIFT) & 0x3;
171 error = sysctl_handle_int(oidp, &state, 0, req);
172 if ((error != 0) || (req->newptr == NULL))
175 /* Sanity check new state */
184 ixgbe_bypass_mutex_enter(sc);
185 if ((error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
186 BYPASS_MODE_OFF_M, state) != 0))
188 /* Set AUTO back on so FW can receive events */
189 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
190 BYPASS_MODE_OFF_M, BYPASS_AUTO);
192 ixgbe_bypass_mutex_clear(sc);
195 } /* ixgbe_bp_set_state */
197 /************************************************************************
198 * The following routines control the operational
199 * "rules" of the feature, what behavior will occur
200 * when particular events occur.
202 * 0 - no change for the event (NOP)
203 * 1 - go to Normal operation
204 * 2 - go to Bypass operation
205 * 3 - go to Isolate operation
206 * Calling the entry with no argument just displays
207 * the current rule setting.
208 ************************************************************************/
210 /************************************************************************
213 * This is to set the Rule for the watchdog,
214 * not the actual watchdog timeout value.
215 ************************************************************************/
217 ixgbe_bp_timeout(SYSCTL_HANDLER_ARGS)
219 struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1;
220 struct ixgbe_hw *hw = &sc->hw;
222 static int timeout = 0;
224 /* Get the current value */
225 ixgbe_bypass_mutex_enter(sc);
226 error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &timeout);
227 ixgbe_bypass_mutex_clear(sc);
230 timeout = (timeout >> BYPASS_WDTIMEOUT_SHIFT) & 0x3;
232 error = sysctl_handle_int(oidp, &timeout, 0, req);
233 if ((error) || (req->newptr == NULL))
236 /* Sanity check on the setting */
247 /* Set the new state */
248 ixgbe_bypass_mutex_enter(sc);
249 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
250 BYPASS_WDTIMEOUT_M, timeout << BYPASS_WDTIMEOUT_SHIFT);
251 ixgbe_bypass_mutex_clear(sc);
254 } /* ixgbe_bp_timeout */
256 /************************************************************************
258 ************************************************************************/
260 ixgbe_bp_main_on(SYSCTL_HANDLER_ARGS)
262 struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1;
263 struct ixgbe_hw *hw = &sc->hw;
265 static int main_on = 0;
267 ixgbe_bypass_mutex_enter(sc);
268 error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_on);
269 main_on = (main_on >> BYPASS_MAIN_ON_SHIFT) & 0x3;
270 ixgbe_bypass_mutex_clear(sc);
274 error = sysctl_handle_int(oidp, &main_on, 0, req);
275 if ((error) || (req->newptr == NULL))
278 /* Sanity check on the setting */
289 /* Set the new state */
290 ixgbe_bypass_mutex_enter(sc);
291 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
292 BYPASS_MAIN_ON_M, main_on << BYPASS_MAIN_ON_SHIFT);
293 ixgbe_bypass_mutex_clear(sc);
296 } /* ixgbe_bp_main_on */
298 /************************************************************************
300 ************************************************************************/
302 ixgbe_bp_main_off(SYSCTL_HANDLER_ARGS)
304 struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1;
305 struct ixgbe_hw *hw = &sc->hw;
307 static int main_off = 0;
309 ixgbe_bypass_mutex_enter(sc);
310 error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &main_off);
311 ixgbe_bypass_mutex_clear(sc);
314 main_off = (main_off >> BYPASS_MAIN_OFF_SHIFT) & 0x3;
316 error = sysctl_handle_int(oidp, &main_off, 0, req);
317 if ((error) || (req->newptr == NULL))
320 /* Sanity check on the setting */
331 /* Set the new state */
332 ixgbe_bypass_mutex_enter(sc);
333 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
334 BYPASS_MAIN_OFF_M, main_off << BYPASS_MAIN_OFF_SHIFT);
335 ixgbe_bypass_mutex_clear(sc);
338 } /* ixgbe_bp_main_off */
340 /************************************************************************
342 ************************************************************************/
344 ixgbe_bp_aux_on(SYSCTL_HANDLER_ARGS)
346 struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1;
347 struct ixgbe_hw *hw = &sc->hw;
349 static int aux_on = 0;
351 ixgbe_bypass_mutex_enter(sc);
352 error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_on);
353 ixgbe_bypass_mutex_clear(sc);
356 aux_on = (aux_on >> BYPASS_AUX_ON_SHIFT) & 0x3;
358 error = sysctl_handle_int(oidp, &aux_on, 0, req);
359 if ((error) || (req->newptr == NULL))
362 /* Sanity check on the setting */
373 /* Set the new state */
374 ixgbe_bypass_mutex_enter(sc);
375 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
376 BYPASS_AUX_ON_M, aux_on << BYPASS_AUX_ON_SHIFT);
377 ixgbe_bypass_mutex_clear(sc);
380 } /* ixgbe_bp_aux_on */
382 /************************************************************************
384 ************************************************************************/
386 ixgbe_bp_aux_off(SYSCTL_HANDLER_ARGS)
388 struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1;
389 struct ixgbe_hw *hw = &sc->hw;
391 static int aux_off = 0;
393 ixgbe_bypass_mutex_enter(sc);
394 error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &aux_off);
395 ixgbe_bypass_mutex_clear(sc);
398 aux_off = (aux_off >> BYPASS_AUX_OFF_SHIFT) & 0x3;
400 error = sysctl_handle_int(oidp, &aux_off, 0, req);
401 if ((error) || (req->newptr == NULL))
404 /* Sanity check on the setting */
415 /* Set the new state */
416 ixgbe_bypass_mutex_enter(sc);
417 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
418 BYPASS_AUX_OFF_M, aux_off << BYPASS_AUX_OFF_SHIFT);
419 ixgbe_bypass_mutex_clear(sc);
422 } /* ixgbe_bp_aux_off */
424 /************************************************************************
425 * ixgbe_bp_wd_set - Set the Watchdog timer value
427 * Valid settings are:
428 * - 0 will disable the watchdog
429 * - 1, 2, 3, 4, 8, 16, 32
430 * - anything else is invalid and will be ignored
431 ************************************************************************/
433 ixgbe_bp_wd_set(SYSCTL_HANDLER_ARGS)
435 struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1;
436 struct ixgbe_hw *hw = &sc->hw;
438 static int timeout = 0;
441 /* Get the current hardware value */
442 ixgbe_bypass_mutex_enter(sc);
443 error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL0, &tmp);
444 ixgbe_bypass_mutex_clear(sc);
448 * If armed keep the displayed value,
449 * else change the display to zero.
451 if ((tmp & (0x1 << BYPASS_WDT_ENABLE_SHIFT)) == 0)
454 error = sysctl_handle_int(oidp, &timeout, 0, req);
455 if ((error) || (req->newptr == NULL))
458 arg = 0x1 << BYPASS_WDT_ENABLE_SHIFT;
459 mask = BYPASS_WDT_ENABLE_M | BYPASS_WDT_VALUE_M;
461 case 0: /* disables the timer */
462 arg = BYPASS_PAGE_CTL0;
463 mask = BYPASS_WDT_ENABLE_M;
466 arg |= BYPASS_WDT_1_5 << BYPASS_WDT_TIME_SHIFT;
469 arg |= BYPASS_WDT_2 << BYPASS_WDT_TIME_SHIFT;
472 arg |= BYPASS_WDT_3 << BYPASS_WDT_TIME_SHIFT;
475 arg |= BYPASS_WDT_4 << BYPASS_WDT_TIME_SHIFT;
478 arg |= BYPASS_WDT_8 << BYPASS_WDT_TIME_SHIFT;
481 arg |= BYPASS_WDT_16 << BYPASS_WDT_TIME_SHIFT;
484 arg |= BYPASS_WDT_32 << BYPASS_WDT_TIME_SHIFT;
490 /* Set the new watchdog */
491 ixgbe_bypass_mutex_enter(sc);
492 error = hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL0, mask, arg);
493 ixgbe_bypass_mutex_clear(sc);
496 } /* ixgbe_bp_wd_set */
498 /************************************************************************
499 * ixgbe_bp_wd_reset - Reset the Watchdog timer
501 * To activate this it must be called with any argument.
502 ************************************************************************/
504 ixgbe_bp_wd_reset(SYSCTL_HANDLER_ARGS)
506 struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1;
507 struct ixgbe_hw *hw = &sc->hw;
509 int cmd, count = 0, error = 0;
512 error = sysctl_handle_int(oidp, &reset_wd, 0, req);
513 if ((error) || (req->newptr == NULL))
516 cmd = BYPASS_PAGE_CTL1 | BYPASS_WE | BYPASS_CTL1_WDT_PET;
518 /* Resync the FW time while writing to CTL1 anyway */
519 ixgbe_get_bypass_time(&year, &sec);
521 cmd |= (sec & BYPASS_CTL1_TIME_M) | BYPASS_CTL1_VALID;
522 cmd |= BYPASS_CTL1_OFFTRST;
524 ixgbe_bypass_wd_mutex_enter(sc);
525 error = hw->mac.ops.bypass_rw(hw, cmd, &reset_wd);
527 /* Read until it matches what we wrote, or we time out */
530 error = IXGBE_BYPASS_FW_WRITE_FAILURE;
533 error = hw->mac.ops.bypass_rw(hw, BYPASS_PAGE_CTL1, &reset_wd);
535 error = IXGBE_ERR_INVALID_ARGUMENT;
538 } while (!hw->mac.ops.bypass_valid_rd(cmd, reset_wd));
541 ixgbe_bypass_wd_mutex_clear(sc);
543 } /* ixgbe_bp_wd_reset */
545 /************************************************************************
546 * ixgbe_bp_log - Display the bypass log
548 * You must pass a non-zero arg to sysctl
549 ************************************************************************/
551 ixgbe_bp_log(SYSCTL_HANDLER_ARGS)
553 struct ixgbe_softc *sc = (struct ixgbe_softc *) arg1;
554 struct ixgbe_hw *hw = &sc->hw;
556 u32 log_off, count = 0;
557 static int status = 0;
559 struct ixgbe_bypass_eeprom eeprom[BYPASS_MAX_LOGS];
562 error = sysctl_handle_int(oidp, &status, 0, req);
563 if ((error) || (req->newptr == NULL))
566 /* Keep the log display single-threaded */
567 while (atomic_cmpset_int(&sc->bypass.log, 0, 1) == 0)
570 ixgbe_bypass_mutex_enter(sc);
572 /* Find Current head of the log eeprom offset */
573 cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
574 cmd |= (0x1 << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
575 error = hw->mac.ops.bypass_rw(hw, cmd, &status);
579 /* wait for the write to stick */
582 /* Now read the results */
584 error = hw->mac.ops.bypass_rw(hw, cmd, &status);
588 ixgbe_bypass_mutex_clear(sc);
590 base = status & BYPASS_CTL2_DATA_M;
591 head = (status & BYPASS_CTL2_HEAD_M) >> BYPASS_CTL2_HEAD_SHIFT;
593 /* address of the first log */
594 log_off = base + (head * 5);
596 /* extract all the log entries */
597 while (count < BYPASS_MAX_LOGS) {
598 eeprom[count].logs = 0;
599 eeprom[count].actions = 0;
601 /* Log 5 bytes store in on u32 and a u8 */
602 for (i = 0; i < 4; i++) {
603 ixgbe_bypass_mutex_enter(sc);
604 error = hw->mac.ops.bypass_rd_eep(hw, log_off + i,
606 ixgbe_bypass_mutex_clear(sc);
609 eeprom[count].logs += data << (8 * i);
612 ixgbe_bypass_mutex_enter(sc);
613 error = hw->mac.ops.bypass_rd_eep(hw,
614 log_off + i, &eeprom[count].actions);
615 ixgbe_bypass_mutex_clear(sc);
619 /* Quit if not a unread log */
620 if (!(eeprom[count].logs & BYPASS_LOG_CLEAR_M))
623 * Log looks good so store the address where it's
624 * Unread Log bit is so we can clear it after safely
625 * pulling out all of the log data.
627 eeprom[count].clear_off = log_off;
630 head = head ? head - 1 : BYPASS_MAX_LOGS;
631 log_off = base + (head * 5);
634 /* reverse order (oldest first) for output */
637 u32 mon, days, hours, min, sec;
638 u32 time = eeprom[count].logs & BYPASS_LOG_TIME_M;
639 u32 event = (eeprom[count].logs & BYPASS_LOG_EVENT_M) >>
640 BYPASS_LOG_EVENT_SHIFT;
641 u8 action = eeprom[count].actions & BYPASS_LOG_ACTION_M;
642 u16 day_mon[2][13] = {
643 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
644 {0, 31, 59, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
646 char *event_str[] = {"unknown", "main on", "aux on",
647 "main off", "aux off", "WDT", "user" };
648 char *action_str[] = {"ignore", "normal", "bypass", "isolate",};
650 /* verify vaild data 1 - 6 */
651 if (event < BYPASS_EVENT_MAIN_ON || event > BYPASS_EVENT_USR)
655 * time is in sec's this year, so convert to something
658 ixgbe_get_bypass_time(&year, &sec);
659 days = time / SEC_PER_DAY;
660 for (i = 11; days < day_mon[LEAP_YR(year)][i]; i--)
662 mon = i + 1; /* display month as 1-12 */
663 time -= (day_mon[LEAP_YR(year)][i] * SEC_PER_DAY);
664 days = (time / SEC_PER_DAY) + 1; /* first day is 1 */
666 hours = time / (60 * 60);
670 device_printf(sc->dev,
671 "UT %02d/%02d %02d:%02d:%02d %8.8s -> %7.7s\n",
672 mon, days, hours, min, sec, event_str[event],
674 cmd = BYPASS_PAGE_CTL2 | BYPASS_WE | BYPASS_CTL2_RW;
675 cmd |= ((eeprom[count].clear_off + 3)
676 << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
677 cmd |= ((eeprom[count].logs & ~BYPASS_LOG_CLEAR_M) >> 24);
679 ixgbe_bypass_mutex_enter(sc);
681 error = hw->mac.ops.bypass_rw(hw, cmd, &status);
683 /* wait for the write to stick */
686 ixgbe_bypass_mutex_clear(sc);
692 status = 0; /* reset */
693 /* Another log command can now run */
694 while (atomic_cmpset_int(&sc->bypass.log, 1, 0) == 0)
699 ixgbe_bypass_mutex_clear(sc);
700 status = 0; /* reset */
701 while (atomic_cmpset_int(&sc->bypass.log, 1, 0) == 0)
706 /************************************************************************
707 * ixgbe_bypass_init - Set up infrastructure for the bypass feature
709 * Do time and sysctl initialization here. This feature is
710 * only enabled for the first port of a bypass adapter.
711 ************************************************************************/
713 ixgbe_bypass_init(struct ixgbe_softc *sc)
715 struct ixgbe_hw *hw = &sc->hw;
716 device_t dev = sc->dev;
717 struct sysctl_oid *bp_node;
718 struct sysctl_oid_list *bp_list;
719 u32 mask, value, sec, year;
721 if (!(sc->feat_cap & IXGBE_FEATURE_BYPASS))
724 /* First set up time for the hardware */
725 ixgbe_get_bypass_time(&year, &sec);
727 mask = BYPASS_CTL1_TIME_M
728 | BYPASS_CTL1_VALID_M
729 | BYPASS_CTL1_OFFTRST_M;
731 value = (sec & BYPASS_CTL1_TIME_M)
733 | BYPASS_CTL1_OFFTRST;
735 ixgbe_bypass_mutex_enter(sc);
736 hw->mac.ops.bypass_set(hw, BYPASS_PAGE_CTL1, mask, value);
737 ixgbe_bypass_mutex_clear(sc);
739 /* Now set up the SYSCTL infrastructure */
742 * The log routine is kept separate from the other
743 * children so a general display command like:
744 * `sysctl dev.ix.0.bypass` will not show the log.
746 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
747 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
748 OID_AUTO, "bypass_log",
749 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
750 sc, 0, ixgbe_bp_log, "I", "Bypass Log");
752 /* All other setting are hung from the 'bypass' node */
753 bp_node = SYSCTL_ADD_NODE(device_get_sysctl_ctx(dev),
754 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
755 OID_AUTO, "bypass", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Bypass");
757 bp_list = SYSCTL_CHILDREN(bp_node);
759 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
760 OID_AUTO, "version", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
761 sc, 0, ixgbe_bp_version, "I", "Bypass Version");
763 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
764 OID_AUTO, "state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
765 sc, 0, ixgbe_bp_set_state, "I", "Bypass State");
767 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
768 OID_AUTO, "timeout", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
769 sc, 0, ixgbe_bp_timeout, "I", "Bypass Timeout");
771 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
772 OID_AUTO, "main_on", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
773 sc, 0, ixgbe_bp_main_on, "I", "Bypass Main On");
775 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
776 OID_AUTO, "main_off", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
777 sc, 0, ixgbe_bp_main_off, "I", "Bypass Main Off");
779 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
780 OID_AUTO, "aux_on", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
781 sc, 0, ixgbe_bp_aux_on, "I", "Bypass Aux On");
783 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
784 OID_AUTO, "aux_off", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
785 sc, 0, ixgbe_bp_aux_off, "I", "Bypass Aux Off");
787 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
788 OID_AUTO, "wd_set", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
789 sc, 0, ixgbe_bp_wd_set, "I", "Set BP Watchdog");
791 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), bp_list,
792 OID_AUTO, "wd_reset", CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_NEEDGIANT,
793 sc, 0, ixgbe_bp_wd_reset, "S", "Bypass WD Reset");
795 sc->feat_en |= IXGBE_FEATURE_BYPASS;
796 } /* ixgbe_bypass_init */