ecore_dbg_fw_funcs.h revision 337517
1142140Snjl/*
2142140Snjl * Copyright (c) 2017-2018 Cavium, Inc.
3142140Snjl * All rights reserved.
4142140Snjl *
5142140Snjl *  Redistribution and use in source and binary forms, with or without
6142140Snjl *  modification, are permitted provided that the following conditions
7142140Snjl *  are met:
8142140Snjl *
9142140Snjl *  1. Redistributions of source code must retain the above copyright
10142140Snjl *     notice, this list of conditions and the following disclaimer.
11142140Snjl *  2. Redistributions in binary form must reproduce the above copyright
12142140Snjl *     notice, this list of conditions and the following disclaimer in the
13142140Snjl *     documentation and/or other materials provided with the distribution.
14142140Snjl *
15142140Snjl *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16142140Snjl *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17142140Snjl *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18142140Snjl *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19142140Snjl *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20142140Snjl *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21142140Snjl *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22142140Snjl *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23142140Snjl *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24142140Snjl *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25142140Snjl *  POSSIBILITY OF SUCH DAMAGE.
26142140Snjl *
27142140Snjl * $FreeBSD: stable/11/sys/dev/qlnx/qlnxe/ecore_dbg_fw_funcs.h 337517 2018-08-09 01:17:35Z davidcs $
28142140Snjl *
29142140Snjl */
30142140Snjl
31142140Snjl#ifndef _DBG_FW_FUNCS_H
32142140Snjl#define _DBG_FW_FUNCS_H
33142140Snjl/**************************** Public Functions *******************************/
34142140Snjl
35143902Snjl/**
36142140Snjl * @brief ecore_dbg_set_bin_ptr - Sets a pointer to the binary data with debug
37142140Snjl * arrays.
38142140Snjl *
39142140Snjl * @param bin_ptr - a pointer to the binary data with debug arrays.
40142140Snjl */
41142140Snjlenum dbg_status ecore_dbg_set_bin_ptr(const u8 * const bin_ptr);
42142140Snjl
43144630Snjl/**
44144630Snjl * @brief ecore_dbg_set_app_ver - Sets the version of the calling app.
45144630Snjl *
46144630Snjl * The application should call this function with the TOOLS_VERSION
47142140Snjl * it compiles with. Must be called before all other debug functions.
48142140Snjl *
49142140Snjl * @return error if one of the following holds:
50142140Snjl *	- the specified app version is not supported
51142140Snjl * Otherwise, returns ok.
52142140Snjl */
53142140Snjlenum dbg_status ecore_dbg_set_app_ver(u32 ver);
54142140Snjl
55142140Snjl/**
56142140Snjl * @brief ecore_dbg_get_fw_func_ver - Returns the FW func version.
57142140Snjl *
58142140Snjl * @return the FW func version.
59142140Snjl */
60143902Snjlu32 ecore_dbg_get_fw_func_ver(void);
61142140Snjl
62142140Snjl/**
63142140Snjl* @brief ecore_dbg_get_chip_id - Returns the FW func version.
64142140Snjl*
65142140Snjl* @param p_hwfn - HW device data
66142140Snjl*
67142140Snjl* @return the chip ID.
68143902Snjl*/
69142140Snjlenum chip_ids ecore_dbg_get_chip_id(struct ecore_hwfn *p_hwfn);
70142140Snjl
71142140Snjl/**
72143902Snjl* @brief ecore_read_regs - Reads registers into a buffer (using GRC).
73143902Snjl*
74143902Snjl* @param p_hwfn -	HW device data
75142140Snjl* @param p_ptt -	Ptt window used for writing the registers.
76142140Snjl* @param buf -	Destination buffer.
77142140Snjl* @param addr -	Source GRC address in dwords.
78142140Snjl* @param len -	Number of registers to read.
79142140Snjl*/
80142140Snjlvoid ecore_read_regs(struct ecore_hwfn *p_hwfn,
81142140Snjl					 struct ecore_ptt *p_ptt,
82142140Snjl					 u32 *buf,
83142140Snjl					 u32 addr,
84142140Snjl					 u32 len);
85143902Snjl
86142140Snjl/**
87142140Snjl * @brief ecore_dbg_bus_reset - Resets the Debug block.
88142140Snjl *
89142140Snjl * After reset:
90142140Snjl * - The last recording is erased.
91142140Snjl * - Recording is directed to the internal buffer.
92142140Snjl * - Wrap-around recording is selected.
93142140Snjl * - All HW blocks are disabled.
94142140Snjl * - All Storms are disabled and all SEM filters are cleared.
95142140Snjl *
96142140Snjl * @param p_hwfn -		    HW device data
97142140Snjl * @param p_ptt -		    Ptt window used for writing the registers.
98142140Snjl * @param one_shot_en -     Enable/Disable one-shot recording. If disabled,
99142140Snjl *			    wrap-around recording is used instead.
100142140Snjl * @param force_hw_dwords - If set to 0, no. of HW/Storm dwords per cycle is
101142140Snjl *			    chosen automatically based on the enabled inputs.
102142140Snjl *			    Otherwise, no. of HW dwords per cycle is forced to
103142140Snjl *			    the specified value. Valid values: 0/2/4/8.
104142140Snjl * @param unify_inputs -    If true, all recorded data is associated with a
105143902Snjl *			    single input, as if all data was received from the
106143902Snjl *			    same block. Otherwise, each data unit is associated
107142140Snjl *			    with its original input.
108142140Snjl * @param grc_input_en -    Enable/Disable recording GRC input. If enabled, the
109143902Snjl *			    GRC input is recorded to the lsb dword of a cycle.
110142140Snjl *
111143902Snjl * @return error if one of the following holds:
112142140Snjl *	- the version wasn't set
113142140Snjl *	- force_hw_dwords is invalid.
114142140Snjl * Otherwise, returns ok.
115142140Snjl */
116142140Snjlenum dbg_status ecore_dbg_bus_reset(struct ecore_hwfn *p_hwfn,
117142140Snjl									struct ecore_ptt *p_ptt,
118142140Snjl									bool one_shot_en,
119142140Snjl									u8 force_hw_dwords,
120142140Snjl									bool unify_inputs,
121143902Snjl									bool grc_input_en);
122142140Snjl
123142140Snjl/**
124142140Snjl * @brief ecore_dbg_bus_set_pci_output - Directs debug output to a PCI buffer.
125142140Snjl *
126142140Snjl * @param p_hwfn -		HW device data
127142140Snjl * @param p_ptt -		Ptt window used for writing the registers.
128142140Snjl * @param buf_size_kb - Size of PCI buffer to allocate (in KB). Must be aligned
129142140Snjl *			to PCI request size.
130142140Snjl *
131143902Snjl * @return error if one of the following holds:
132142140Snjl *	- the Debug block wasn't reset since last recording
133142140Snjl *	- the version wasn't set
134142140Snjl *	- the output was already set
135142140Snjl *	- the PCI buffer size is not aligned to PCI packet size
136142140Snjl *	- the PCI buffer allocation failed
137142140Snjl * Otherwise, returns ok.
138142140Snjl */
139142140Snjlenum dbg_status ecore_dbg_bus_set_pci_output(struct ecore_hwfn *p_hwfn,
140142140Snjl											 struct ecore_ptt *p_ptt,
141143902Snjl											 u16 buf_size_kb);
142142140Snjl
143142140Snjl/**
144142140Snjl * @brief ecore_dbg_bus_set_nw_output - Directs debug output to the network.
145142140Snjl *
146142140Snjl * @param p_hwfn -			HW device data
147142140Snjl * @param p_ptt -			Ptt window used for writing the registers.
148142140Snjl * @param port_id -		Port ID to transmit the debug data on
149142140Snjl * @param dest_addr_lo32 -	Destination MAC address (for Eth header)
150143902Snjl * @param dest_addr_hi16
151142140Snjl * @param data_limit_size_kb -  Data limit size in KB (valid only for one-shot)
152142140Snjl *				If set to 0, data limit won't be configured.
153142140Snjl * @param send_to_other_engine -If true:
154142140Snjl *				1) The NW output will be sent to the DBG block
155142140Snjl *				   of the other engine.
156142140Snjl *				2) port_id argument is ignored.
157142140Snjl *				3) rcv_from_other_engine should be set to false
158142140Snjl *				   The other engine DBG block should call this
159143902Snjl *				   function with rcv_from_other_engine set to
160142140Snjl *				   true.
161142140Snjl * @param rcv_from_other_engine-If true:
162142140Snjl *				1) the DBG block receives the NW output sent
163142140Snjl *				   from the other engine DBG block, and sends
164142140Snjl *				   it to a NW port in the current engine
165142140Snjl *				   (according to port_id).
166142140Snjl *				2) The src/dest addresses and eth_type
167142140Snjl *				   arguments are ignored.
168142140Snjl *				3) send_to_other_engine should be set to false.
169142140Snjl *				   The other engine DBG block should call this
170143902Snjl *				   function with send_to_other_engine set to
171142140Snjl *				   true.
172142140Snjl *
173142140Snjl * @return error if one of the following holds:
174142140Snjl *	- the Debug block wasn't reset since last recording
175142140Snjl *	- the version wasn't set
176142140Snjl *	- the output was already set
177142140Snjl * Otherwise, returns ok.
178142140Snjl */
179142140Snjlenum dbg_status ecore_dbg_bus_set_nw_output(struct ecore_hwfn *p_hwfn,
180143902Snjl											struct ecore_ptt *p_ptt,
181142140Snjl											u8 port_id,
182142140Snjl											u32 dest_addr_lo32,
183142140Snjl											u16 dest_addr_hi16,
184142140Snjl											u16 data_limit_size_kb,
185142140Snjl											bool send_to_other_engine,
186142140Snjl											bool rcv_from_other_engine);
187142140Snjl
188142140Snjl/**
189143902Snjl * @brief ecore_dbg_bus_enable_block - Enables recording of the specified block
190142140Snjl *
191142140Snjl * Each recording cycle contains 4 "units". If the recorded HW data requires up
192142140Snjl * to 4 dwords per cycle, each unit is one dword (32 bits). Otherwise, each
193142140Snjl * unit is 2 dwords (64 bits).
194142140Snjl *
195142140Snjl * @param p_hwfn -		HW device data
196142140Snjl * @param block -	block to be enabled.
197142140Snjl * @param line_num -	debug line number to select.
198143902Snjl * @param cycle_en -	4-bit value. If bit i is set, unit i is enabled.
199142140Snjl * @param right_shift -	number of units to  right the debug data (0-3).
200142140Snjl * @param force_valid - 4-bit value. If bit i is set, unit i is forced valid.
201142140Snjl * @param force_frame - 4-bit value. If bit i is set, the frame bit of unit i
202142140Snjl *			is forced.
203142140Snjl *
204142140Snjl * @return error if one of the following holds:
205142140Snjl *	- the Debug block wasn't reset since last recording
206142140Snjl *	- the version wasn't set
207142140Snjl *	- block is not valid
208142140Snjl *	- block was already enabled
209142140Snjl *	- cycle_en, force_valid or force_frame are wider than 4 bits
210142140Snjl *	- right_shift is larger than 3
211143902Snjl *	- cycle unit 0 is enabled, but GRC or timestamp were also enabled.
212142140Snjl *	- Too many inputs were enabled.
213142140Snjl * Otherwise, returns ok.
214142140Snjl */
215142140Snjlenum dbg_status ecore_dbg_bus_enable_block(struct ecore_hwfn *p_hwfn,
216142140Snjl										   enum block_id block,
217142140Snjl										   u8 line_num,
218142140Snjl										   u8 cycle_en,
219142140Snjl										   u8 right_shift,
220142140Snjl										   u8 force_valid,
221142140Snjl										   u8 force_frame);
222142140Snjl
223143902Snjl/**
224142140Snjl * @brief ecore_dbg_bus_enable_storm - Enables recording of the specified Storm
225142140Snjl *
226142140Snjl * @param p_hwfn -		HW device data
227142140Snjl * @param storm -	Storm to be enabled.
228142140Snjl * @param storm_mode-	Storm mode
229142140Snjl *
230142140Snjl * @return error if one of the following holds:
231142140Snjl *	- the Debug block wasn't reset since last recording
232142140Snjl *	- the version wasn't set
233142140Snjl *	- the specified storm or mode is invalid
234142140Snjl *	- Storm was already enabled
235143902Snjl *	- only HW data can be recorded
236142140Snjl *	- Too many inputs were enabled.
237142140Snjl * Otherwise, returns ok.
238142140Snjl */
239142140Snjlenum dbg_status ecore_dbg_bus_enable_storm(struct ecore_hwfn *p_hwfn,
240142140Snjl										   enum dbg_storms storm,
241142140Snjl										   enum dbg_bus_storm_modes storm_mode);
242142140Snjl
243142140Snjl/**
244142140Snjl * @brief ecore_dbg_bus_enable_timestamp - Enables timestamp recording.
245142140Snjl *
246142140Snjl * When enabled, the timestamp input is always recorded to the lsb dword of
247143902Snjl * a cycle, with HW ID 0.
248142140Snjl *
249142140Snjl * @param p_hwfn -	     HW device data
250142140Snjl * @param p_ptt -	     Ptt window used for writing the registers.
251142140Snjl * @param valid_en - 3-bit value. The Timestamp will be recorded in a cycle if
252142140Snjl *		     bit i is set and unit i+1 is valid.
253142140Snjl * @param frame_en - 3-bit value. The Timestamp will be recorded in a cycle if
254142140Snjl *		     bit i is set and unit i+1 has frame bit set.
255142140Snjl * @param tick_len - timestamp tick length in cycles, minus 1. A value of 0
256142140Snjl *		     means one cycle.
257142140Snjl *
258142140Snjl * @return error if one of the following holds:
259143902Snjl *	- the Debug block wasn't reset since last recording
260142140Snjl *	- the version wasn't set
261142140Snjl *	- valid_en or frame_en are wider than 4 bits
262142140Snjl *	- Both timestamp and GRC are enabled.
263142140Snjl * Otherwise, returns ok.
264142140Snjl */
265142140Snjlenum dbg_status ecore_dbg_bus_enable_timestamp(struct ecore_hwfn *p_hwfn,
266142140Snjl											   struct ecore_ptt *p_ptt,
267142140Snjl											   u8 valid_en,
268142140Snjl											   u8 frame_en,
269142140Snjl											   u32 tick_len);
270142140Snjl
271143902Snjl/**
272142140Snjl * @brief ecore_dbg_bus_add_eid_range_sem_filter- Add Event ID range SEM filter
273142140Snjl *
274142140Snjl * @param p_hwfn -     HW device data
275142140Snjl * @param storm -   Storm to be filtered.
276142140Snjl * @param min_eid - minimal Event ID to filter on.
277142140Snjl * @param max_eid - maximal Event ID to filter on.
278142140Snjl *
279142140Snjl * @return error if one of the following holds:
280142140Snjl *	- the specified Storm is invalid
281142140Snjl *	- the specified Storm wasn't enabled
282142140Snjl *	- the EID range is not valid
283143902Snjl * Otherwise, returns ok.
284142140Snjl */
285142140Snjlenum dbg_status ecore_dbg_bus_add_eid_range_sem_filter(struct ecore_hwfn *p_hwfn,
286142140Snjl													   enum dbg_storms storm,
287142140Snjl													   u8 min_eid,
288142140Snjl													   u8 max_eid);
289142140Snjl
290142140Snjl/**
291142140Snjl * @brief ecore_dbg_bus_add_eid_mask_sem_filter - Add Event ID mask SEM filter
292142140Snjl *
293142140Snjl * @param p_hwfn -      HW device data
294142140Snjl * @param storm -    Storm to be filtered.
295143902Snjl * @param eid_val -  Event ID value.
296142140Snjl * @param eid_mask - Event ID mask. 0's in the mask = don't care bits.
297142140Snjl *
298142140Snjl * @return error if one of the following holds:
299142140Snjl *	- the specified Storm is invalid
300142140Snjl *	- the specified Storm wasn't enabled
301142140Snjl * Otherwise, returns ok.
302142140Snjl */
303142140Snjlenum dbg_status ecore_dbg_bus_add_eid_mask_sem_filter(struct ecore_hwfn *p_hwfn,
304142140Snjl													  enum dbg_storms storm,
305142140Snjl													  u8 eid_val,
306142140Snjl													  u8 eid_mask);
307143902Snjl
308142140Snjl/**
309142140Snjl * @brief ecore_dbg_bus_add_cid_sem_filter - Adds a CID SEM filter.
310142140Snjl *
311142140Snjl * @param p_hwfn -   HW device data
312142140Snjl * @param storm	- Storm to be filtered.
313142140Snjl * @param cid -   CID to filter on.
314142140Snjl *
315142140Snjl * @return error if one of the following holds:
316142140Snjl *	- the specified Storm is invalid
317142140Snjl *	- the specified Storm wasn't enabled
318143902Snjl * Otherwise, returns ok.
319142140Snjl */
320142140Snjlenum dbg_status ecore_dbg_bus_add_cid_sem_filter(struct ecore_hwfn *p_hwfn,
321142140Snjl												 enum dbg_storms storm,
322142140Snjl												 u32 cid);
323142140Snjl
324142140Snjl/**
325142140Snjl * @brief ecore_dbg_bus_enable_filter - Enables the recording filter.
326142140Snjl *
327142140Snjl * A filter contains up to 4 constraints. The data is "filtered in" when the
328142140Snjl * added constraints hold.
329143902Snjl *
330142140Snjl * @param p_hwfn -		  HW device data
331142140Snjl * @param p_ptt -		  Ptt window used for writing the registers.
332142140Snjl * @param block -	  block to filter on.
333142140Snjl * @param const_msg_len	- Constant message length (in cycles) to be used for
334142140Snjl *			  message-based filter constraints. If set to 0,
335142140Snjl *			  message length is based only on frame bit received
336142140Snjl *			  from HW (no constant message length).
337142140Snjl *
338142140Snjl * @return error if one of the following holds:
339142140Snjl *	- the Debug block wasn't reset since last recording
340143902Snjl *	- the version wasn't set
341142140Snjl *	- the filter was already enabled
342142140Snjl *	- block is not valid or not enabled
343142140Snjl *	- more than 4 dwords are recorded per-cycle (forbids filters)
344142140Snjl * Otherwise, returns ok.
345142140Snjl */
346142140Snjlenum dbg_status ecore_dbg_bus_enable_filter(struct ecore_hwfn *p_hwfn,
347142140Snjl											struct ecore_ptt *p_ptt,
348142140Snjl											enum block_id block,
349142140Snjl											u8 const_msg_len);
350142140Snjl
351143902Snjl/**
352142140Snjl * @brief ecore_dbg_bus_enable_trigger - Enables the recording trigger.
353142140Snjl *
354142140Snjl * A trigger contains up to 3 states, where each state contains up to
355142140Snjl * 4 constraints. After the constraints of a state hold for a specified number
356142140Snjl * of times, the DBG block moves to the next state. If there's no next state,
357142140Snjl * the DBG block triggers.
358142140Snjl *
359142140Snjl * @param p_hwfn -			HW device data
360142140Snjl * @param p_ptt -			Ptt window used for writing the registers.
361143902Snjl * @param rec_pre_trigger -	if true, recording starts before the trigger.
362142140Snjl *				if false, recording starts at the trigger.
363142140Snjl * @param pre_chunks -		max number of chunks to record before the
364142140Snjl *				trigger (1-47). If set to 0, recording starts
365142140Snjl *				from time 0. Ignored if rec_pre_trigger is
366142140Snjl *				false.
367142140Snjl * @param rec_post_trigger -	if true, recording ends after the trigger.
368142140Snjl *				if false, recording ends at the trigger.
369142140Snjl * @param post_cycles -		max number of cycles to record after the
370142140Snjl *				trigger (0x1-0xffffffff). If set to 0,
371143902Snjl *				recording ends only when stopped by the user.
372142140Snjl *				Ignored if rec_post_trigger is false.
373142140Snjl * @param filter_pre_trigger -	if true, data is filtered before the trigger.
374142140Snjl *				Ignored if the filter wasn't enabled.
375142140Snjl * @param filter_post_trigger -	if true, data is filtered after the trigger.
376142140Snjl *				Ignored if the filter wasn't enabled.
377142140Snjl *
378142140Snjl * @return error if one of the following holds:
379142140Snjl *	- the Debug block wasn't reset since last recording
380142140Snjl *	- the version wasn't set
381143902Snjl *	- the trigger was already enabled
382142140Snjl *	- more than 4 dwords are recorded per-cycle (forbids triggers)
383142140Snjl *	- pre_chunks is not in the range 0-47.
384142140Snjl * Otherwise, returns ok.
385142140Snjl */
386142140Snjlenum dbg_status ecore_dbg_bus_enable_trigger(struct ecore_hwfn *p_hwfn,
387142140Snjl											 struct ecore_ptt *p_ptt,
388142140Snjl											 bool rec_pre_trigger,
389142140Snjl											 u8 pre_chunks,
390142140Snjl											 bool rec_post_trigger,
391143902Snjl											 u32 post_cycles,
392142140Snjl											 bool filter_pre_trigger,
393142140Snjl											 bool filter_post_trigger);
394142140Snjl
395142140Snjl/**
396142140Snjl * @brief ecore_dbg_bus_add_trigger_state - Adds a trigger state.
397142140Snjl *
398142140Snjl * Up to 3 trigger states can be added, where each state contains up to
399142140Snjl * 4 constraints. After the constraints of a state hold for the specified
400142140Snjl * number of times, the DBG block moves to the next state. If there's no next
401143902Snjl * state, the DBG block triggers.
402142140Snjl *
403142140Snjl * @param p_hwfn -		  HW device data
404142140Snjl * @param p_ptt -		  Ptt window used for writing the registers.
405142140Snjl * @param block	-	  block to trigger on.
406142140Snjl * @param const_msg_len	- Constant message length (in cycles) to be used for
407142140Snjl *			  message-based filter constraints. If set to 0,
408142140Snjl *			  message length is based only on frame bit received
409142140Snjl *			  from HW (no constant message length).
410142140Snjl * @param count_to_next	- The number of times the constraints of the state
411143902Snjl *			  should hold before moving to the next state. Must be
412142140Snjl *			  non-zero.
413142140Snjl *
414142140Snjl * @return error if one of the following holds:
415142140Snjl *	- The trigger wasn't enabled.
416142140Snjl *	- more than 3 trigger states were added
417142140Snjl *	- block is not valid or not enabled
418142140Snjl *	- count_to_next is 0
419142140Snjl * Otherwise, returns ok.
420142140Snjl */
421143902Snjlenum dbg_status ecore_dbg_bus_add_trigger_state(struct ecore_hwfn *p_hwfn,
422142140Snjl												struct ecore_ptt *p_ptt,
423142140Snjl												enum block_id block,
424142140Snjl												u8 const_msg_len,
425142140Snjl												u16 count_to_next);
426142140Snjl
427142140Snjl/**
428142140Snjl * @brief ecore_dbg_bus_add_constraint - Adds a filter/trigger constraint.
429142140Snjl *
430142140Snjl * The constraint is added to a filter or trigger state, which ever was added
431143902Snjl * last. The filter/trigger happens if both of the following hold:
432142140Snjl * 1. All mandatory constraints are true.
433142140Snjl * 2. At least one optional (non-mandatory) constraints is true.
434142140Snjl *
435142140Snjl * @param p_hwfn -			  HW device data
436142140Snjl * @param p_ptt -			  Ptt window used for writing the registers.
437142140Snjl * @param op -			  constraint operation
438142140Snjl * @param data -		  32-bit data to compare with the recorded
439142140Snjl *				  data.
440143902Snjl * @param data_mask -		  32-bit mask for data comparison. If mask bit
441142140Snjl *				  i is 1, data bit i is compared, otherwise
442142140Snjl *				  it's ignored.
443142140Snjl *				  For eq/ne operations: any mask can be used.
444142140Snjl *				  For other operations: the mask must be
445142140Snjl *				  non-zero, and the 1's in the mask must be
446142140Snjl *				  continuous.
447142140Snjl * @param compare_frame -	  indicates if the frame bit should be
448142140Snjl *				  compared. Must be false for all operations
449143902Snjl *				  other than eq/ne.
450142140Snjl * @param frame_bit -		  frame bit to compare with the recorded data
451142140Snjl *				  (0/1). ignored if compare_frame is false.
452142140Snjl * @param cycle_offset -	  offset in cycles from the beginning of the
453142140Snjl *				  message, where cycle = 4 dwords.
454142140Snjl * @param dword_offset_in_cycle	- offset in dwords from the beginning of the
455142140Snjl *				  cycle (0-3).
456142140Snjl * @param is_mandatory -	  indicates if this constraint is mandatory
457142140Snjl *				  (true) or optional (false). The data is
458143902Snjl *				  filtered-in if all mandatory constraints hold
459142140Snjl *				  AND at least one optional constraint (if
460142140Snjl *				  added) holds.
461142140Snjl *
462142140Snjl * @return error if one of the following holds:
463142140Snjl *	- a filter or trigger state weren't enabled
464142140Snjl *	- all 4 filter constraints were added already
465142140Snjl *	- the op string is invalid
466142140Snjl *	- the data mask is invalid.
467143902Snjl *	- frame bit is not 0/1.
468142140Snjl *	- cycle_offset and dword_offset are not in the range 0-3.
469142140Snjl *	- compare_frame is true and operation is not eq/ne.
470142140Snjl * Otherwise, returns ok.
471142140Snjl */
472142140Snjlenum dbg_status ecore_dbg_bus_add_constraint(struct ecore_hwfn *p_hwfn,
473142140Snjl											 struct ecore_ptt *p_ptt,
474142140Snjl											 enum dbg_bus_constraint_ops constraint_op,
475142140Snjl											 u32 data,
476142140Snjl											 u32 data_mask,
477142140Snjl											 bool compare_frame,
478142140Snjl											 u8 frame_bit,
479143902Snjl											 u8 cycle_offset,
480142140Snjl											 u8 dword_offset_in_cycle,
481142140Snjl											 bool is_mandatory);
482142140Snjl
483142140Snjl/**
484142140Snjl * @brief ecore_dbg_bus_start - Starts the recording.
485142140Snjl *
486142140Snjl * @param p_hwfn - HW device data
487142140Snjl * @param p_ptt - Ptt window used for writing the registers.
488143902Snjl *
489142140Snjl * @return error if one of the following holds:
490142140Snjl *	- the Debug block wasn't reset since last recording
491142140Snjl *	- the version wasn't set
492142140Snjl * Otherwise, returns ok.
493142140Snjl */
494142140Snjlenum dbg_status ecore_dbg_bus_start(struct ecore_hwfn *p_hwfn,
495142140Snjl									struct ecore_ptt *p_ptt);
496142140Snjl
497143902Snjl/**
498142140Snjl * @brief ecore_dbg_bus_stop - Stops the recording and flushes the internal
499142140Snjl * buffer.
500142140Snjl *
501142140Snjl * @param p_hwfn - HW device data
502142140Snjl * @param p_ptt - Ptt window used for writing the registers.
503142140Snjl *
504142140Snjl * @return error if a recording is not in progress, ok otherwise.
505142140Snjl */
506142140Snjlenum dbg_status ecore_dbg_bus_stop(struct ecore_hwfn *p_hwfn,
507142140Snjl								   struct ecore_ptt *p_ptt);
508142140Snjl
509142140Snjl/**
510142140Snjl * @brief ecore_dbg_bus_get_dump_buf_size - Returns the required buffer size
511142140Snjl * for Debug Bus recording.
512142140Snjl *
513142140Snjl * @param p_hwfn -      HW device data
514142140Snjl * @param p_ptt -	     Ptt window used for writing the registers.
515142140Snjl * @param buf_size - OUT: the required size (in dwords) of the buffer for
516142140Snjl *		     dumping the recorded Debug Bus data. If recording to the
517142140Snjl *		     internal buffer, the size of the internal buffer is
518142140Snjl *		     returned. If recording to PCI, the size of the PCI buffer
519142140Snjl *		     is returned. Otherwise, 0 is returned.
520142140Snjl *
521142140Snjl * @return error if one of the following holds:
522142140Snjl *	- the version wasn't set
523142140Snjl * Otherwise, returns ok.
524142140Snjl */
525142140Snjlenum dbg_status ecore_dbg_bus_get_dump_buf_size(struct ecore_hwfn *p_hwfn,
526142140Snjl												struct ecore_ptt *p_ptt,
527142140Snjl												u32 *buf_size);
528142140Snjl
529142140Snjl/**
530142140Snjl * @brief ecore_dbg_bus_dump - Dumps the recorded Debug Bus data into the
531142140Snjl * specified buffer.
532142140Snjl *
533142140Snjl * The dumped data starts with a header. If recording to NW, only a header is
534142140Snjl * dumped. The dumped size is assigned to num_dumped_dwords.
535142140Snjl *
536142140Snjl * @param p_hwfn -			HW device data
537142140Snjl * @param p_ptt -			Ptt window used for writing the registers.
538142140Snjl * @param dump_buf -		Pointer to copy the recorded data into.
539144630Snjl * @param buf_size_in_dwords -	Size of the specified buffer in dwords.
540142140Snjl * @param num_dumped_dwords -	OUT: number of dumped dwords.
541142140Snjl *
542142140Snjl * @return error if one of the following holds:
543143902Snjl *	- a recording wasn't started/stopped
544143902Snjl *	- the specified dump buffer is too small
545143902Snjl * Otherwise, returns ok.
546143902Snjl */
547143902Snjlenum dbg_status ecore_dbg_bus_dump(struct ecore_hwfn *p_hwfn,
548142140Snjl								   struct ecore_ptt *p_ptt,
549142140Snjl								   u32 *dump_buf,
550142140Snjl								   u32 buf_size_in_dwords,
551142140Snjl								   u32 *num_dumped_dwords);
552142140Snjl
553142140Snjl/**
554142140Snjl * @brief ecore_dbg_grc_config - Sets the value of a GRC parameter.
555142140Snjl *
556142140Snjl * @param p_hwfn -		HW device data
557142140Snjl * @param grc_param -	GRC parameter
558142140Snjl * @param val -		Value to set.
559142140Snjl
560142140Snjl * @return error if one of the following holds:
561142140Snjl *	- the version wasn't set
562142140Snjl *	- grc_param is invalid
563142140Snjl *	- val is outside the allowed boundaries
564142140Snjl */
565144630Snjlenum dbg_status ecore_dbg_grc_config(struct ecore_hwfn *p_hwfn,
566144630Snjl									 enum dbg_grc_params grc_param,
567144630Snjl									 u32 val);
568144630Snjl
569142140Snjl/**
570142140Snjl* @brief ecore_dbg_grc_set_params_default - Reverts all GRC parameters to their
571142140Snjl* default value.
572142140Snjl*
573142140Snjl* @param p_hwfn - HW device data
574142140Snjl*/
575142140Snjlvoid ecore_dbg_grc_set_params_default(struct ecore_hwfn *p_hwfn);
576142140Snjl
577142140Snjl/**
578142140Snjl * @brief ecore_dbg_grc_get_dump_buf_size - Returns the required buffer size
579142140Snjl * for GRC Dump.
580142140Snjl *
581144630Snjl * @param p_hwfn -      HW device data
582144630Snjl * @param p_ptt -	     Ptt window used for writing the registers.
583144630Snjl * @param buf_size - OUT: required buffer size (in dwords) for GRC Dump data.
584144630Snjl *
585144630Snjl * @return error if one of the following holds:
586144630Snjl *	- the version wasn't set
587144630Snjl * Otherwise, returns ok.
588144630Snjl */
589144630Snjlenum dbg_status ecore_dbg_grc_get_dump_buf_size(struct ecore_hwfn *p_hwfn,
590142140Snjl												struct ecore_ptt *p_ptt,
591142140Snjl												u32 *buf_size);
592142140Snjl
593144630Snjl/**
594142140Snjl * @brief ecore_dbg_grc_dump - Dumps GRC data into the specified buffer.
595142140Snjl *
596142140Snjl * @param p_hwfn -			HW device data
597142140Snjl * @param p_ptt -			Ptt window used for writing the registers.
598142140Snjl * @param dump_buf -		Pointer to write the collected GRC data into.
599142140Snjl * @param buf_size_in_dwords -	Size of the specified buffer in dwords.
600142140Snjl * @param num_dumped_dwords -	OUT: number of dumped dwords.
601142140Snjl *
602142140Snjl * @return error if one of the following holds:
603142140Snjl *	- the version wasn't set
604142140Snjl *	- the specified dump buffer is too small
605142140Snjl * Otherwise, returns ok.
606142140Snjl */
607142140Snjlenum dbg_status ecore_dbg_grc_dump(struct ecore_hwfn *p_hwfn,
608142140Snjl								   struct ecore_ptt *p_ptt,
609142625Snjl								   u32 *dump_buf,
610142625Snjl								   u32 buf_size_in_dwords,
611142625Snjl								   u32 *num_dumped_dwords);
612142625Snjl
613144630Snjl/**
614144630Snjl * @brief ecore_dbg_idle_chk_get_dump_buf_size - Returns the required buffer
615142140Snjl * size for idle check results.
616142140Snjl *
617142140Snjl * @param p_hwfn -      HW device data
618142140Snjl * @param p_ptt -      Ptt window used for writing the registers.
619142140Snjl * @param buf_size - OUT: required buffer size (in dwords) for idle check data.
620142140Snjl *
621142140Snjl * @return error if one of the following holds:
622142140Snjl *	- the version wasn't set
623142140Snjl * Otherwise, returns ok.
624142203Snjl */
625142203Snjlenum dbg_status ecore_dbg_idle_chk_get_dump_buf_size(struct ecore_hwfn *p_hwfn,
626142203Snjl													 struct ecore_ptt *p_ptt,
627142140Snjl													 u32 *buf_size);
628142140Snjl
629142140Snjl/**
630142140Snjl * @brief ecore_dbg_idle_chk_dump - Performs idle check and writes the results
631142140Snjl * into the specified buffer.
632142140Snjl *
633142140Snjl * @param p_hwfn -			HW device data
634142140Snjl * @param p_ptt -			Ptt window used for writing the registers.
635142140Snjl * @param dump_buf -		Pointer to write the idle check data into.
636142140Snjl * @param buf_size_in_dwords -	Size of the specified buffer in dwords.
637142140Snjl * @param num_dumped_dwords -	OUT: number of dumped dwords.
638142140Snjl *
639142140Snjl * @return error if one of the following holds:
640142140Snjl *	- the version wasn't set
641142140Snjl *	- the specified buffer is too small
642142140Snjl * Otherwise, returns ok.
643143902Snjl */
644143902Snjlenum dbg_status ecore_dbg_idle_chk_dump(struct ecore_hwfn *p_hwfn,
645142140Snjl										struct ecore_ptt *p_ptt,
646142140Snjl										u32 *dump_buf,
647142140Snjl										u32 buf_size_in_dwords,
648142140Snjl										u32 *num_dumped_dwords);
649142140Snjl
650142140Snjl/**
651142140Snjl * @brief ecore_dbg_mcp_trace_get_dump_buf_size - Returns the required buffer
652142140Snjl * size for mcp trace results.
653142140Snjl *
654142140Snjl * @param p_hwfn -	     HW device data
655142140Snjl * @param p_ptt -	     Ptt window used for writing the registers.
656142140Snjl * @param buf_size - OUT: required buffer size (in dwords) for mcp trace data.
657142140Snjl *
658142140Snjl * @return error if one of the following holds:
659142140Snjl *	- the version wasn't set
660142140Snjl *	- the trace data in MCP scratchpad contain an invalid signature
661142140Snjl *	- the bundle ID in NVRAM is invalid
662142140Snjl *	- the trace meta data cannot be found (in NVRAM or image file)
663142140Snjl * Otherwise, returns ok.
664142140Snjl */
665143902Snjlenum dbg_status ecore_dbg_mcp_trace_get_dump_buf_size(struct ecore_hwfn *p_hwfn,
666143902Snjl													  struct ecore_ptt *p_ptt,
667143902Snjl													  u32 *buf_size);
668143902Snjl
669143902Snjl/**
670142140Snjl * @brief ecore_dbg_mcp_trace_dump - Performs mcp trace and writes the results
671142140Snjl * into the specified buffer.
672142140Snjl *
673142140Snjl * @param p_hwfn -			HW device data
674142140Snjl * @param p_ptt -			Ptt window used for writing the registers.
675142140Snjl * @param dump_buf -		Pointer to write the mcp trace data into.
676142140Snjl * @param buf_size_in_dwords -	Size of the specified buffer in dwords.
677143902Snjl * @param num_dumped_dwords -	OUT: number of dumped dwords.
678143902Snjl *
679143902Snjl * @return error if one of the following holds:
680143902Snjl *	- the version wasn't set
681143902Snjl *	- the specified buffer is too small
682142140Snjl *	- the trace data in MCP scratchpad contain an invalid signature
683142140Snjl *	- the bundle ID in NVRAM is invalid
684142140Snjl *	- the trace meta data cannot be found (in NVRAM or image file)
685143902Snjl *	- the trace meta data cannot be read (from NVRAM or image file)
686143902Snjl * Otherwise, returns ok.
687143902Snjl */
688143902Snjlenum dbg_status ecore_dbg_mcp_trace_dump(struct ecore_hwfn *p_hwfn,
689143902Snjl										 struct ecore_ptt *p_ptt,
690143902Snjl										 u32 *dump_buf,
691143902Snjl										 u32 buf_size_in_dwords,
692142140Snjl										 u32 *num_dumped_dwords);
693143902Snjl
694142140Snjl/**
695143902Snjl * @brief ecore_dbg_reg_fifo_get_dump_buf_size - Returns the required buffer
696143902Snjl * size for grc trace fifo results.
697143902Snjl *
698143902Snjl * @param p_hwfn -      HW device data
699143902Snjl * @param p_ptt -      Ptt window used for writing the registers.
700143902Snjl * @param buf_size - OUT: required buffer size (in dwords) for reg fifo data.
701143902Snjl *
702143902Snjl * @return error if one of the following holds:
703143902Snjl *	- the version wasn't set
704143902Snjl * Otherwise, returns ok.
705143902Snjl */
706143902Snjlenum dbg_status ecore_dbg_reg_fifo_get_dump_buf_size(struct ecore_hwfn *p_hwfn,
707143902Snjl													 struct ecore_ptt *p_ptt,
708148583Scperciva													 u32 *buf_size);
709143902Snjl
710143902Snjl/**
711143902Snjl * @brief ecore_dbg_reg_fifo_dump - Reads the reg fifo and writes the results
712143902Snjl * into the specified buffer.
713143902Snjl *
714143902Snjl * @param p_hwfn -			HW device data
715143902Snjl * @param p_ptt -			Ptt window used for writing the registers.
716143902Snjl * @param dump_buf -		Pointer to write the reg fifo data into.
717143902Snjl * @param buf_size_in_dwords -	Size of the specified buffer in dwords.
718143902Snjl * @param num_dumped_dwords -	OUT: number of dumped dwords.
719143902Snjl *
720143902Snjl * @return error if one of the following holds:
721143902Snjl *	- the version wasn't set
722143902Snjl *	- the specified buffer is too small
723143902Snjl *	- DMAE transaction failed
724143902Snjl * Otherwise, returns ok.
725143902Snjl */
726143902Snjlenum dbg_status ecore_dbg_reg_fifo_dump(struct ecore_hwfn *p_hwfn,
727143902Snjl										struct ecore_ptt *p_ptt,
728143902Snjl										u32 *dump_buf,
729143902Snjl										u32 buf_size_in_dwords,
730143902Snjl										u32 *num_dumped_dwords);
731143902Snjl
732143902Snjl/**
733143902Snjl* @brief ecore_dbg_igu_fifo_get_dump_buf_size - Returns the required buffer
734143902Snjl* size for the IGU fifo results.
735143902Snjl*
736143902Snjl* @param p_hwfn -      HW device data
737143902Snjl* @param p_ptt -      Ptt window used for writing the registers.
738143902Snjl* @param buf_size - OUT: required buffer size (in dwords) for IGU fifo data.
739144881Snjl*
740143902Snjl* @return error if one of the following holds:
741143902Snjl*	- the version wasn't set
742143902Snjl* Otherwise, returns ok.
743143902Snjl*/
744143902Snjlenum dbg_status ecore_dbg_igu_fifo_get_dump_buf_size(struct ecore_hwfn *p_hwfn,
745143902Snjl													 struct ecore_ptt *p_ptt,
746144881Snjl													 u32 *buf_size);
747144881Snjl
748143902Snjl/**
749143902Snjl* @brief ecore_dbg_igu_fifo_dump - Reads the IGU fifo and writes the results
750143902Snjl* into the specified buffer.
751143902Snjl*
752143902Snjl* @param p_hwfn -			HW device data
753143902Snjl* @param p_ptt -			Ptt window used for writing the registers.
754143902Snjl* @param dump_buf -		Pointer to write the IGU fifo data into.
755144881Snjl* @param buf_size_in_dwords -	Size of the specified buffer in dwords.
756144881Snjl* @param num_dumped_dwords -	OUT: number of dumped dwords.
757144881Snjl*
758143902Snjl* @return error if one of the following holds:
759143902Snjl*	- the version wasn't set
760143902Snjl*	- the specified buffer is too small
761143902Snjl*	- DMAE transaction failed
762143902Snjl* Otherwise, returns ok.
763143902Snjl*/
764143902Snjlenum dbg_status ecore_dbg_igu_fifo_dump(struct ecore_hwfn *p_hwfn,
765143902Snjl										struct ecore_ptt *p_ptt,
766143902Snjl										u32 *dump_buf,
767143902Snjl										u32 buf_size_in_dwords,
768143902Snjl										u32 *num_dumped_dwords);
769143902Snjl
770143902Snjl/**
771143902Snjl * @brief ecore_dbg_protection_override_get_dump_buf_size - Return the required
772143902Snjl * buffer size for protection override window results.
773143902Snjl *
774142140Snjl * @param p_hwfn -      HW device data
775142140Snjl * @param p_ptt -      Ptt window used for writing the registers.
776142140Snjl * @param buf_size - OUT: required buffer size (in dwords) for protection
777142140Snjl *		     override data.
778142140Snjl *
779143902Snjl * @return error if one of the following holds:
780142140Snjl *	- the version wasn't set
781142140Snjl * Otherwise, returns ok.
782142140Snjl */
783142140Snjlenum dbg_status ecore_dbg_protection_override_get_dump_buf_size(struct ecore_hwfn *p_hwfn,
784142140Snjl																struct ecore_ptt *p_ptt,
785142140Snjl																u32 *buf_size);
786142140Snjl/**
787143902Snjl * @brief ecore_dbg_protection_override_dump - Reads protection override window
788143902Snjl * entries and writes the results into the specified buffer.
789142140Snjl *
790143902Snjl * @param p_hwfn -			HW device data
791142140Snjl * @param p_ptt -			Ptt window used for writing the registers.
792142140Snjl * @param dump_buf -		Pointer to write the protection override data
793142140Snjl *				into.
794142140Snjl * @param buf_size_in_dwords -	Size of the specified buffer in dwords.
795142140Snjl * @param num_dumped_dwords -	OUT: number of dumped dwords.
796143902Snjl *
797143902Snjl * @return error if one of the following holds:
798142140Snjl *	- the version wasn't set
799143902Snjl *	- the specified buffer is too small
800142140Snjl *	- DMAE transaction failed
801142140Snjl * Otherwise, returns ok.
802142140Snjl */
803142140Snjlenum dbg_status ecore_dbg_protection_override_dump(struct ecore_hwfn *p_hwfn,
804142140Snjl												   struct ecore_ptt *p_ptt,
805142140Snjl												   u32 *dump_buf,
806142140Snjl												   u32 buf_size_in_dwords,
807142140Snjl												   u32 *num_dumped_dwords);
808142140Snjl
809142140Snjl/**
810142140Snjl* @brief ecore_dbg_fw_asserts_get_dump_buf_size - Returns the required buffer
811142140Snjl* size for FW Asserts results.
812142140Snjl*
813142140Snjl* @param p_hwfn -	    HW device data
814142140Snjl* @param p_ptt -	    Ptt window used for writing the registers.
815142140Snjl* @param buf_size - OUT: required buffer size (in dwords) for FW Asserts data.
816142140Snjl*
817142140Snjl* @return error if one of the following holds:
818142140Snjl*	- the version wasn't set
819142140Snjl* Otherwise, returns ok.
820142140Snjl*/
821142140Snjlenum dbg_status ecore_dbg_fw_asserts_get_dump_buf_size(struct ecore_hwfn *p_hwfn,
822142140Snjl													   struct ecore_ptt *p_ptt,
823143902Snjl													   u32 *buf_size);
824142140Snjl
825142140Snjl/**
826142140Snjl* @brief ecore_dbg_fw_asserts_dump - Reads the FW Asserts and writes the
827142140Snjl* results into the specified buffer.
828142140Snjl*
829142140Snjl* @param p_hwfn -			HW device data
830142140Snjl* @param p_ptt -			Ptt window used for writing the registers.
831142394Snjl* @param dump_buf -		Pointer to write the FW Asserts data into.
832142140Snjl* @param buf_size_in_dwords -	Size of the specified buffer in dwords.
833142140Snjl* @param num_dumped_dwords -	OUT: number of dumped dwords.
834143902Snjl*
835142140Snjl* @return error if one of the following holds:
836142140Snjl*	- the version wasn't set
837142140Snjl*	- the specified buffer is too small
838142394Snjl* Otherwise, returns ok.
839142140Snjl*/
840142140Snjlenum dbg_status ecore_dbg_fw_asserts_dump(struct ecore_hwfn *p_hwfn,
841142140Snjl										  struct ecore_ptt *p_ptt,
842142140Snjl										  u32 *dump_buf,
843142140Snjl										  u32 buf_size_in_dwords,
844142140Snjl										  u32 *num_dumped_dwords);
845142140Snjl
846142140Snjl/**
847143902Snjl* @brief ecore_dbg_read_attn - Reads the attention registers of the specified
848142140Snjl* block and type, and writes the results into the specified buffer.
849142140Snjl*
850142140Snjl* @param p_hwfn -		HW device data
851142140Snjl* @param p_ptt -		Ptt window used for writing the registers.
852142140Snjl* @param block -	Block ID.
853142140Snjl* @param attn_type -	Attention type.
854142140Snjl* @param clear_status -	Indicates if the attention status should be cleared.
855142140Snjl* @param results -	OUT: Pointer to write the read results into
856142140Snjl*
857142140Snjl* @return error if one of the following holds:
858142140Snjl*	- the version wasn't set
859142140Snjl* Otherwise, returns ok.
860142140Snjl*/
861142140Snjlenum dbg_status ecore_dbg_read_attn(struct ecore_hwfn *p_hwfn,
862142140Snjl									struct ecore_ptt *p_ptt,
863142140Snjl									enum block_id block,
864142394Snjl									enum dbg_attn_type attn_type,
865142140Snjl									bool clear_status,
866142140Snjl									struct dbg_attn_block_result *results);
867142140Snjl
868142140Snjl/**
869142140Snjl* @brief ecore_dbg_print_attn - Prints attention registers values in the
870142140Snjl* specified results struct.
871142140Snjl*
872142140Snjl* @param p_hwfn -     HW device data
873142140Snjl* @param results - Pointer to the attention read results
874143902Snjl*
875142140Snjl* @return error if one of the following holds:
876142140Snjl*	- the version wasn't set
877142140Snjl* Otherwise, returns ok.
878142140Snjl*/
879142140Snjlenum dbg_status ecore_dbg_print_attn(struct ecore_hwfn *p_hwfn,
880142140Snjl									 struct dbg_attn_block_result *results);
881142140Snjl
882142140Snjl/**
883143902Snjl* @brief ecore_is_block_in_reset - Returns true if the specified block is in
884142140Snjl* reset, false otherwise.
885142140Snjl*
886142140Snjl* @param p_hwfn   - HW device data
887142140Snjl* @param p_ptt   - Ptt window used for writing the registers.
888142140Snjl* @param block - Block ID.
889142140Snjl*
890142140Snjl* @return true if the specified block is in reset, false otherwise.
891142140Snjl*/
892142140Snjlbool ecore_is_block_in_reset(struct ecore_hwfn *p_hwfn,
893142140Snjl							 struct ecore_ptt *p_ptt,
894142140Snjl							 enum block_id block);
895142140Snjl
896142140Snjl
897142140Snjl#endif
898142140Snjl