1*14b24e2bSVaishali Kulkarni /*
2*14b24e2bSVaishali Kulkarni * CDDL HEADER START
3*14b24e2bSVaishali Kulkarni *
4*14b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the
5*14b24e2bSVaishali Kulkarni * Common Development and Distribution License, v.1,  (the "License").
6*14b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License.
7*14b24e2bSVaishali Kulkarni *
8*14b24e2bSVaishali Kulkarni * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*14b24e2bSVaishali Kulkarni * or http://opensource.org/licenses/CDDL-1.0.
10*14b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions
11*14b24e2bSVaishali Kulkarni * and limitations under the License.
12*14b24e2bSVaishali Kulkarni *
13*14b24e2bSVaishali Kulkarni * When distributing Covered Code, include this CDDL HEADER in each
14*14b24e2bSVaishali Kulkarni * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*14b24e2bSVaishali Kulkarni * If applicable, add the following below this CDDL HEADER, with the
16*14b24e2bSVaishali Kulkarni * fields enclosed by brackets "[]" replaced with your own identifying
17*14b24e2bSVaishali Kulkarni * information: Portions Copyright [yyyy] [name of copyright owner]
18*14b24e2bSVaishali Kulkarni *
19*14b24e2bSVaishali Kulkarni * CDDL HEADER END
20*14b24e2bSVaishali Kulkarni */
21*14b24e2bSVaishali Kulkarni 
22*14b24e2bSVaishali Kulkarni /*
23*14b24e2bSVaishali Kulkarni * Copyright 2014-2017 Cavium, Inc.
24*14b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the Common Development
25*14b24e2bSVaishali Kulkarni * and Distribution License, v.1,  (the "License").
26*14b24e2bSVaishali Kulkarni 
27*14b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License.
28*14b24e2bSVaishali Kulkarni 
29*14b24e2bSVaishali Kulkarni * You can obtain a copy of the License at available
30*14b24e2bSVaishali Kulkarni * at http://opensource.org/licenses/CDDL-1.0
31*14b24e2bSVaishali Kulkarni 
32*14b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions and
33*14b24e2bSVaishali Kulkarni * limitations under the License.
34*14b24e2bSVaishali Kulkarni */
35*14b24e2bSVaishali Kulkarni 
36*14b24e2bSVaishali Kulkarni #ifndef __ECORE_HW_H__
37*14b24e2bSVaishali Kulkarni #define __ECORE_HW_H__
38*14b24e2bSVaishali Kulkarni 
39*14b24e2bSVaishali Kulkarni #include "ecore.h"
40*14b24e2bSVaishali Kulkarni #include "ecore_dev_api.h"
41*14b24e2bSVaishali Kulkarni 
42*14b24e2bSVaishali Kulkarni /* Forward decleration */
43*14b24e2bSVaishali Kulkarni struct ecore_ptt;
44*14b24e2bSVaishali Kulkarni 
45*14b24e2bSVaishali Kulkarni enum reserved_ptts {
46*14b24e2bSVaishali Kulkarni 	RESERVED_PTT_EDIAG,
47*14b24e2bSVaishali Kulkarni 	RESERVED_PTT_USER_SPACE,
48*14b24e2bSVaishali Kulkarni 	RESERVED_PTT_MAIN,
49*14b24e2bSVaishali Kulkarni 	RESERVED_PTT_DPC,
50*14b24e2bSVaishali Kulkarni 	RESERVED_PTT_MAX
51*14b24e2bSVaishali Kulkarni };
52*14b24e2bSVaishali Kulkarni 
53*14b24e2bSVaishali Kulkarni /* @@@TMP - in earlier versions of the emulation, the HW lock started from 1
54*14b24e2bSVaishali Kulkarni  * instead of 0, this should be fixed in later HW versions.
55*14b24e2bSVaishali Kulkarni  */
56*14b24e2bSVaishali Kulkarni #ifndef MISC_REG_DRIVER_CONTROL_0
57*14b24e2bSVaishali Kulkarni #define MISC_REG_DRIVER_CONTROL_0	MISC_REG_DRIVER_CONTROL_1
58*14b24e2bSVaishali Kulkarni #endif
59*14b24e2bSVaishali Kulkarni #ifndef MISC_REG_DRIVER_CONTROL_0_SIZE
61*14b24e2bSVaishali Kulkarni #endif
62*14b24e2bSVaishali Kulkarni 
63*14b24e2bSVaishali Kulkarni enum _dmae_cmd_dst_mask {
64*14b24e2bSVaishali Kulkarni 	DMAE_CMD_DST_MASK_NONE = 0,
65*14b24e2bSVaishali Kulkarni 	DMAE_CMD_DST_MASK_PCIE = 1,
66*14b24e2bSVaishali Kulkarni 	DMAE_CMD_DST_MASK_GRC = 2
67*14b24e2bSVaishali Kulkarni };
68*14b24e2bSVaishali Kulkarni 
69*14b24e2bSVaishali Kulkarni enum _dmae_cmd_src_mask {
70*14b24e2bSVaishali Kulkarni 	DMAE_CMD_SRC_MASK_PCIE = 0,
71*14b24e2bSVaishali Kulkarni 	DMAE_CMD_SRC_MASK_GRC = 1
72*14b24e2bSVaishali Kulkarni };
73*14b24e2bSVaishali Kulkarni 
74*14b24e2bSVaishali Kulkarni enum _dmae_cmd_crc_mask {
75*14b24e2bSVaishali Kulkarni 	DMAE_CMD_COMP_CRC_EN_MASK_NONE = 0,
76*14b24e2bSVaishali Kulkarni 	DMAE_CMD_COMP_CRC_EN_MASK_SET = 1
77*14b24e2bSVaishali Kulkarni };
78*14b24e2bSVaishali Kulkarni 
79*14b24e2bSVaishali Kulkarni /* definitions for DMA constants */
80*14b24e2bSVaishali Kulkarni #define DMAE_GO_VALUE	0x1
81*14b24e2bSVaishali Kulkarni 
82*14b24e2bSVaishali Kulkarni #ifdef __BIG_ENDIAN
83*14b24e2bSVaishali Kulkarni #define DMAE_COMPLETION_VAL	0xAED10000
84*14b24e2bSVaishali Kulkarni #define DMAE_CMD_ENDIANITY	0x3
85*14b24e2bSVaishali Kulkarni #else
86*14b24e2bSVaishali Kulkarni #define DMAE_COMPLETION_VAL	0xD1AE
87*14b24e2bSVaishali Kulkarni #define DMAE_CMD_ENDIANITY	0x2
88*14b24e2bSVaishali Kulkarni #endif
89*14b24e2bSVaishali Kulkarni 
90*14b24e2bSVaishali Kulkarni #define DMAE_CMD_SIZE	14
91*14b24e2bSVaishali Kulkarni /* size of DMAE command structure to fill.. DMAE_CMD_SIZE-5 */
92*14b24e2bSVaishali Kulkarni #define DMAE_CMD_SIZE_TO_FILL	(DMAE_CMD_SIZE - 5)
93*14b24e2bSVaishali Kulkarni /* Minimum wait for dmae opertaion to complete 2 milliseconds */
94*14b24e2bSVaishali Kulkarni #define DMAE_MIN_WAIT_TIME	0x2
95*14b24e2bSVaishali Kulkarni #define DMAE_MAX_CLIENTS	32
96*14b24e2bSVaishali Kulkarni 
97*14b24e2bSVaishali Kulkarni /**
98*14b24e2bSVaishali Kulkarni * @brief ecore_gtt_init - Initialize GTT windows
99*14b24e2bSVaishali Kulkarni *
100*14b24e2bSVaishali Kulkarni * @param p_hwfn
101*14b24e2bSVaishali Kulkarni */
102*14b24e2bSVaishali Kulkarni void ecore_gtt_init(struct ecore_hwfn *p_hwfn);
103*14b24e2bSVaishali Kulkarni 
104*14b24e2bSVaishali Kulkarni /**
105*14b24e2bSVaishali Kulkarni  * @brief ecore_ptt_invalidate - Forces all ptt entries to be re-configured
106*14b24e2bSVaishali Kulkarni  *
107*14b24e2bSVaishali Kulkarni  * @param p_hwfn
108*14b24e2bSVaishali Kulkarni  */
109*14b24e2bSVaishali Kulkarni void ecore_ptt_invalidate(struct ecore_hwfn *p_hwfn);
110*14b24e2bSVaishali Kulkarni 
111*14b24e2bSVaishali Kulkarni /**
112*14b24e2bSVaishali Kulkarni  * @brief ecore_ptt_pool_alloc - Allocate and initialize PTT pool
113*14b24e2bSVaishali Kulkarni  *
114*14b24e2bSVaishali Kulkarni  * @param p_hwfn
115*14b24e2bSVaishali Kulkarni  *
116*14b24e2bSVaishali Kulkarni  * @return _ecore_status_t - success (0), negative - error.
117*14b24e2bSVaishali Kulkarni  */
118*14b24e2bSVaishali Kulkarni enum _ecore_status_t ecore_ptt_pool_alloc(struct ecore_hwfn *p_hwfn);
119*14b24e2bSVaishali Kulkarni 
120*14b24e2bSVaishali Kulkarni /**
121*14b24e2bSVaishali Kulkarni  * @brief ecore_ptt_pool_free -
122*14b24e2bSVaishali Kulkarni  *
123*14b24e2bSVaishali Kulkarni  * @param p_hwfn
124*14b24e2bSVaishali Kulkarni  */
125*14b24e2bSVaishali Kulkarni void ecore_ptt_pool_free(struct ecore_hwfn *p_hwfn);
126*14b24e2bSVaishali Kulkarni 
127*14b24e2bSVaishali Kulkarni /**
128*14b24e2bSVaishali Kulkarni  * @brief ecore_ptt_get_hw_addr - Get PTT's GRC/HW address
129*14b24e2bSVaishali Kulkarni  *
130*14b24e2bSVaishali Kulkarni  * @param p_hwfn
131*14b24e2bSVaishali Kulkarni  * @param p_ptt
132*14b24e2bSVaishali Kulkarni  *
133*14b24e2bSVaishali Kulkarni  * @return u32
134*14b24e2bSVaishali Kulkarni  */
135*14b24e2bSVaishali Kulkarni u32 ecore_ptt_get_hw_addr(struct ecore_hwfn	*p_hwfn,
136*14b24e2bSVaishali Kulkarni 			  struct ecore_ptt	*p_ptt);
137*14b24e2bSVaishali Kulkarni 
138*14b24e2bSVaishali Kulkarni /**
139*14b24e2bSVaishali Kulkarni  * @brief ecore_ptt_get_bar_addr - Get PPT's external BAR address
140*14b24e2bSVaishali Kulkarni  *
141*14b24e2bSVaishali Kulkarni  * @param p_hwfn
142*14b24e2bSVaishali Kulkarni  * @param p_ptt
143*14b24e2bSVaishali Kulkarni  *
144*14b24e2bSVaishali Kulkarni  * @return u32
145*14b24e2bSVaishali Kulkarni  */
146*14b24e2bSVaishali Kulkarni u32 ecore_ptt_get_bar_addr(struct ecore_ptt	*p_ptt);
147*14b24e2bSVaishali Kulkarni 
148*14b24e2bSVaishali Kulkarni /**
149*14b24e2bSVaishali Kulkarni  * @brief ecore_ptt_set_win - Set PTT Window's GRC BAR address
150*14b24e2bSVaishali Kulkarni  *
151*14b24e2bSVaishali Kulkarni  * @param p_hwfn
152*14b24e2bSVaishali Kulkarni  * @param new_hw_addr
153*14b24e2bSVaishali Kulkarni  * @param p_ptt
154*14b24e2bSVaishali Kulkarni  */
155*14b24e2bSVaishali Kulkarni void ecore_ptt_set_win(struct ecore_hwfn	*p_hwfn,
156*14b24e2bSVaishali Kulkarni 		       struct ecore_ptt		*p_ptt,
157*14b24e2bSVaishali Kulkarni 		       u32			new_hw_addr);
158*14b24e2bSVaishali Kulkarni 
159*14b24e2bSVaishali Kulkarni /**
160*14b24e2bSVaishali Kulkarni  * @brief ecore_get_reserved_ptt - Get a specific reserved PTT
161*14b24e2bSVaishali Kulkarni  *
162*14b24e2bSVaishali Kulkarni  * @param p_hwfn
163*14b24e2bSVaishali Kulkarni  * @param ptt_idx
164*14b24e2bSVaishali Kulkarni  *
165*14b24e2bSVaishali Kulkarni  * @return struct ecore_ptt *
166*14b24e2bSVaishali Kulkarni  */
167*14b24e2bSVaishali Kulkarni struct ecore_ptt *ecore_get_reserved_ptt(struct ecore_hwfn	*p_hwfn,
168*14b24e2bSVaishali Kulkarni 					 enum reserved_ptts	ptt_idx);
169*14b24e2bSVaishali Kulkarni 
170*14b24e2bSVaishali Kulkarni /**
171*14b24e2bSVaishali Kulkarni  * @brief ecore_wr - Write value to BAR using the given ptt
172*14b24e2bSVaishali Kulkarni  *
173*14b24e2bSVaishali Kulkarni  * @param p_hwfn
174*14b24e2bSVaishali Kulkarni  * @param p_ptt
175*14b24e2bSVaishali Kulkarni  * @param val
176*14b24e2bSVaishali Kulkarni  * @param hw_addr
177*14b24e2bSVaishali Kulkarni  */
178*14b24e2bSVaishali Kulkarni void ecore_wr(struct ecore_hwfn	*p_hwfn,
179*14b24e2bSVaishali Kulkarni 	      struct ecore_ptt	*p_ptt,
180*14b24e2bSVaishali Kulkarni 	      u32		hw_addr,
181*14b24e2bSVaishali Kulkarni 	      u32		val);
182*14b24e2bSVaishali Kulkarni 
183*14b24e2bSVaishali Kulkarni /**
184*14b24e2bSVaishali Kulkarni  * @brief ecore_rd - Read value from BAR using the given ptt
185*14b24e2bSVaishali Kulkarni  *
186*14b24e2bSVaishali Kulkarni  * @param p_hwfn
187*14b24e2bSVaishali Kulkarni  * @param p_ptt
188*14b24e2bSVaishali Kulkarni  * @param val
189*14b24e2bSVaishali Kulkarni  * @param hw_addr
190*14b24e2bSVaishali Kulkarni  */
191*14b24e2bSVaishali Kulkarni u32 ecore_rd(struct ecore_hwfn	*p_hwfn,
192*14b24e2bSVaishali Kulkarni 	     struct ecore_ptt	*p_ptt,
193*14b24e2bSVaishali Kulkarni 	     u32		hw_addr);
194*14b24e2bSVaishali Kulkarni 
195*14b24e2bSVaishali Kulkarni /**
196*14b24e2bSVaishali Kulkarni  * @brief ecore_memcpy_from - copy n bytes from BAR using the given
197*14b24e2bSVaishali Kulkarni  *        ptt
198*14b24e2bSVaishali Kulkarni  *
199*14b24e2bSVaishali Kulkarni  * @param p_hwfn
200*14b24e2bSVaishali Kulkarni  * @param p_ptt
201*14b24e2bSVaishali Kulkarni  * @param dest
202*14b24e2bSVaishali Kulkarni  * @param hw_addr
203*14b24e2bSVaishali Kulkarni  * @param n
204*14b24e2bSVaishali Kulkarni  */
205*14b24e2bSVaishali Kulkarni void ecore_memcpy_from(struct ecore_hwfn	*p_hwfn,
206*14b24e2bSVaishali Kulkarni 		       struct ecore_ptt		*p_ptt,
207*14b24e2bSVaishali Kulkarni 		       void			*dest,
208*14b24e2bSVaishali Kulkarni 		       u32			hw_addr,
209*14b24e2bSVaishali Kulkarni 		       osal_size_t		n);
210*14b24e2bSVaishali Kulkarni 
211*14b24e2bSVaishali Kulkarni /**
212*14b24e2bSVaishali Kulkarni  * @brief ecore_memcpy_to - copy n bytes to BAR using the given
213*14b24e2bSVaishali Kulkarni  *        ptt
214*14b24e2bSVaishali Kulkarni  *
215*14b24e2bSVaishali Kulkarni  * @param p_hwfn
216*14b24e2bSVaishali Kulkarni  * @param p_ptt
217*14b24e2bSVaishali Kulkarni  * @param hw_addr
218*14b24e2bSVaishali Kulkarni  * @param src
219*14b24e2bSVaishali Kulkarni  * @param n
220*14b24e2bSVaishali Kulkarni  */
221*14b24e2bSVaishali Kulkarni void ecore_memcpy_to(struct ecore_hwfn	*p_hwfn,
222*14b24e2bSVaishali Kulkarni 		     struct ecore_ptt	*p_ptt,
223*14b24e2bSVaishali Kulkarni 		     u32		hw_addr,
224*14b24e2bSVaishali Kulkarni 		     void		*src,
225*14b24e2bSVaishali Kulkarni 		     osal_size_t	n);
226*14b24e2bSVaishali Kulkarni /**
227*14b24e2bSVaishali Kulkarni  * @brief ecore_fid_pretend - pretend to another function when
228*14b24e2bSVaishali Kulkarni  *        accessing the ptt window. There is no way to unpretend
229*14b24e2bSVaishali Kulkarni  *        a function. The only way to cancel a pretend is to
230*14b24e2bSVaishali Kulkarni  *        pretend back to the original function.
231*14b24e2bSVaishali Kulkarni  *
232*14b24e2bSVaishali Kulkarni  * @param p_hwfn
233*14b24e2bSVaishali Kulkarni  * @param p_ptt
234*14b24e2bSVaishali Kulkarni  * @param fid - fid field of pxp_pretend structure. Can contain
235*14b24e2bSVaishali Kulkarni  *            either pf / vf, port/path fields are don't care.
236*14b24e2bSVaishali Kulkarni  */
237*14b24e2bSVaishali Kulkarni void ecore_fid_pretend(struct ecore_hwfn	*p_hwfn,
238*14b24e2bSVaishali Kulkarni 		       struct ecore_ptt		*p_ptt,
239*14b24e2bSVaishali Kulkarni 		       u16			fid);
240*14b24e2bSVaishali Kulkarni 
241*14b24e2bSVaishali Kulkarni /**
242*14b24e2bSVaishali Kulkarni  * @brief ecore_port_pretend - pretend to another port when
243*14b24e2bSVaishali Kulkarni  *        accessing the ptt window
244*14b24e2bSVaishali Kulkarni  *
245*14b24e2bSVaishali Kulkarni  * @param p_hwfn
246*14b24e2bSVaishali Kulkarni  * @param p_ptt
247*14b24e2bSVaishali Kulkarni  * @param port_id - the port to pretend to
248*14b24e2bSVaishali Kulkarni  */
249*14b24e2bSVaishali Kulkarni void ecore_port_pretend(struct ecore_hwfn	*p_hwfn,
250*14b24e2bSVaishali Kulkarni 			struct ecore_ptt	*p_ptt,
251*14b24e2bSVaishali Kulkarni 			u8			port_id);
252*14b24e2bSVaishali Kulkarni 
253*14b24e2bSVaishali Kulkarni /**
254*14b24e2bSVaishali Kulkarni  * @brief ecore_port_unpretend - cancel any previously set port
255*14b24e2bSVaishali Kulkarni  *        pretend
256*14b24e2bSVaishali Kulkarni  *
257*14b24e2bSVaishali Kulkarni  * @param p_hwfn
258*14b24e2bSVaishali Kulkarni  * @param p_ptt
259*14b24e2bSVaishali Kulkarni  */
260*14b24e2bSVaishali Kulkarni void ecore_port_unpretend(struct ecore_hwfn	*p_hwfn,
261*14b24e2bSVaishali Kulkarni 			  struct ecore_ptt	*p_ptt);
262*14b24e2bSVaishali Kulkarni 
263*14b24e2bSVaishali Kulkarni /**
264*14b24e2bSVaishali Kulkarni  * @brief ecore_vfid_to_concrete - build a concrete FID for a
265*14b24e2bSVaishali Kulkarni  *        given VF ID
266*14b24e2bSVaishali Kulkarni  *
267*14b24e2bSVaishali Kulkarni  * @param p_hwfn
268*14b24e2bSVaishali Kulkarni  * @param p_ptt
269*14b24e2bSVaishali Kulkarni  * @param vfid
270*14b24e2bSVaishali Kulkarni  */
271*14b24e2bSVaishali Kulkarni u32 ecore_vfid_to_concrete(struct ecore_hwfn *p_hwfn, u8 vfid);
272*14b24e2bSVaishali Kulkarni 
273*14b24e2bSVaishali Kulkarni /**
274*14b24e2bSVaishali Kulkarni * @brief ecore_dmae_info_alloc - Init the dmae_info structure
275*14b24e2bSVaishali Kulkarni * which is part of p_hwfn.
276*14b24e2bSVaishali Kulkarni * @param p_hwfn
277*14b24e2bSVaishali Kulkarni */
278*14b24e2bSVaishali Kulkarni enum _ecore_status_t ecore_dmae_info_alloc(struct ecore_hwfn	*p_hwfn);
279*14b24e2bSVaishali Kulkarni 
280*14b24e2bSVaishali Kulkarni /**
281*14b24e2bSVaishali Kulkarni * @brief ecore_dmae_info_free - Free the dmae_info structure
282*14b24e2bSVaishali Kulkarni * which is part of p_hwfn
283*14b24e2bSVaishali Kulkarni *
284*14b24e2bSVaishali Kulkarni * @param p_hwfn
285*14b24e2bSVaishali Kulkarni */
286*14b24e2bSVaishali Kulkarni void ecore_dmae_info_free(struct ecore_hwfn	*p_hwfn);
287*14b24e2bSVaishali Kulkarni 
288*14b24e2bSVaishali Kulkarni union ecore_qm_pq_params {
289*14b24e2bSVaishali Kulkarni 	struct {
290*14b24e2bSVaishali Kulkarni 		u8 q_idx;
291*14b24e2bSVaishali Kulkarni 	} iscsi;
292*14b24e2bSVaishali Kulkarni 
293*14b24e2bSVaishali Kulkarni 	struct {
294*14b24e2bSVaishali Kulkarni 		u8 tc;
295*14b24e2bSVaishali Kulkarni 	} core;
296*14b24e2bSVaishali Kulkarni 
297*14b24e2bSVaishali Kulkarni 	struct {
298*14b24e2bSVaishali Kulkarni 		u8 is_vf;
299*14b24e2bSVaishali Kulkarni 		u8 vf_id;
300*14b24e2bSVaishali Kulkarni 		u8 tc;
301*14b24e2bSVaishali Kulkarni 	} eth;
302*14b24e2bSVaishali Kulkarni 
303*14b24e2bSVaishali Kulkarni 	struct {
304*14b24e2bSVaishali Kulkarni 		u8 dcqcn;
305*14b24e2bSVaishali Kulkarni 		u8 qpid; /* roce relative */
306*14b24e2bSVaishali Kulkarni 	} roce;
307*14b24e2bSVaishali Kulkarni 
308*14b24e2bSVaishali Kulkarni 	struct {
309*14b24e2bSVaishali Kulkarni 		u8 qidx;
310*14b24e2bSVaishali Kulkarni 	} iwarp;
311*14b24e2bSVaishali Kulkarni };
312*14b24e2bSVaishali Kulkarni 
313*14b24e2bSVaishali Kulkarni u16 ecore_get_qm_pq(struct ecore_hwfn	*p_hwfn,
314*14b24e2bSVaishali Kulkarni 		    enum protocol_type	proto,
315*14b24e2bSVaishali Kulkarni 		    union ecore_qm_pq_params *params);
316*14b24e2bSVaishali Kulkarni 
317*14b24e2bSVaishali Kulkarni enum _ecore_status_t ecore_init_fw_data(struct ecore_dev *p_dev,
318*14b24e2bSVaishali Kulkarni 					const u8 *fw_data);
319*14b24e2bSVaishali Kulkarni 
320*14b24e2bSVaishali Kulkarni void ecore_hw_err_notify(struct ecore_hwfn *p_hwfn,
321*14b24e2bSVaishali Kulkarni 			 enum ecore_hw_err_type err_type);
322*14b24e2bSVaishali Kulkarni 
323*14b24e2bSVaishali Kulkarni #endif /* __ECORE_HW_H__ */