xref: /illumos-gate/usr/src/uts/common/io/xge/hal/xgehal/xgehal-mgmt.c (revision a23fd118e437af0a7877dd313db8fdaa3537c675)
1*a23fd118Syl /*
2*a23fd118Syl  * CDDL HEADER START
3*a23fd118Syl  *
4*a23fd118Syl  * The contents of this file are subject to the terms of the
5*a23fd118Syl  * Common Development and Distribution License (the "License").
6*a23fd118Syl  * You may not use this file except in compliance with the License.
7*a23fd118Syl  *
8*a23fd118Syl  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*a23fd118Syl  * or http://www.opensolaris.org/os/licensing.
10*a23fd118Syl  * See the License for the specific language governing permissions
11*a23fd118Syl  * and limitations under the License.
12*a23fd118Syl  *
13*a23fd118Syl  * When distributing Covered Code, include this CDDL HEADER in each
14*a23fd118Syl  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*a23fd118Syl  * If applicable, add the following below this CDDL HEADER, with the
16*a23fd118Syl  * fields enclosed by brackets "[]" replaced with your own identifying
17*a23fd118Syl  * information: Portions Copyright [yyyy] [name of copyright owner]
18*a23fd118Syl  *
19*a23fd118Syl  * CDDL HEADER END
20*a23fd118Syl  */
21*a23fd118Syl 
22*a23fd118Syl /*
23*a23fd118Syl  *  Copyright (c) 2002-2005 Neterion, Inc.
24*a23fd118Syl  *  All right Reserved.
25*a23fd118Syl  *
26*a23fd118Syl  *  FileName :    xgehal-mgmt.c
27*a23fd118Syl  *
28*a23fd118Syl  *  Description:  Xframe-family management facility implementation
29*a23fd118Syl  *
30*a23fd118Syl  *  Created:      1 September 2004
31*a23fd118Syl  */
32*a23fd118Syl 
33*a23fd118Syl #include "xgehal-mgmt.h"
34*a23fd118Syl #include "xgehal-driver.h"
35*a23fd118Syl #include "xgehal-device.h"
36*a23fd118Syl 
37*a23fd118Syl /**
38*a23fd118Syl  * xge_hal_mgmt_about - Retrieve about info.
39*a23fd118Syl  * @devh: HAL device handle.
40*a23fd118Syl  * @about_info: Filled in by HAL. See xge_hal_mgmt_about_info_t{}.
41*a23fd118Syl  * @size: Size of the @about_info buffer. HAL will return error if the
42*a23fd118Syl  *        size is smaller than sizeof(xge_hal_mgmt_about_info_t).
43*a23fd118Syl  *
44*a23fd118Syl  * Retrieve information such as PCI device and vendor IDs, board
45*a23fd118Syl  * revision number, HAL version number, etc.
46*a23fd118Syl  *
47*a23fd118Syl  * Returns: XGE_HAL_OK - success;
48*a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
49*a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
50*a23fd118Syl  * XGE_HAL_FAIL - Failed to retrieve the information.
51*a23fd118Syl  *
52*a23fd118Syl  * See also: xge_hal_mgmt_about_info_t{}.
53*a23fd118Syl  */
54*a23fd118Syl xge_hal_status_e
55*a23fd118Syl xge_hal_mgmt_about(xge_hal_device_h devh, xge_hal_mgmt_about_info_t *about_info,
56*a23fd118Syl 		int size)
57*a23fd118Syl {
58*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
59*a23fd118Syl 
60*a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
61*a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
62*a23fd118Syl 	}
63*a23fd118Syl 
64*a23fd118Syl 	if (size != sizeof(xge_hal_mgmt_about_info_t)) {
65*a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
66*a23fd118Syl 	}
67*a23fd118Syl 
68*a23fd118Syl 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
69*a23fd118Syl 		xge_offsetof(xge_hal_pci_config_le_t, vendor_id),
70*a23fd118Syl 		&about_info->vendor);
71*a23fd118Syl 
72*a23fd118Syl 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
73*a23fd118Syl 		xge_offsetof(xge_hal_pci_config_le_t, device_id),
74*a23fd118Syl 		&about_info->device);
75*a23fd118Syl 
76*a23fd118Syl 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
77*a23fd118Syl 		xge_offsetof(xge_hal_pci_config_le_t, subsystem_vendor_id),
78*a23fd118Syl 		&about_info->subsys_vendor);
79*a23fd118Syl 
80*a23fd118Syl 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
81*a23fd118Syl 		xge_offsetof(xge_hal_pci_config_le_t, subsystem_id),
82*a23fd118Syl 		&about_info->subsys_device);
83*a23fd118Syl 
84*a23fd118Syl 	xge_os_pci_read8(hldev->pdev, hldev->cfgh,
85*a23fd118Syl 		xge_offsetof(xge_hal_pci_config_le_t, revision),
86*a23fd118Syl 		&about_info->board_rev);
87*a23fd118Syl 
88*a23fd118Syl 	xge_os_strcpy(about_info->vendor_name, XGE_DRIVER_VENDOR);
89*a23fd118Syl 	xge_os_strcpy(about_info->chip_name, XGE_CHIP_FAMILY);
90*a23fd118Syl 	xge_os_strcpy(about_info->media, XGE_SUPPORTED_MEDIA_0);
91*a23fd118Syl 
92*a23fd118Syl 	xge_os_strcpy(about_info->hal_major, XGE_HAL_VERSION_MAJOR);
93*a23fd118Syl 	xge_os_strcpy(about_info->hal_minor, XGE_HAL_VERSION_MINOR);
94*a23fd118Syl 	xge_os_strcpy(about_info->hal_fix,   XGE_HAL_VERSION_FIX);
95*a23fd118Syl 	xge_os_strcpy(about_info->hal_build, XGE_HAL_VERSION_BUILD);
96*a23fd118Syl 
97*a23fd118Syl 	xge_os_strcpy(about_info->ll_major, XGELL_VERSION_MAJOR);
98*a23fd118Syl 	xge_os_strcpy(about_info->ll_minor, XGELL_VERSION_MINOR);
99*a23fd118Syl 	xge_os_strcpy(about_info->ll_fix,   XGELL_VERSION_FIX);
100*a23fd118Syl 	xge_os_strcpy(about_info->ll_build, XGELL_VERSION_BUILD);
101*a23fd118Syl 
102*a23fd118Syl 	return XGE_HAL_OK;
103*a23fd118Syl }
104*a23fd118Syl 
105*a23fd118Syl /**
106*a23fd118Syl  * xge_hal_mgmt_reg_read - Read Xframe register.
107*a23fd118Syl  * @devh: HAL device handle.
108*a23fd118Syl  * @bar_id: 0 - for BAR0, 1- for BAR1.
109*a23fd118Syl  * @offset: Register offset in the Base Address Register (BAR) space.
110*a23fd118Syl  * @value: Register value. Returned by HAL.
111*a23fd118Syl  * Read Xframe register.
112*a23fd118Syl  *
113*a23fd118Syl  * Returns: XGE_HAL_OK - success.
114*a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
115*a23fd118Syl  * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
116*a23fd118Syl  * valid.
117*a23fd118Syl  * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
118*a23fd118Syl  *
119*a23fd118Syl  * See also: xge_hal_aux_bar0_read(), xge_hal_aux_bar1_read().
120*a23fd118Syl  */
121*a23fd118Syl xge_hal_status_e
122*a23fd118Syl xge_hal_mgmt_reg_read(xge_hal_device_h devh, int bar_id, unsigned int offset,
123*a23fd118Syl 		u64 *value)
124*a23fd118Syl {
125*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
126*a23fd118Syl 
127*a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
128*a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
129*a23fd118Syl 	}
130*a23fd118Syl 
131*a23fd118Syl 	if (bar_id == 0) {
132*a23fd118Syl 		if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
133*a23fd118Syl 			return XGE_HAL_ERR_INVALID_OFFSET;
134*a23fd118Syl 		}
135*a23fd118Syl 		*value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
136*a23fd118Syl 					     (void *)(hldev->bar0 + offset));
137*a23fd118Syl 	} else if (bar_id == 1) {
138*a23fd118Syl 		int i;
139*a23fd118Syl 		for (i=0; i<XGE_HAL_MAX_FIFO_NUM; i++) {
140*a23fd118Syl 			if (offset == i*0x2000 || offset == i*0x2000+0x18) {
141*a23fd118Syl 				break;
142*a23fd118Syl 			}
143*a23fd118Syl 		}
144*a23fd118Syl 		if (i == XGE_HAL_MAX_FIFO_NUM) {
145*a23fd118Syl 			return XGE_HAL_ERR_INVALID_OFFSET;
146*a23fd118Syl 		}
147*a23fd118Syl 		*value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh1,
148*a23fd118Syl 					     (void *)(hldev->bar1 + offset));
149*a23fd118Syl 	} else {
150*a23fd118Syl 		return XGE_HAL_ERR_INVALID_BAR_ID;
151*a23fd118Syl 	}
152*a23fd118Syl 
153*a23fd118Syl 	return XGE_HAL_OK;
154*a23fd118Syl }
155*a23fd118Syl 
156*a23fd118Syl /**
157*a23fd118Syl  * xge_hal_mgmt_reg_write - Write Xframe register.
158*a23fd118Syl  * @devh: HAL device handle.
159*a23fd118Syl  * @bar_id: 0 - for BAR0, 1- for BAR1.
160*a23fd118Syl  * @offset: Register offset in the Base Address Register (BAR) space.
161*a23fd118Syl  * @value: Register value.
162*a23fd118Syl  *
163*a23fd118Syl  * Write Xframe register.
164*a23fd118Syl  *
165*a23fd118Syl  * Returns: XGE_HAL_OK - success.
166*a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
167*a23fd118Syl  * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
168*a23fd118Syl  * valid.
169*a23fd118Syl  * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
170*a23fd118Syl  *
171*a23fd118Syl  * See also: xge_hal_aux_bar0_write().
172*a23fd118Syl  */
173*a23fd118Syl xge_hal_status_e
174*a23fd118Syl xge_hal_mgmt_reg_write(xge_hal_device_h devh, int bar_id, unsigned int offset,
175*a23fd118Syl 		u64 value)
176*a23fd118Syl {
177*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
178*a23fd118Syl 
179*a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
180*a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
181*a23fd118Syl 	}
182*a23fd118Syl 
183*a23fd118Syl 	if (bar_id == 0) {
184*a23fd118Syl 		if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
185*a23fd118Syl 			return XGE_HAL_ERR_INVALID_OFFSET;
186*a23fd118Syl 		}
187*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, value,
188*a23fd118Syl 				     (void *)(hldev->bar0 + offset));
189*a23fd118Syl 	} else if (bar_id == 1) {
190*a23fd118Syl 		int i;
191*a23fd118Syl 		for (i=0; i<XGE_HAL_MAX_FIFO_NUM; i++) {
192*a23fd118Syl 			if (offset == i*0x2000 || offset == i*0x2000+0x18) {
193*a23fd118Syl 				break;
194*a23fd118Syl 			}
195*a23fd118Syl 		}
196*a23fd118Syl 		if (i == XGE_HAL_MAX_FIFO_NUM) {
197*a23fd118Syl 			return XGE_HAL_ERR_INVALID_OFFSET;
198*a23fd118Syl 		}
199*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh1, value,
200*a23fd118Syl 				     (void *)(hldev->bar1 + offset));
201*a23fd118Syl 	} else {
202*a23fd118Syl 		return XGE_HAL_ERR_INVALID_BAR_ID;
203*a23fd118Syl 	}
204*a23fd118Syl 
205*a23fd118Syl 	return XGE_HAL_OK;
206*a23fd118Syl }
207*a23fd118Syl 
208*a23fd118Syl /**
209*a23fd118Syl  * xge_hal_mgmt_hw_stats - Get Xframe hardware statistics.
210*a23fd118Syl  * @devh: HAL device handle.
211*a23fd118Syl  * @hw_stats: Hardware statistics. Returned by HAL.
212*a23fd118Syl  *            See xge_hal_stats_hw_info_t{}.
213*a23fd118Syl  * @size: Size of the @hw_stats buffer. HAL will return an error
214*a23fd118Syl  * if the size is smaller than sizeof(xge_hal_stats_hw_info_t).
215*a23fd118Syl  * Get Xframe hardware statistics.
216*a23fd118Syl  *
217*a23fd118Syl  * Returns: XGE_HAL_OK - success.
218*a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
219*a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
220*a23fd118Syl  *
221*a23fd118Syl  * See also: xge_hal_mgmt_sw_stats().
222*a23fd118Syl  */
223*a23fd118Syl xge_hal_status_e
224*a23fd118Syl xge_hal_mgmt_hw_stats(xge_hal_device_h devh, xge_hal_mgmt_hw_stats_t *hw_stats,
225*a23fd118Syl 		int size)
226*a23fd118Syl {
227*a23fd118Syl 	xge_hal_status_e status;
228*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
229*a23fd118Syl 	xge_hal_stats_hw_info_t	*hw_info;
230*a23fd118Syl 
231*a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
232*a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
233*a23fd118Syl 	}
234*a23fd118Syl 
235*a23fd118Syl 	if (size != sizeof(xge_hal_stats_hw_info_t)) {
236*a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
237*a23fd118Syl 	}
238*a23fd118Syl 
239*a23fd118Syl 	if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
240*a23fd118Syl 		return status;
241*a23fd118Syl 	}
242*a23fd118Syl 
243*a23fd118Syl 	xge_os_memcpy(hw_stats, hw_info, sizeof(xge_hal_stats_hw_info_t));
244*a23fd118Syl 
245*a23fd118Syl 	return XGE_HAL_OK;
246*a23fd118Syl }
247*a23fd118Syl 
248*a23fd118Syl /**
249*a23fd118Syl  * FIXME: document
250*a23fd118Syl  */
251*a23fd118Syl xge_hal_status_e
252*a23fd118Syl xge_hal_mgmt_hw_stats_off(xge_hal_device_h devh, int off, int size, char *out)
253*a23fd118Syl {
254*a23fd118Syl 	xge_hal_status_e status;
255*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
256*a23fd118Syl 	xge_hal_stats_hw_info_t	*hw_info;
257*a23fd118Syl 
258*a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
259*a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
260*a23fd118Syl 	}
261*a23fd118Syl 
262*a23fd118Syl 	if (off > sizeof(xge_hal_stats_hw_info_t)-4 ||
263*a23fd118Syl 	    size > 8) {
264*a23fd118Syl 		return XGE_HAL_ERR_INVALID_OFFSET;
265*a23fd118Syl 	}
266*a23fd118Syl 
267*a23fd118Syl 	if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
268*a23fd118Syl 		return status;
269*a23fd118Syl 	}
270*a23fd118Syl 
271*a23fd118Syl 	xge_os_memcpy(out, (char*)hw_info + off, size);
272*a23fd118Syl 
273*a23fd118Syl 	return XGE_HAL_OK;
274*a23fd118Syl }
275*a23fd118Syl 
276*a23fd118Syl /**
277*a23fd118Syl  * xge_hal_mgmt_sw_stats - Get per-device software statistics.
278*a23fd118Syl  * @devh: HAL device handle.
279*a23fd118Syl  * @sw_stats: Hardware statistics. Returned by HAL.
280*a23fd118Syl  *            See xge_hal_stats_sw_err_t{}.
281*a23fd118Syl  * @size: Size of the @sw_stats buffer. HAL will return an error
282*a23fd118Syl  * if the size is smaller than sizeof(xge_hal_stats_sw_err_t).
283*a23fd118Syl  * Get device software statistics, including ECC and Parity error
284*a23fd118Syl  * counters, etc.
285*a23fd118Syl  *
286*a23fd118Syl  * Returns: XGE_HAL_OK - success.
287*a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
288*a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
289*a23fd118Syl  *
290*a23fd118Syl  * See also: xge_hal_stats_sw_err_t{}, xge_hal_mgmt_hw_stats().
291*a23fd118Syl  */
292*a23fd118Syl xge_hal_status_e
293*a23fd118Syl xge_hal_mgmt_sw_stats(xge_hal_device_h devh, xge_hal_mgmt_sw_stats_t *sw_stats,
294*a23fd118Syl 		int size)
295*a23fd118Syl {
296*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
297*a23fd118Syl 
298*a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
299*a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
300*a23fd118Syl 	}
301*a23fd118Syl 
302*a23fd118Syl 	if (size != sizeof(xge_hal_stats_sw_err_t)) {
303*a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
304*a23fd118Syl 	}
305*a23fd118Syl 
306*a23fd118Syl 	if (!hldev->stats.is_initialized ||
307*a23fd118Syl 	    !hldev->stats.is_enabled) {
308*a23fd118Syl 		return XGE_HAL_INF_STATS_IS_NOT_READY;
309*a23fd118Syl 	}
310*a23fd118Syl 
311*a23fd118Syl 	xge_os_memcpy(sw_stats, &hldev->stats.sw_dev_err_stats,
312*a23fd118Syl 	            sizeof(xge_hal_stats_sw_err_t));
313*a23fd118Syl 
314*a23fd118Syl 	return XGE_HAL_OK;
315*a23fd118Syl }
316*a23fd118Syl 
317*a23fd118Syl /**
318*a23fd118Syl  * xge_hal_mgmt_device_stats - Get HAL device statistics.
319*a23fd118Syl  * @devh: HAL device handle.
320*a23fd118Syl  * @device_stats: HAL device "soft" statistics. Maintained by HAL itself.
321*a23fd118Syl  *            (as opposed to xge_hal_mgmt_hw_stats() - those are
322*a23fd118Syl  *            maintained by the Xframe hardware).
323*a23fd118Syl  *            Returned by HAL.
324*a23fd118Syl  *            See xge_hal_stats_device_info_t{}.
325*a23fd118Syl  * @size: Size of the @device_stats buffer. HAL will return an error
326*a23fd118Syl  * if the size is smaller than sizeof(xge_hal_stats_device_info_t).
327*a23fd118Syl  *
328*a23fd118Syl  * Get HAL (layer) statistic counters.
329*a23fd118Syl  * Returns: XGE_HAL_OK - success.
330*a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
331*a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
332*a23fd118Syl  * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
333*a23fd118Syl  * currently available.
334*a23fd118Syl  *
335*a23fd118Syl  */
336*a23fd118Syl xge_hal_status_e
337*a23fd118Syl xge_hal_mgmt_device_stats(xge_hal_device_h devh,
338*a23fd118Syl 		xge_hal_mgmt_device_stats_t *device_stats, int size)
339*a23fd118Syl {
340*a23fd118Syl 	xge_hal_status_e status;
341*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
342*a23fd118Syl 	xge_hal_stats_device_info_t *device_info;
343*a23fd118Syl 
344*a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
345*a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
346*a23fd118Syl 	}
347*a23fd118Syl 
348*a23fd118Syl 	if (size != sizeof(xge_hal_stats_device_info_t)) {
349*a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
350*a23fd118Syl 	}
351*a23fd118Syl 
352*a23fd118Syl 	if ((status = xge_hal_stats_device (devh, &device_info)) !=
353*a23fd118Syl 	XGE_HAL_OK) {
354*a23fd118Syl 		return status;
355*a23fd118Syl 	}
356*a23fd118Syl 
357*a23fd118Syl 	xge_os_memcpy(device_stats, device_info,
358*a23fd118Syl 		    sizeof(xge_hal_stats_device_info_t));
359*a23fd118Syl 
360*a23fd118Syl 	return XGE_HAL_OK;
361*a23fd118Syl }
362*a23fd118Syl 
363*a23fd118Syl /*
364*a23fd118Syl  * __hal_update_ring_bump - Update the ring bump counter for the
365*a23fd118Syl  * particular channel.
366*a23fd118Syl  * @hldev: HAL device handle.
367*a23fd118Syl  * @queue: the queue who's data is to be collected.
368*a23fd118Syl  * @chinfo: pointer to the statistics structure of the given channel.
369*a23fd118Syl  * Usage: See xge_hal_aux_stats_hal_read{}
370*a23fd118Syl  */
371*a23fd118Syl 
372*a23fd118Syl static void
373*a23fd118Syl __hal_update_ring_bump(xge_hal_device_t *hldev, int queue,
374*a23fd118Syl 	xge_hal_stats_channel_info_t *chinfo)
375*a23fd118Syl {
376*a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
377*a23fd118Syl 	u64 rbc = 0;
378*a23fd118Syl 	int reg = (queue / 4);
379*a23fd118Syl 	void * addr;
380*a23fd118Syl 
381*a23fd118Syl 	addr = (reg == 1)? (&bar0->ring_bump_counter2) :
382*a23fd118Syl 		(&bar0->ring_bump_counter1);
383*a23fd118Syl 	rbc = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, addr);
384*a23fd118Syl 	chinfo->ring_bump_cnt = XGE_HAL_RING_BUMP_CNT(queue, rbc);
385*a23fd118Syl }
386*a23fd118Syl 
387*a23fd118Syl /**
388*a23fd118Syl  * xge_hal_mgmt_channel_stats - Get HAL channel statistics.
389*a23fd118Syl  * @channelh: HAL channel handle.
390*a23fd118Syl  * @channel_stats: HAL channel statistics. Maintained by HAL itself
391*a23fd118Syl  *            (as opposed to xge_hal_mgmt_hw_stats() - those are
392*a23fd118Syl  *            maintained by the Xframe hardware).
393*a23fd118Syl  *            Returned by HAL.
394*a23fd118Syl  *            See xge_hal_stats_channel_info_t{}.
395*a23fd118Syl  * @size: Size of the @channel_stats buffer. HAL will return an error
396*a23fd118Syl  * if the size is smaller than sizeof(xge_hal_mgmt_channel_stats_t).
397*a23fd118Syl  *
398*a23fd118Syl  * Get HAL per-channel statistic counters.
399*a23fd118Syl  *
400*a23fd118Syl  * Returns: XGE_HAL_OK - success.
401*a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
402*a23fd118Syl  * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
403*a23fd118Syl  * currently available.
404*a23fd118Syl  *
405*a23fd118Syl  */
406*a23fd118Syl xge_hal_status_e
407*a23fd118Syl xge_hal_mgmt_channel_stats(xge_hal_channel_h channelh,
408*a23fd118Syl 		xge_hal_mgmt_channel_stats_t *channel_stats, int size)
409*a23fd118Syl {
410*a23fd118Syl 	xge_hal_status_e status;
411*a23fd118Syl 	xge_hal_stats_channel_info_t *channel_info;
412*a23fd118Syl 	xge_hal_channel_t *channel = channelh;
413*a23fd118Syl 
414*a23fd118Syl 	if (size != sizeof(xge_hal_stats_channel_info_t)) {
415*a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
416*a23fd118Syl 	}
417*a23fd118Syl 
418*a23fd118Syl 	if ((status = xge_hal_stats_channel (channelh, &channel_info)) !=
419*a23fd118Syl 								XGE_HAL_OK) {
420*a23fd118Syl 		return status;
421*a23fd118Syl 	}
422*a23fd118Syl 
423*a23fd118Syl 	if (xge_hal_device_check_id(channel->devh) == XGE_HAL_CARD_HERC) {
424*a23fd118Syl 		__hal_update_ring_bump(channel->devh, channel->post_qid,
425*a23fd118Syl 			channel_info);
426*a23fd118Syl 	}
427*a23fd118Syl 
428*a23fd118Syl 	xge_os_memcpy(channel_stats, channel_info,
429*a23fd118Syl 		    sizeof(xge_hal_stats_channel_info_t));
430*a23fd118Syl 
431*a23fd118Syl 	return XGE_HAL_OK;
432*a23fd118Syl }
433*a23fd118Syl 
434*a23fd118Syl /**
435*a23fd118Syl  * xge_hal_mgmt_pcireg_read - Read PCI configuration at a specified
436*a23fd118Syl  * offset.
437*a23fd118Syl  * @devh: HAL device handle.
438*a23fd118Syl  * @offset: Offset in the 256 byte PCI configuration space.
439*a23fd118Syl  * @value_bits: 8, 16, or 32 (bits) to read.
440*a23fd118Syl  * @value: Value returned by HAL.
441*a23fd118Syl  *
442*a23fd118Syl  * Read PCI configuration, given device and offset in the PCI space.
443*a23fd118Syl  *
444*a23fd118Syl  * Returns: XGE_HAL_OK - success.
445*a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
446*a23fd118Syl  * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
447*a23fd118Syl  * valid.
448*a23fd118Syl  * XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE - Invalid bits size. Valid
449*a23fd118Syl  * values(8/16/32).
450*a23fd118Syl  *
451*a23fd118Syl  */
452*a23fd118Syl xge_hal_status_e
453*a23fd118Syl xge_hal_mgmt_pcireg_read(xge_hal_device_h devh, unsigned int offset,
454*a23fd118Syl 		int value_bits, u32 *value)
455*a23fd118Syl {
456*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
457*a23fd118Syl 
458*a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
459*a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
460*a23fd118Syl 	}
461*a23fd118Syl 
462*a23fd118Syl 	if (offset > sizeof(xge_hal_pci_config_t)-value_bits/8) {
463*a23fd118Syl 		return XGE_HAL_ERR_INVALID_OFFSET;
464*a23fd118Syl 	}
465*a23fd118Syl 
466*a23fd118Syl 	if (value_bits == 8) {
467*a23fd118Syl 		xge_os_pci_read8(hldev->pdev, hldev->cfgh, offset, (u8*)value);
468*a23fd118Syl 	} else if (value_bits == 16) {
469*a23fd118Syl 		xge_os_pci_read16(hldev->pdev, hldev->cfgh, offset,
470*a23fd118Syl 		(u16*)value);
471*a23fd118Syl 	} else if (value_bits == 32) {
472*a23fd118Syl 		xge_os_pci_read32(hldev->pdev, hldev->cfgh, offset, value);
473*a23fd118Syl 	} else {
474*a23fd118Syl 		return XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE;
475*a23fd118Syl 	}
476*a23fd118Syl 
477*a23fd118Syl 	return XGE_HAL_OK;
478*a23fd118Syl }
479*a23fd118Syl 
480*a23fd118Syl /**
481*a23fd118Syl  * xge_hal_mgmt_device_config - Retrieve device configuration.
482*a23fd118Syl  * @devh: HAL device handle.
483*a23fd118Syl  * @dev_config: Device configuration, see xge_hal_device_config_t{}.
484*a23fd118Syl  * @size: Size of the @dev_config buffer. HAL will return an error
485*a23fd118Syl  * if the size is smaller than sizeof(xge_hal_mgmt_device_config_t).
486*a23fd118Syl  *
487*a23fd118Syl  * Get device configuration. Permits to retrieve at run-time configuration
488*a23fd118Syl  * values that were used to initialize and configure the device.
489*a23fd118Syl  *
490*a23fd118Syl  * Returns: XGE_HAL_OK - success.
491*a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
492*a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
493*a23fd118Syl  *
494*a23fd118Syl  * See also: xge_hal_device_config_t{}, xge_hal_mgmt_driver_config().
495*a23fd118Syl  */
496*a23fd118Syl xge_hal_status_e
497*a23fd118Syl xge_hal_mgmt_device_config(xge_hal_device_h devh,
498*a23fd118Syl 		xge_hal_mgmt_device_config_t	*dev_config, int size)
499*a23fd118Syl {
500*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
501*a23fd118Syl 
502*a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
503*a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
504*a23fd118Syl 	}
505*a23fd118Syl 
506*a23fd118Syl 	if (size != sizeof(xge_hal_mgmt_device_config_t)) {
507*a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
508*a23fd118Syl 	}
509*a23fd118Syl 
510*a23fd118Syl 	xge_os_memcpy(dev_config, &hldev->config,
511*a23fd118Syl 	sizeof(xge_hal_device_config_t));
512*a23fd118Syl 
513*a23fd118Syl 	return XGE_HAL_OK;
514*a23fd118Syl }
515*a23fd118Syl 
516*a23fd118Syl /**
517*a23fd118Syl  * xge_hal_mgmt_driver_config - Retrieve driver configuration.
518*a23fd118Syl  * @drv_config: Device configuration, see xge_hal_driver_config_t{}.
519*a23fd118Syl  * @size: Size of the @dev_config buffer. HAL will return an error
520*a23fd118Syl  * if the size is smaller than sizeof(xge_hal_mgmt_driver_config_t).
521*a23fd118Syl  *
522*a23fd118Syl  * Get driver configuration. Permits to retrieve at run-time configuration
523*a23fd118Syl  * values that were used to configure the device at load-time.
524*a23fd118Syl  *
525*a23fd118Syl  * Returns: XGE_HAL_OK - success.
526*a23fd118Syl  * XGE_HAL_ERR_DRIVER_NOT_INITIALIZED - HAL is not initialized.
527*a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version is not maching.
528*a23fd118Syl  *
529*a23fd118Syl  * See also: xge_hal_driver_config_t{}, xge_hal_mgmt_device_config().
530*a23fd118Syl  */
531*a23fd118Syl xge_hal_status_e
532*a23fd118Syl xge_hal_mgmt_driver_config(xge_hal_mgmt_driver_config_t *drv_config, int size)
533*a23fd118Syl {
534*a23fd118Syl 
535*a23fd118Syl 	if (g_xge_hal_driver == NULL) {
536*a23fd118Syl 		return XGE_HAL_ERR_DRIVER_NOT_INITIALIZED;
537*a23fd118Syl 	}
538*a23fd118Syl 
539*a23fd118Syl 	if (size != sizeof(xge_hal_mgmt_driver_config_t)) {
540*a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
541*a23fd118Syl 	}
542*a23fd118Syl 
543*a23fd118Syl 	xge_os_memcpy(drv_config, &g_xge_hal_driver->config,
544*a23fd118Syl 		    sizeof(xge_hal_mgmt_driver_config_t));
545*a23fd118Syl 
546*a23fd118Syl 	return XGE_HAL_OK;
547*a23fd118Syl }
548*a23fd118Syl 
549*a23fd118Syl /**
550*a23fd118Syl  * xge_hal_mgmt_pci_config - Retrieve PCI configuration.
551*a23fd118Syl  * @devh: HAL device handle.
552*a23fd118Syl  * @pci_config: 256 byte long buffer for PCI configuration space.
553*a23fd118Syl  * @size: Size of the @ buffer. HAL will return an error
554*a23fd118Syl  * if the size is smaller than sizeof(xge_hal_mgmt_pci_config_t).
555*a23fd118Syl  *
556*a23fd118Syl  * Get PCI configuration. Permits to retrieve at run-time configuration
557*a23fd118Syl  * values that were used to configure the device at load-time.
558*a23fd118Syl  *
559*a23fd118Syl  * Returns: XGE_HAL_OK - success.
560*a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
561*a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
562*a23fd118Syl  *
563*a23fd118Syl  */
564*a23fd118Syl xge_hal_status_e
565*a23fd118Syl xge_hal_mgmt_pci_config(xge_hal_device_h devh,
566*a23fd118Syl 		xge_hal_mgmt_pci_config_t *pci_config, int size)
567*a23fd118Syl {
568*a23fd118Syl 	int i;
569*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
570*a23fd118Syl 
571*a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
572*a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
573*a23fd118Syl 	}
574*a23fd118Syl 
575*a23fd118Syl 	if (size != sizeof(xge_hal_mgmt_pci_config_t)) {
576*a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
577*a23fd118Syl 	}
578*a23fd118Syl 
579*a23fd118Syl 	/* refresh PCI config space */
580*a23fd118Syl 	for (i = 0; i < 0x68/4+1; i++) {
581*a23fd118Syl 		xge_os_pci_read32(hldev->pdev, hldev->cfgh, i*4,
582*a23fd118Syl 		                (u32*)&hldev->pci_config_space + i);
583*a23fd118Syl 	}
584*a23fd118Syl 
585*a23fd118Syl 	xge_os_memcpy(pci_config, &hldev->pci_config_space,
586*a23fd118Syl 		    sizeof(xge_hal_mgmt_pci_config_t));
587*a23fd118Syl 
588*a23fd118Syl 	return XGE_HAL_OK;
589*a23fd118Syl }
590*a23fd118Syl 
591*a23fd118Syl #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
592*a23fd118Syl /**
593*a23fd118Syl  * xge_hal_mgmt_trace_read - Read trace buffer contents.
594*a23fd118Syl  * @buffer: Buffer to store the trace buffer contents.
595*a23fd118Syl  * @buf_size: Size of the buffer.
596*a23fd118Syl  * @offset: Offset in the internal trace buffer to read data.
597*a23fd118Syl  * @read_length: Size of the valid data in the buffer.
598*a23fd118Syl  *
599*a23fd118Syl  * Read  HAL trace buffer contents starting from the offset
600*a23fd118Syl  * upto the size of the buffer or till EOF is reached.
601*a23fd118Syl  *
602*a23fd118Syl  * Returns: XGE_HAL_OK - success.
603*a23fd118Syl  * XGE_HAL_EOF_TRACE_BUF - No more data in the trace buffer.
604*a23fd118Syl  *
605*a23fd118Syl  */
606*a23fd118Syl xge_hal_status_e
607*a23fd118Syl xge_hal_mgmt_trace_read (char		*buffer,
608*a23fd118Syl 			unsigned	buf_size,
609*a23fd118Syl 			unsigned	*offset,
610*a23fd118Syl 			unsigned	*read_length)
611*a23fd118Syl {
612*a23fd118Syl 	int data_offset;
613*a23fd118Syl 	int start_offset;
614*a23fd118Syl 
615*a23fd118Syl 	if ((g_xge_os_tracebuf == NULL) ||
616*a23fd118Syl 		(g_xge_os_tracebuf->offset == g_xge_os_tracebuf->size - 2)) {
617*a23fd118Syl 		return XGE_HAL_EOF_TRACE_BUF;
618*a23fd118Syl 	}
619*a23fd118Syl 
620*a23fd118Syl 	data_offset = g_xge_os_tracebuf->offset + 1;
621*a23fd118Syl 
622*a23fd118Syl 	if  (*offset >= (unsigned)xge_os_strlen(g_xge_os_tracebuf->data +
623*a23fd118Syl 	data_offset)) {
624*a23fd118Syl 
625*a23fd118Syl 		return XGE_HAL_EOF_TRACE_BUF;
626*a23fd118Syl 	}
627*a23fd118Syl 
628*a23fd118Syl 	xge_os_memzero(buffer, buf_size);
629*a23fd118Syl 
630*a23fd118Syl 	start_offset  =  data_offset + *offset;
631*a23fd118Syl 	*read_length = xge_os_strlen(g_xge_os_tracebuf->data +
632*a23fd118Syl 	start_offset);
633*a23fd118Syl 
634*a23fd118Syl 	if (*read_length  >=  buf_size) {
635*a23fd118Syl 		*read_length = buf_size - 1;
636*a23fd118Syl 	}
637*a23fd118Syl 
638*a23fd118Syl 	xge_os_memcpy(buffer, g_xge_os_tracebuf->data + start_offset,
639*a23fd118Syl 	*read_length);
640*a23fd118Syl 
641*a23fd118Syl 	*offset += *read_length;
642*a23fd118Syl 	(*read_length) ++;
643*a23fd118Syl 
644*a23fd118Syl 	return XGE_HAL_OK;
645*a23fd118Syl }
646*a23fd118Syl 
647*a23fd118Syl #endif
648*a23fd118Syl 
649*a23fd118Syl /**
650*a23fd118Syl  * xge_hal_restore_link_led - Restore link LED to its original state.
651*a23fd118Syl  * @devh: HAL device handle.
652*a23fd118Syl  */
653*a23fd118Syl void
654*a23fd118Syl xge_hal_restore_link_led(xge_hal_device_h devh)
655*a23fd118Syl {
656*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
657*a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
658*a23fd118Syl 	u64 val64;
659*a23fd118Syl 
660*a23fd118Syl 	/*
661*a23fd118Syl 	 * If the current link state is UP, switch on LED else make it
662*a23fd118Syl 	 * off.
663*a23fd118Syl 	 */
664*a23fd118Syl 
665*a23fd118Syl 	/*
666*a23fd118Syl 	 * For Xena 3 and lower revision cards, adapter control needs to be
667*a23fd118Syl 	 * used for making LED ON/OFF.
668*a23fd118Syl 	 */
669*a23fd118Syl 	if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
670*a23fd118Syl 	   (xge_hal_device_rev(hldev) <= 3)) {
671*a23fd118Syl 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
672*a23fd118Syl 					      &bar0->adapter_control);
673*a23fd118Syl 		if (hldev->link_state == XGE_HAL_LINK_UP) {
674*a23fd118Syl 			val64 |= XGE_HAL_ADAPTER_LED_ON;
675*a23fd118Syl 		} else {
676*a23fd118Syl 			val64 &= ~XGE_HAL_ADAPTER_LED_ON;
677*a23fd118Syl 		}
678*a23fd118Syl 
679*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
680*a23fd118Syl 					&bar0->adapter_control);
681*a23fd118Syl 		return;
682*a23fd118Syl 	}
683*a23fd118Syl 
684*a23fd118Syl 	/*
685*a23fd118Syl 	 * Use beacon control register to control the LED.
686*a23fd118Syl 	 * LED link output corresponds to bit 8 of the beacon control
687*a23fd118Syl 	 * register. Note that, in the case of Xena, beacon control register
688*a23fd118Syl 	 * represents the gpio control register. In the case of Herc, LED
689*a23fd118Syl 	 * handling is done by beacon control register as opposed to gpio
690*a23fd118Syl 	 * control register in Xena.
691*a23fd118Syl 	 */
692*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
693*a23fd118Syl 				      &bar0->beacon_control);
694*a23fd118Syl 	if (hldev->link_state == XGE_HAL_LINK_UP) {
695*a23fd118Syl 		val64 |= 0x0080800000000000ULL;
696*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
697*a23fd118Syl 				       val64, &bar0->beacon_control);
698*a23fd118Syl 	} else {
699*a23fd118Syl 		val64 |= 0x0000800000000000ULL;
700*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
701*a23fd118Syl 				       val64, &bar0->beacon_control);
702*a23fd118Syl 	}
703*a23fd118Syl }
704*a23fd118Syl 
705*a23fd118Syl /**
706*a23fd118Syl  * xge_hal_flick_link_led - Flick (blink) link LED.
707*a23fd118Syl  * @devh: HAL device handle.
708*a23fd118Syl  *
709*a23fd118Syl  * Depending on the card revision flicker the link LED by using the
710*a23fd118Syl  * beacon control or the adapter_control register.
711*a23fd118Syl  */
712*a23fd118Syl void
713*a23fd118Syl xge_hal_flick_link_led(xge_hal_device_h devh)
714*a23fd118Syl {
715*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
716*a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
717*a23fd118Syl 	u64 val64 = 0;
718*a23fd118Syl 
719*a23fd118Syl 	/*
720*a23fd118Syl 	 * For Xena 3 and lower revision cards, adapter control needs to be
721*a23fd118Syl 	 * used for making LED ON/OFF.
722*a23fd118Syl 	 */
723*a23fd118Syl 	if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
724*a23fd118Syl 	   (xge_hal_device_rev(hldev) <= 3)) {
725*a23fd118Syl 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
726*a23fd118Syl 					      &bar0->adapter_control);
727*a23fd118Syl 		val64 ^= XGE_HAL_ADAPTER_LED_ON;
728*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
729*a23fd118Syl 					&bar0->adapter_control);
730*a23fd118Syl 		return;
731*a23fd118Syl 	}
732*a23fd118Syl 
733*a23fd118Syl 	/*
734*a23fd118Syl 	 * Use beacon control register to control the Link LED.
735*a23fd118Syl 	 * Note that, in the case of Xena, beacon control register represents
736*a23fd118Syl 	 * the gpio control register. In the case of Herc, LED handling is
737*a23fd118Syl 	 * done by beacon control register as opposed to gpio control register
738*a23fd118Syl 	 * in Xena.
739*a23fd118Syl 	 */
740*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
741*a23fd118Syl 				      &bar0->beacon_control);
742*a23fd118Syl 	val64 ^= XGE_HAL_GPIO_CTRL_GPIO_0;
743*a23fd118Syl 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
744*a23fd118Syl 			       &bar0->beacon_control);
745*a23fd118Syl }
746*a23fd118Syl 
747*a23fd118Syl /**
748*a23fd118Syl  * xge_hal_read_eeprom - Read 4 bytes of data from user given offset.
749*a23fd118Syl  * @devh: HAL device handle.
750*a23fd118Syl  * @off: offset at which the data must be written
751*a23fd118Syl  * @data: output parameter where the data is stored.
752*a23fd118Syl  *
753*a23fd118Syl  * Read 4 bytes of data from the user given offset and return the
754*a23fd118Syl  * read data.
755*a23fd118Syl  * Note: will allow to read only part of the EEPROM visible through the
756*a23fd118Syl  * I2C bus.
757*a23fd118Syl  * Returns: -1 on failure, 0 on success.
758*a23fd118Syl  */
759*a23fd118Syl xge_hal_status_e
760*a23fd118Syl xge_hal_read_eeprom(xge_hal_device_h devh, xge_hal_status_e off, u32* data)
761*a23fd118Syl {
762*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
763*a23fd118Syl 	int ret = XGE_HAL_FAIL;
764*a23fd118Syl 	u32 exit_cnt = 0;
765*a23fd118Syl 	u64 val64;
766*a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
767*a23fd118Syl 
768*a23fd118Syl 
769*a23fd118Syl 	val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) |
770*a23fd118Syl 		XGE_HAL_I2C_CONTROL_ADDR(off) |
771*a23fd118Syl 		XGE_HAL_I2C_CONTROL_BYTE_CNT(0x3) |
772*a23fd118Syl 		XGE_HAL_I2C_CONTROL_READ | XGE_HAL_I2C_CONTROL_CNTL_START;
773*a23fd118Syl 
774*a23fd118Syl 	__hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
775*a23fd118Syl 			(u32)val64, &bar0->i2c_control);
776*a23fd118Syl 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
777*a23fd118Syl 			(u32) (val64 >> 32), &bar0->i2c_control);
778*a23fd118Syl 
779*a23fd118Syl 	while (exit_cnt < 5) {
780*a23fd118Syl 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
781*a23fd118Syl 					&bar0->i2c_control);
782*a23fd118Syl 		if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) {
783*a23fd118Syl 			*data = XGE_HAL_I2C_CONTROL_GET_DATA(val64);
784*a23fd118Syl 			ret = XGE_HAL_OK;
785*a23fd118Syl 			break;
786*a23fd118Syl 		}
787*a23fd118Syl 		xge_os_mdelay(50);
788*a23fd118Syl 		exit_cnt++;
789*a23fd118Syl 	}
790*a23fd118Syl 
791*a23fd118Syl 	return ret;
792*a23fd118Syl }
793*a23fd118Syl 
794*a23fd118Syl /*
795*a23fd118Syl  * xge_hal_write_eeprom - actually writes the relevant part of the data
796*a23fd118Syl  value.
797*a23fd118Syl  * @devh: HAL device handle.
798*a23fd118Syl  * @off: offset at which the data must be written
799*a23fd118Syl  * @data : The data that is to be written
800*a23fd118Syl  * @cnt : Number of bytes of the data that are actually to be written into
801*a23fd118Syl  * the Eeprom. (max of 3)
802*a23fd118Syl  *
803*a23fd118Syl  * Actually writes the relevant part of the data value into the Eeprom
804*a23fd118Syl  * through the I2C bus.
805*a23fd118Syl  * Return value:
806*a23fd118Syl  * 0 on success, -1 on failure.
807*a23fd118Syl  */
808*a23fd118Syl 
809*a23fd118Syl xge_hal_status_e
810*a23fd118Syl xge_hal_write_eeprom(xge_hal_device_h devh, int off, u32 data, int cnt)
811*a23fd118Syl {
812*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
813*a23fd118Syl 	int exit_cnt = 0, ret = XGE_HAL_FAIL;
814*a23fd118Syl 	u64 val64;
815*a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
816*a23fd118Syl 
817*a23fd118Syl 	val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) |
818*a23fd118Syl 		XGE_HAL_I2C_CONTROL_ADDR(off) |
819*a23fd118Syl 		XGE_HAL_I2C_CONTROL_BYTE_CNT(cnt) |
820*a23fd118Syl 		XGE_HAL_I2C_CONTROL_SET_DATA(data) |
821*a23fd118Syl 		XGE_HAL_I2C_CONTROL_CNTL_START;
822*a23fd118Syl 	__hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
823*a23fd118Syl 			(u32)val64, &bar0->i2c_control);
824*a23fd118Syl 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
825*a23fd118Syl 			(u32) (val64 >> 32), &bar0->i2c_control);
826*a23fd118Syl 
827*a23fd118Syl 	while (exit_cnt < 5) {
828*a23fd118Syl 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
829*a23fd118Syl 					&bar0->i2c_control);
830*a23fd118Syl 		if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) {
831*a23fd118Syl 			if (!(val64 & XGE_HAL_I2C_CONTROL_NACK))
832*a23fd118Syl 				ret = XGE_HAL_OK;
833*a23fd118Syl 			break;
834*a23fd118Syl 		}
835*a23fd118Syl 		xge_os_mdelay(50);
836*a23fd118Syl 		exit_cnt++;
837*a23fd118Syl 	}
838*a23fd118Syl 
839*a23fd118Syl 	return ret;
840*a23fd118Syl }
841*a23fd118Syl 
842*a23fd118Syl /*
843*a23fd118Syl  * xge_hal_register_test - reads and writes into all clock domains.
844*a23fd118Syl  * @hldev : private member of the device structure.
845*a23fd118Syl  * xge_nic structure.
846*a23fd118Syl  * @data : variable that returns the result of each of the test conducted b
847*a23fd118Syl  * by the driver.
848*a23fd118Syl  *
849*a23fd118Syl  * Read and write into all clock domains. The NIC has 3 clock domains,
850*a23fd118Syl  * see that registers in all the three regions are accessible.
851*a23fd118Syl  * Return value:
852*a23fd118Syl  * 0 on success.
853*a23fd118Syl  */
854*a23fd118Syl xge_hal_status_e
855*a23fd118Syl xge_hal_register_test(xge_hal_device_h devh, u64 *data)
856*a23fd118Syl {
857*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
858*a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
859*a23fd118Syl 	u64 val64 = 0;
860*a23fd118Syl 	int fail = 0;
861*a23fd118Syl 
862*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
863*a23fd118Syl 			&bar0->pif_rd_swapper_fb);
864*a23fd118Syl 	if (val64 != 0x123456789abcdefULL) {
865*a23fd118Syl 		fail = 1;
866*a23fd118Syl 		xge_debug_osdep(XGE_TRACE, "Read Test level 1 fails\n");
867*a23fd118Syl 	}
868*a23fd118Syl 
869*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
870*a23fd118Syl 			&bar0->rmac_pause_cfg);
871*a23fd118Syl 	if (val64 != 0xc000ffff00000000ULL) {
872*a23fd118Syl 		fail = 1;
873*a23fd118Syl 		xge_debug_osdep(XGE_TRACE, "Read Test level 2 fails\n");
874*a23fd118Syl 	}
875*a23fd118Syl 
876*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
877*a23fd118Syl 			&bar0->rx_queue_cfg);
878*a23fd118Syl 	if (val64 != 0x0808080808080808ULL) {
879*a23fd118Syl 		fail = 1;
880*a23fd118Syl 		xge_debug_osdep(XGE_TRACE, "Read Test level 3 fails\n");
881*a23fd118Syl 	}
882*a23fd118Syl 
883*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
884*a23fd118Syl 			&bar0->xgxs_efifo_cfg);
885*a23fd118Syl 	if (val64 != 0x000000001923141EULL) {
886*a23fd118Syl 		fail = 1;
887*a23fd118Syl 		xge_debug_osdep(XGE_TRACE, "Read Test level 4 fails\n");
888*a23fd118Syl 	}
889*a23fd118Syl 
890*a23fd118Syl 	val64 = 0x5A5A5A5A5A5A5A5AULL;
891*a23fd118Syl 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
892*a23fd118Syl 			&bar0->xmsi_data);
893*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
894*a23fd118Syl 			&bar0->xmsi_data);
895*a23fd118Syl 	if (val64 != 0x5A5A5A5A5A5A5A5AULL) {
896*a23fd118Syl 		fail = 1;
897*a23fd118Syl 		xge_debug_osdep(XGE_ERR, "Write Test level 1 fails\n");
898*a23fd118Syl 	}
899*a23fd118Syl 
900*a23fd118Syl 	val64 = 0xA5A5A5A5A5A5A5A5ULL;
901*a23fd118Syl 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
902*a23fd118Syl 			&bar0->xmsi_data);
903*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
904*a23fd118Syl 			&bar0->xmsi_data);
905*a23fd118Syl 	if (val64 != 0xA5A5A5A5A5A5A5A5ULL) {
906*a23fd118Syl 		fail = 1;
907*a23fd118Syl 		xge_debug_osdep(XGE_ERR, "Write Test level 2 fails\n");
908*a23fd118Syl 	}
909*a23fd118Syl 
910*a23fd118Syl 	*data = fail;
911*a23fd118Syl 	return XGE_HAL_OK;
912*a23fd118Syl }
913*a23fd118Syl 
914*a23fd118Syl /*
915*a23fd118Syl  * xge_hal_rldram_test - offline test for access to the RldRam chip on
916*a23fd118Syl  the NIC
917*a23fd118Syl  * @devh: HAL device handle.
918*a23fd118Syl  * @data: variable that returns the result of each of the test
919*a23fd118Syl  * conducted by the driver.
920*a23fd118Syl  *
921*a23fd118Syl  * This is one of the offline test that tests the read and write
922*a23fd118Syl  * access to the RldRam chip on the NIC.
923*a23fd118Syl  * Return value:
924*a23fd118Syl  * 0 on success.
925*a23fd118Syl  */
926*a23fd118Syl xge_hal_status_e
927*a23fd118Syl xge_hal_rldram_test(xge_hal_device_h devh, uint64_t * data)
928*a23fd118Syl {
929*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
930*a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
931*a23fd118Syl 	u64 val64;
932*a23fd118Syl 	int cnt, iteration = 0, test_pass = 0;
933*a23fd118Syl 
934*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
935*a23fd118Syl 			&bar0->adapter_control);
936*a23fd118Syl 	val64 &= ~XGE_HAL_ADAPTER_ECC_EN;
937*a23fd118Syl 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
938*a23fd118Syl 			&bar0->adapter_control);
939*a23fd118Syl 
940*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
941*a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
942*a23fd118Syl 	val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE;
943*a23fd118Syl 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
944*a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
945*a23fd118Syl 
946*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
947*a23fd118Syl 			&bar0->mc_rldram_mrs);
948*a23fd118Syl 	val64 |= XGE_HAL_MC_RLDRAM_QUEUE_SIZE_ENABLE;
949*a23fd118Syl 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
950*a23fd118Syl 			(u32) (val64 >> 32), &bar0->i2c_control);
951*a23fd118Syl 	__hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
952*a23fd118Syl 			(u32)val64, &bar0->mc_rldram_mrs);
953*a23fd118Syl 
954*a23fd118Syl 	val64 |= XGE_HAL_MC_RLDRAM_MRS_ENABLE;
955*a23fd118Syl 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
956*a23fd118Syl 			(u32) (val64 >> 32), &bar0->i2c_control);
957*a23fd118Syl 	__hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
958*a23fd118Syl 			(u32)val64, &bar0->mc_rldram_mrs);
959*a23fd118Syl 
960*a23fd118Syl 	while (iteration < 2) {
961*a23fd118Syl 		val64 = 0x55555555aaaa0000ULL;
962*a23fd118Syl 		if (iteration == 1) {
963*a23fd118Syl 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
964*a23fd118Syl 		}
965*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
966*a23fd118Syl 			&bar0->mc_rldram_test_d0);
967*a23fd118Syl 
968*a23fd118Syl 		val64 = 0xaaaa5a5555550000ULL;
969*a23fd118Syl 		if (iteration == 1) {
970*a23fd118Syl 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
971*a23fd118Syl 		}
972*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
973*a23fd118Syl 			&bar0->mc_rldram_test_d1);
974*a23fd118Syl 
975*a23fd118Syl 		val64 = 0x55aaaaaaaa5a0000ULL;
976*a23fd118Syl 		if (iteration == 1) {
977*a23fd118Syl 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
978*a23fd118Syl 		}
979*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
980*a23fd118Syl 			&bar0->mc_rldram_test_d2);
981*a23fd118Syl 
982*a23fd118Syl 		val64 = (u64) (0x0000003fffff0000ULL);
983*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
984*a23fd118Syl 			&bar0->mc_rldram_test_add);
985*a23fd118Syl 
986*a23fd118Syl 
987*a23fd118Syl 		val64 = XGE_HAL_MC_RLDRAM_TEST_MODE;
988*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
989*a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
990*a23fd118Syl 
991*a23fd118Syl 		val64 |=
992*a23fd118Syl 		    XGE_HAL_MC_RLDRAM_TEST_MODE | XGE_HAL_MC_RLDRAM_TEST_WRITE |
993*a23fd118Syl 		    XGE_HAL_MC_RLDRAM_TEST_GO;
994*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
995*a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
996*a23fd118Syl 
997*a23fd118Syl 		for (cnt = 0; cnt < 5; cnt++) {
998*a23fd118Syl 			val64 = xge_os_pio_mem_read64(hldev->pdev,
999*a23fd118Syl 				hldev->regh0, &bar0->mc_rldram_test_ctrl);
1000*a23fd118Syl 			if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE)
1001*a23fd118Syl 				break;
1002*a23fd118Syl 			xge_os_mdelay(200);
1003*a23fd118Syl 		}
1004*a23fd118Syl 
1005*a23fd118Syl 		if (cnt == 5)
1006*a23fd118Syl 			break;
1007*a23fd118Syl 
1008*a23fd118Syl 		val64 = XGE_HAL_MC_RLDRAM_TEST_MODE;
1009*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1010*a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
1011*a23fd118Syl 
1012*a23fd118Syl 		val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE |
1013*a23fd118Syl 		XGE_HAL_MC_RLDRAM_TEST_GO;
1014*a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1015*a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
1016*a23fd118Syl 
1017*a23fd118Syl 		for (cnt = 0; cnt < 5; cnt++) {
1018*a23fd118Syl 			val64 = xge_os_pio_mem_read64(hldev->pdev,
1019*a23fd118Syl 				hldev->regh0, &bar0->mc_rldram_test_ctrl);
1020*a23fd118Syl 			if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE)
1021*a23fd118Syl 				break;
1022*a23fd118Syl 			xge_os_mdelay(500);
1023*a23fd118Syl 		}
1024*a23fd118Syl 
1025*a23fd118Syl 		if (cnt == 5)
1026*a23fd118Syl 			break;
1027*a23fd118Syl 
1028*a23fd118Syl 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1029*a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
1030*a23fd118Syl 		if (val64 & XGE_HAL_MC_RLDRAM_TEST_PASS)
1031*a23fd118Syl 			test_pass = 1;
1032*a23fd118Syl 
1033*a23fd118Syl 		iteration++;
1034*a23fd118Syl 	}
1035*a23fd118Syl 
1036*a23fd118Syl 	if (!test_pass)
1037*a23fd118Syl 		*data = 1;
1038*a23fd118Syl 	else
1039*a23fd118Syl 		*data = 0;
1040*a23fd118Syl 
1041*a23fd118Syl 	return XGE_HAL_OK;
1042*a23fd118Syl }
1043*a23fd118Syl 
1044*a23fd118Syl /*
1045*a23fd118Syl  * xge_hal_eeprom_test - to verify that EEprom in the xena can be
1046*a23fd118Syl  programmed.
1047*a23fd118Syl  * @devh: HAL device handle.
1048*a23fd118Syl  * @data:variable that returns the result of each of the test conducted by
1049*a23fd118Syl  * the driver.
1050*a23fd118Syl  *
1051*a23fd118Syl  * Verify that EEPROM in the xena can be programmed using I2C_CONTROL
1052*a23fd118Syl  * register.
1053*a23fd118Syl  * Return value:
1054*a23fd118Syl  * 0 on success.
1055*a23fd118Syl  */
1056*a23fd118Syl xge_hal_status_e
1057*a23fd118Syl xge_hal_eeprom_test(xge_hal_device_h devh, u64 *data)
1058*a23fd118Syl {
1059*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1060*a23fd118Syl 	int fail = 0;
1061*a23fd118Syl 	u32 ret_data;
1062*a23fd118Syl 
1063*a23fd118Syl 	/* Test Write Error at offset 0 */
1064*a23fd118Syl 	if (!xge_hal_write_eeprom(hldev, 0, 0, 3))
1065*a23fd118Syl 		fail = 1;
1066*a23fd118Syl 
1067*a23fd118Syl 	/* Test Write at offset 4f0 */
1068*a23fd118Syl 	if (xge_hal_write_eeprom(hldev, 0x4F0, 0x01234567, 3))
1069*a23fd118Syl 		fail = 1;
1070*a23fd118Syl 	if (xge_hal_read_eeprom(hldev, 0x4F0, &ret_data))
1071*a23fd118Syl 		fail = 1;
1072*a23fd118Syl 
1073*a23fd118Syl 	if (ret_data != 0x01234567)
1074*a23fd118Syl 		fail = 1;
1075*a23fd118Syl 
1076*a23fd118Syl 	/* Reset the EEPROM data go FFFF */
1077*a23fd118Syl 	(void) xge_hal_write_eeprom(hldev, 0x4F0, 0xFFFFFFFF, 3);
1078*a23fd118Syl 
1079*a23fd118Syl 	/* Test Write Request Error at offset 0x7c */
1080*a23fd118Syl 	if (!xge_hal_write_eeprom(hldev, 0x07C, 0, 3))
1081*a23fd118Syl 		fail = 1;
1082*a23fd118Syl 
1083*a23fd118Syl 	/* Test Write Request at offset 0x7fc */
1084*a23fd118Syl 	if (xge_hal_write_eeprom(hldev, 0x7FC, 0x01234567, 3))
1085*a23fd118Syl 		fail = 1;
1086*a23fd118Syl 	if (xge_hal_read_eeprom(hldev, 0x7FC, &ret_data))
1087*a23fd118Syl 		fail = 1;
1088*a23fd118Syl 
1089*a23fd118Syl 	if (ret_data != 0x01234567)
1090*a23fd118Syl 		fail = 1;
1091*a23fd118Syl 
1092*a23fd118Syl 	/* Reset the EEPROM data go FFFF */
1093*a23fd118Syl 	(void) xge_hal_write_eeprom(hldev, 0x7FC, 0xFFFFFFFF, 3);
1094*a23fd118Syl 
1095*a23fd118Syl 	/* Test Write Error at offset 0x80 */
1096*a23fd118Syl 	if (!xge_hal_write_eeprom(hldev, 0x080, 0, 3))
1097*a23fd118Syl 		fail = 1;
1098*a23fd118Syl 
1099*a23fd118Syl 	/* Test Write Error at offset 0xfc */
1100*a23fd118Syl 	if (!xge_hal_write_eeprom(hldev, 0x0FC, 0, 3))
1101*a23fd118Syl 		fail = 1;
1102*a23fd118Syl 
1103*a23fd118Syl 	/* Test Write Error at offset 0x100 */
1104*a23fd118Syl 	if (!xge_hal_write_eeprom(hldev, 0x100, 0, 3))
1105*a23fd118Syl 		fail = 1;
1106*a23fd118Syl 
1107*a23fd118Syl 	/* Test Write Error at offset 4ec */
1108*a23fd118Syl 	if (!xge_hal_write_eeprom(hldev, 0x4EC, 0, 3))
1109*a23fd118Syl 		fail = 1;
1110*a23fd118Syl 
1111*a23fd118Syl 	*data = fail;
1112*a23fd118Syl 	return XGE_HAL_OK;
1113*a23fd118Syl }
1114*a23fd118Syl 
1115*a23fd118Syl /*
1116*a23fd118Syl  * xge_hal_bist_test - invokes the MemBist test of the card .
1117*a23fd118Syl  * @devh: HAL device handle.
1118*a23fd118Syl  * xge_nic structure.
1119*a23fd118Syl  * @data:variable that returns the result of each of the test conducted by
1120*a23fd118Syl  * the driver.
1121*a23fd118Syl  *
1122*a23fd118Syl  * This invokes the MemBist test of the card. We give around
1123*a23fd118Syl  * 2 secs time for the Test to complete. If it's still not complete
1124*a23fd118Syl  * within this peiod, we consider that the test failed.
1125*a23fd118Syl  * Return value:
1126*a23fd118Syl  * 0 on success and -1 on failure.
1127*a23fd118Syl  */
1128*a23fd118Syl xge_hal_status_e
1129*a23fd118Syl xge_hal_bist_test(xge_hal_device_h devh, u64 *data)
1130*a23fd118Syl {
1131*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1132*a23fd118Syl 	u8 bist = 0;
1133*a23fd118Syl 	int cnt = 0, ret = XGE_HAL_FAIL;
1134*a23fd118Syl 
1135*a23fd118Syl 	xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist);
1136*a23fd118Syl 	bist |= 0x40;
1137*a23fd118Syl 	xge_os_pci_write8(hldev->pdev, hldev->cfgh, 0x0f, bist);
1138*a23fd118Syl 
1139*a23fd118Syl 	while (cnt < 20) {
1140*a23fd118Syl 		xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist);
1141*a23fd118Syl 		if (!(bist & 0x40)) {
1142*a23fd118Syl 			*data = (bist & 0x0f);
1143*a23fd118Syl 			ret = XGE_HAL_OK;
1144*a23fd118Syl 			break;
1145*a23fd118Syl 		}
1146*a23fd118Syl 		xge_os_mdelay(100);
1147*a23fd118Syl 		cnt++;
1148*a23fd118Syl 	}
1149*a23fd118Syl 
1150*a23fd118Syl 	return ret;
1151*a23fd118Syl }
1152*a23fd118Syl 
1153*a23fd118Syl /*
1154*a23fd118Syl  * xge_hal_link_test - verifies the link state of the nic
1155*a23fd118Syl  * @devh: HAL device handle.
1156*a23fd118Syl  * @data: variable that returns the result of each of the test conducted by
1157*a23fd118Syl  * the driver.
1158*a23fd118Syl  *
1159*a23fd118Syl  * Verify the link state of the NIC and updates the input
1160*a23fd118Syl  * argument 'data' appropriately.
1161*a23fd118Syl  * Return value:
1162*a23fd118Syl  * 0 on success.
1163*a23fd118Syl  */
1164*a23fd118Syl xge_hal_status_e
1165*a23fd118Syl xge_hal_link_test(xge_hal_device_h devh, u64 *data)
1166*a23fd118Syl {
1167*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1168*a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1169*a23fd118Syl 	u64 val64;
1170*a23fd118Syl 
1171*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1172*a23fd118Syl 			&bar0->adapter_status);
1173*a23fd118Syl 	if (val64 & XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)
1174*a23fd118Syl 		*data = 1;
1175*a23fd118Syl 
1176*a23fd118Syl 	return XGE_HAL_OK;
1177*a23fd118Syl }
1178*a23fd118Syl 
1179*a23fd118Syl 
1180*a23fd118Syl /**
1181*a23fd118Syl  * xge_hal_getpause_data -Pause frame frame generation and reception.
1182*a23fd118Syl  * @devh: HAL device handle.
1183*a23fd118Syl  * @tx : A field to return the pause generation capability of the NIC.
1184*a23fd118Syl  * @rx : A field to return the pause reception capability of the NIC.
1185*a23fd118Syl  *
1186*a23fd118Syl  * Returns the Pause frame generation and reception capability of the NIC.
1187*a23fd118Syl  * Return value:
1188*a23fd118Syl  *  void
1189*a23fd118Syl  */
1190*a23fd118Syl void xge_hal_getpause_data(xge_hal_device_h devh, int *tx, int *rx)
1191*a23fd118Syl {
1192*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1193*a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1194*a23fd118Syl 	u64 val64;
1195*a23fd118Syl 
1196*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1197*a23fd118Syl 				&bar0->rmac_pause_cfg);
1198*a23fd118Syl 	if (val64 & XGE_HAL_RMAC_PAUSE_GEN_EN)
1199*a23fd118Syl 		*tx = 1;
1200*a23fd118Syl 	if (val64 & XGE_HAL_RMAC_PAUSE_RCV_EN)
1201*a23fd118Syl 		*rx = 1;
1202*a23fd118Syl }
1203*a23fd118Syl 
1204*a23fd118Syl /**
1205*a23fd118Syl  * xge_hal_setpause_data -  set/reset pause frame generation.
1206*a23fd118Syl  * @devh: HAL device handle.
1207*a23fd118Syl  * @tx: A field that indicates the pause generation capability to be
1208*a23fd118Syl  * set on the NIC.
1209*a23fd118Syl  * @rx: A field that indicates the pause reception capability to be
1210*a23fd118Syl  * set on the NIC.
1211*a23fd118Syl  *
1212*a23fd118Syl  * It can be used to set or reset Pause frame generation or reception
1213*a23fd118Syl  * support of the NIC.
1214*a23fd118Syl  * Return value:
1215*a23fd118Syl  * int, returns 0 on Success
1216*a23fd118Syl  */
1217*a23fd118Syl 
1218*a23fd118Syl int xge_hal_setpause_data(xge_hal_device_h devh, int tx, int rx)
1219*a23fd118Syl {
1220*a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1221*a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1222*a23fd118Syl 	u64 val64;
1223*a23fd118Syl 
1224*a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1225*a23fd118Syl 				    &bar0->rmac_pause_cfg);
1226*a23fd118Syl 	if (tx)
1227*a23fd118Syl 		val64 |= XGE_HAL_RMAC_PAUSE_GEN_EN;
1228*a23fd118Syl 	else
1229*a23fd118Syl 		val64 &= ~XGE_HAL_RMAC_PAUSE_GEN_EN;
1230*a23fd118Syl 	if (rx)
1231*a23fd118Syl 		val64 |= XGE_HAL_RMAC_PAUSE_RCV_EN;
1232*a23fd118Syl 	else
1233*a23fd118Syl 		val64 &= ~XGE_HAL_RMAC_PAUSE_RCV_EN;
1234*a23fd118Syl 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1235*a23fd118Syl 			     val64, &bar0->rmac_pause_cfg);
1236*a23fd118Syl 	return 0;
1237*a23fd118Syl }
1238*a23fd118Syl 
1239