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