1a23fd11yl/*
2a23fd11yl * CDDL HEADER START
3a23fd11yl *
4a23fd11yl * The contents of this file are subject to the terms of the
5a23fd11yl * Common Development and Distribution License (the "License").
6a23fd11yl * You may not use this file except in compliance with the License.
7a23fd11yl *
8a23fd11yl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9a23fd11yl * or http://www.opensolaris.org/os/licensing.
10a23fd11yl * See the License for the specific language governing permissions
11a23fd11yl * and limitations under the License.
12a23fd11yl *
13a23fd11yl * When distributing Covered Code, include this CDDL HEADER in each
14a23fd11yl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15a23fd11yl * If applicable, add the following below this CDDL HEADER, with the
16a23fd11yl * fields enclosed by brackets "[]" replaced with your own identifying
17a23fd11yl * information: Portions Copyright [yyyy] [name of copyright owner]
18a23fd11yl *
19a23fd11yl * CDDL HEADER END
20a23fd11yl *
218347601yl * Copyright (c) 2002-2006 Neterion, Inc.
22a23fd11yl */
23a23fd11yl
24a23fd11yl#include "xgehal-mgmt.h"
25a23fd11yl#include "xgehal-driver.h"
26a23fd11yl#include "xgehal-device.h"
27a23fd11yl
28a23fd11yl/**
29a23fd11yl * xge_hal_mgmt_about - Retrieve about info.
30a23fd11yl * @devh: HAL device handle.
31a23fd11yl * @about_info: Filled in by HAL. See xge_hal_mgmt_about_info_t{}.
32a23fd11yl * @size: Size of the @about_info buffer. HAL will return error if the
33a23fd11yl *        size is smaller than sizeof(xge_hal_mgmt_about_info_t).
34a23fd11yl *
35a23fd11yl * Retrieve information such as PCI device and vendor IDs, board
36a23fd11yl * revision number, HAL version number, etc.
37a23fd11yl *
38a23fd11yl * Returns: XGE_HAL_OK - success;
39a23fd11yl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
40a23fd11yl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
41a23fd11yl * XGE_HAL_FAIL - Failed to retrieve the information.
42a23fd11yl *
43a23fd11yl * See also: xge_hal_mgmt_about_info_t{}.
44a23fd11yl */
45a23fd11ylxge_hal_status_e
46a23fd11ylxge_hal_mgmt_about(xge_hal_device_h devh, xge_hal_mgmt_about_info_t *about_info,
47a23fd11yl		int size)
48a23fd11yl{
49a23fd11yl	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
50a23fd11yl
51a23fd11yl	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
52a23fd11yl		return XGE_HAL_ERR_INVALID_DEVICE;
53a23fd11yl	}
54a23fd11yl
55a23fd11yl	if (size != sizeof(xge_hal_mgmt_about_info_t)) {
56a23fd11yl		return XGE_HAL_ERR_VERSION_CONFLICT;
57a23fd11yl	}
58a23fd11yl
59a23fd11yl	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
60a23fd11yl		xge_offsetof(xge_hal_pci_config_le_t, vendor_id),
61a23fd11yl		&about_info->vendor);
62a23fd11yl
63a23fd11yl	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
64a23fd11yl		xge_offsetof(xge_hal_pci_config_le_t, device_id),
65a23fd11yl		&about_info->device);
66a23fd11yl
67a23fd11yl	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
68a23fd11yl		xge_offsetof(xge_hal_pci_config_le_t, subsystem_vendor_id),
69a23fd11yl		&about_info->subsys_vendor);
70a23fd11yl
71a23fd11yl	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
72a23fd11yl		xge_offsetof(xge_hal_pci_config_le_t, subsystem_id),
73a23fd11yl		&about_info->subsys_device);
74a23fd11yl
75a23fd11yl	xge_os_pci_read8(hldev->pdev, hldev->cfgh,
76a23fd11yl		xge_offsetof(xge_hal_pci_config_le_t, revision),
77a23fd11yl		&about_info->board_rev);
78a23fd11yl
797eced41xw	xge_os_strlcpy(about_info->vendor_name, XGE_DRIVER_VENDOR,
807eced41xw	    sizeof(about_info->vendor_name));
81a23fd11yl
827eced41xw	xge_os_strlcpy(about_info->chip_name, XGE_CHIP_FAMILY,
837eced41xw	    sizeof(about_info->chip_name));
84a23fd11yl
857eced41xw	xge_os_strlcpy(about_info->media, XGE_SUPPORTED_MEDIA_0,
867eced41xw	    sizeof(about_info->media));
877eced41xw
887eced41xw	xge_os_strlcpy(about_info->hal_major, XGE_HAL_VERSION_MAJOR,
897eced41xw	    sizeof(about_info->hal_major));
907eced41xw
917eced41xw	xge_os_strlcpy(about_info->hal_minor, XGE_HAL_VERSION_MINOR,
927eced41xw	    sizeof(about_info->hal_minor));
937eced41xw
947eced41xw	xge_os_strlcpy(about_info->hal_fix,   XGE_HAL_VERSION_FIX,
957eced41xw	    sizeof(about_info->hal_fix));
967eced41xw
977eced41xw	xge_os_strlcpy(about_info->hal_build, XGE_HAL_VERSION_BUILD,
987eced41xw	    sizeof(about_info->hal_build));
997eced41xw
1007eced41xw	xge_os_strlcpy(about_info->ll_major, XGELL_VERSION_MAJOR,
1017eced41xw	    sizeof(about_info->ll_major));
1027eced41xw
1037eced41xw	xge_os_strlcpy(about_info->ll_minor, XGELL_VERSION_MINOR,
1047eced41xw	    sizeof(about_info->ll_minor));
1057eced41xw
1067eced41xw	xge_os_strlcpy(about_info->ll_fix,   XGELL_VERSION_FIX,
1077eced41xw	    sizeof(about_info->ll_fix));
1087eced41xw
1097eced41xw	xge_os_strlcpy(about_info->ll_build, XGELL_VERSION_BUILD,
1107eced41xw	    sizeof(about_info->ll_build));
111a23fd11yl
1128347601yl	about_info->transponder_temperature =
1138347601yl		xge_hal_read_xfp_current_temp(devh);
1148347601yl
115a23fd11yl	return XGE_HAL_OK;
116a23fd11yl}
117a23fd11yl
118a23fd11yl/**
119a23fd11yl * xge_hal_mgmt_reg_read - Read Xframe register.
120a23fd11yl * @devh: HAL device handle.
121a23fd11yl * @bar_id: 0 - for BAR0, 1- for BAR1.
122a23fd11yl * @offset: Register offset in the Base Address Register (BAR) space.
123a23fd11yl * @value: Register value. Returned by HAL.
124a23fd11yl * Read Xframe register.
125a23fd11yl *
126a23fd11yl * Returns: XGE_HAL_OK - success.
127a23fd11yl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
128a23fd11yl * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
129a23fd11yl * valid.
130a23fd11yl * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
131a23fd11yl *
132a23fd11yl * See also: xge_hal_aux_bar0_read(), xge_hal_aux_bar1_read().
133a23fd11yl */
134a23fd11ylxge_hal_status_e
135a23fd11ylxge_hal_mgmt_reg_read(xge_hal_device_h devh, int bar_id, unsigned int offset,
136a23fd11yl		u64 *value)
137a23fd11yl{
138a23fd11yl	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
139a23fd11yl
140a23fd11yl	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
141a23fd11yl		return XGE_HAL_ERR_INVALID_DEVICE;
142a23fd11yl	}
143a23fd11yl
144a23fd11yl	if (bar_id == 0) {
145a23fd11yl		if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
146a23fd11yl			return XGE_HAL_ERR_INVALID_OFFSET;
147a23fd11yl		}
148a23fd11yl		*value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
149a23fd11yl					     (void *)(hldev->bar0 + offset));
1507eced41xw	} else if (bar_id == 1 &&
1517eced41xw		   (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA ||
1527eced41xw		    xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC))  {
153a23fd11yl		int i;
1547eced41xw		for (i=0; i<XGE_HAL_MAX_FIFO_NUM_HERC; i++) {
155a23fd11yl			if (offset == i*0x2000 || offset == i*0x2000+0x18) {
156a23fd11yl				break;
157a23fd11yl			}
158a23fd11yl		}
1597eced41xw		if (i == XGE_HAL_MAX_FIFO_NUM_HERC) {
160a23fd11yl			return XGE_HAL_ERR_INVALID_OFFSET;
161a23fd11yl		}
162a23fd11yl		*value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh1,
163a23fd11yl					     (void *)(hldev->bar1 + offset));
1647eced41xw	} else if (bar_id == 1) {
1657eced41xw		/* FIXME: check TITAN BAR1 offsets */
1667eced41xw		return XGE_HAL_ERR_INVALID_DEVICE;
167a23fd11yl	} else {
168a23fd11yl		return XGE_HAL_ERR_INVALID_BAR_ID;
169a23fd11yl	}
170a23fd11yl
171a23fd11yl	return XGE_HAL_OK;
172a23fd11yl}
173a23fd11yl
174a23fd11yl/**
175a23fd11yl * xge_hal_mgmt_reg_write - Write Xframe register.
176a23fd11yl * @devh: HAL device handle.
177a23fd11yl * @bar_id: 0 - for BAR0, 1- for BAR1.
178a23fd11yl * @offset: Register offset in the Base Address Register (BAR) space.
179a23fd11yl * @value: Register value.
180a23fd11yl *
181a23fd11yl * Write Xframe register.
182a23fd11yl *
183a23fd11yl * Returns: XGE_HAL_OK - success.
184a23fd11yl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
185a23fd11yl * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
186a23fd11yl * valid.
187a23fd11yl * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
188a23fd11yl *
189a23fd11yl * See also: xge_hal_aux_bar0_write().
190a23fd11yl */
191a23fd11ylxge_hal_status_e
192a23fd11ylxge_hal_mgmt_reg_write(xge_hal_device_h devh, int bar_id, unsigned int offset,
193a23fd11yl		u64 value)
194a23fd11yl{
195a23fd11yl	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
196a23fd11yl
197a23fd11yl	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
198a23fd11yl		return XGE_HAL_ERR_INVALID_DEVICE;
199a23fd11yl	}
200a23fd11yl
201a23fd11yl	if (bar_id == 0) {
202a23fd11yl		if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
203a23fd11yl			return XGE_HAL_ERR_INVALID_OFFSET;
204a23fd11yl		}
205a23fd11yl		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, value,
206a23fd11yl				     (void *)(hldev->bar0 + offset));
2077eced41xw	} else if (bar_id == 1 &&
2087eced41xw		   (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA ||
2097eced41xw		    xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC))  {
210a23fd11yl		int i;
2117eced41xw		for (i=0; i<XGE_HAL_MAX_FIFO_NUM_HERC; i++) {
212a23fd11yl			if (offset == i*0x2000 || offset == i*0x2000+0x18) {
213a23fd11yl				break;
214a23fd11yl			}
215a23fd11yl		}
2167eced41xw		if (i == XGE_HAL_MAX_FIFO_NUM_HERC) {
217a23fd11yl			return XGE_HAL_ERR_INVALID_OFFSET;
218a23fd11yl		}
219a23fd11yl		xge_os_pio_mem_write64(hldev->pdev, hldev->regh1, value,
220a23fd11yl				     (void *)(hldev->bar1 + offset));
2217eced41xw	} else if (bar_id == 1) {
2227eced41xw		/* FIXME: check TITAN BAR1 offsets */
2237eced41xw		return XGE_HAL_ERR_INVALID_DEVICE;
224a23fd11yl	} else {
225a23fd11yl		return XGE_HAL_ERR_INVALID_BAR_ID;
226a23fd11yl	}
227a23fd11yl
228a23fd11yl	return XGE_HAL_OK;
229a23fd11yl}
230a23fd11yl
231a23fd11yl/**
232a23fd11yl * xge_hal_mgmt_hw_stats - Get Xframe hardware statistics.
233a23fd11yl * @devh: HAL device handle.
234a23fd11yl * @hw_stats: Hardware statistics. Returned by HAL.
235a23fd11yl *            See xge_hal_stats_hw_info_t{}.
236a23fd11yl * @size: Size of the @hw_stats buffer. HAL will return an error
237a23fd11yl * if the size is smaller than sizeof(xge_hal_stats_hw_info_t).
238a23fd11yl * Get Xframe hardware statistics.
239a23fd11yl *
240a23fd11yl * Returns: XGE_HAL_OK - success.
241a23fd11yl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
242a23fd11yl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
243a23fd11yl *
244a23fd11yl * See also: xge_hal_mgmt_sw_stats().
245a23fd11yl */
246a23fd11ylxge_hal_status_e
247a23fd11ylxge_hal_mgmt_hw_stats(xge_hal_device_h devh, xge_hal_mgmt_hw_stats_t *hw_stats,
248a23fd11yl		int size)
249a23fd11yl{
250a23fd11yl	xge_hal_status_e status;
251a23fd11yl	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
252a23fd11yl	xge_hal_stats_hw_info_t	*hw_info;
253a23fd11yl
2547eced41xw	xge_assert(xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN);
2557eced41xw
256a23fd11yl	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
257a23fd11yl		return XGE_HAL_ERR_INVALID_DEVICE;
258a23fd11yl	}
259a23fd11yl
260a23fd11yl	if (size != sizeof(xge_hal_stats_hw_info_t)) {
261a23fd11yl		return XGE_HAL_ERR_VERSION_CONFLICT;
262a23fd11yl	}
263a23fd11yl
264a23fd11yl	if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
265a23fd11yl		return status;
266a23fd11yl	}
267a23fd11yl
268a23fd11yl	xge_os_memcpy(hw_stats, hw_info, sizeof(xge_hal_stats_hw_info_t));
269a23fd11yl
270a23fd11yl	return XGE_HAL_OK;
271a23fd11yl}
272a23fd11yl
273a23fd11yl/**
2748347601yl * xge_hal_mgmt_hw_stats_off - TBD.
2758347601yl * @devh: HAL device handle.
2768347601yl * @off: TBD
2778347601yl * @size: TBD
2788347601yl * @out: TBD
2798347601yl *
2808347601yl * Returns: XGE_HAL_OK - success.
2818347601yl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
2828347601yl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
2838347601yl *
2848347601yl * See also: xge_hal_mgmt_sw_stats().
285a23fd11yl */
286a23fd11ylxge_hal_status_e
287a23fd11ylxge_hal_mgmt_hw_stats_off(xge_hal_device_h devh, int off, int size, char *out)
288a23fd11yl{
289a23fd11yl	xge_hal_status_e status;
290a23fd11yl	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
291a23fd11yl	xge_hal_stats_hw_info_t	*hw_info;
292a23fd11yl
2937eced41xw	xge_assert(xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN);
2947eced41xw
295a23fd11yl	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
296a23fd11yl		return XGE_HAL_ERR_INVALID_DEVICE;
297a23fd11yl	}
298a23fd11yl
299a23fd11yl	if (off > sizeof(xge_hal_stats_hw_info_t)-4 ||
300a23fd11yl	    size > 8) {
301a23fd11yl		return XGE_HAL_ERR_INVALID_OFFSET;
302a23fd11yl	}
303a23fd11yl
304a23fd11yl	if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
305a23fd11yl		return status;
306a23fd11yl	}
307a23fd11yl
308a23fd11yl	xge_os_memcpy(out, (char*)hw_info + off, size);
309a23fd11yl
310a23fd11yl	return XGE_HAL_OK;
311a23fd11yl}
312a23fd11yl
313a23fd11yl/**
3147eced41xw * xge_hal_mgmt_pcim_stats - Get Titan hardware statistics.
3157eced41xw * @devh: HAL device handle.
3167eced41xw * @pcim_stats: PCIM statistics. Returned by HAL.
3177eced41xw *            See xge_hal_stats_hw_info_t{}.
3187eced41xw * @size: Size of the @hw_stats buffer. HAL will return an error
3197eced41xw * if the size is smaller than sizeof(xge_hal_stats_hw_info_t).
3207eced41xw * Get Xframe hardware statistics.
3217eced41xw *
3227eced41xw * Returns: XGE_HAL_OK - success.
3237eced41xw * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
3247eced41xw * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
3257eced41xw *
3267eced41xw * See also: xge_hal_mgmt_sw_stats().
3277eced41xw */
3287eced41xwxge_hal_status_e
3297eced41xwxge_hal_mgmt_pcim_stats(xge_hal_device_h devh,
3307eced41xw		xge_hal_mgmt_pcim_stats_t *pcim_stats, int size)
3317eced41xw{
3327eced41xw	xge_hal_status_e status;
3337eced41xw	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
3347eced41xw	xge_hal_stats_pcim_info_t	*pcim_info;
3357eced41xw
3367eced41xw	xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN);
3377eced41xw
3387eced41xw	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
3397eced41xw		return XGE_HAL_ERR_INVALID_DEVICE;
3407eced41xw	}
3417eced41xw
3427eced41xw	if (size != sizeof(xge_hal_stats_pcim_info_t)) {
3437eced41xw		return XGE_HAL_ERR_VERSION_CONFLICT;
3447eced41xw	}
3457eced41xw
3467eced41xw	if ((status = xge_hal_stats_pcim (devh, &pcim_info)) != XGE_HAL_OK) {
3477eced41xw		return status;
3487eced41xw	}
3497eced41xw
3507eced41xw	xge_os_memcpy(pcim_stats, pcim_info,
3517eced41xw		sizeof(xge_hal_stats_pcim_info_t));
3527eced41xw
3537eced41xw	return XGE_HAL_OK;
3547eced41xw}
3557eced41xw
3567eced41xw/**
3577eced41xw * xge_hal_mgmt_pcim_stats_off - TBD.
3587eced41xw * @devh: HAL device handle.
3597eced41xw * @off: TBD
3607eced41xw * @size: TBD
3617eced41xw * @out: TBD
3627eced41xw *
3637eced41xw * Returns: XGE_HAL_OK - success.
3647eced41xw * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
3657eced41xw * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
3667eced41xw *
3677eced41xw * See also: xge_hal_mgmt_sw_stats().
3687eced41xw */
3697eced41xwxge_hal_status_e
3707eced41xwxge_hal_mgmt_pcim_stats_off(xge_hal_device_h devh, int off, int size,
3717eced41xw			    char *out)
3727eced41xw{
3737eced41xw	xge_hal_status_e status;
3747eced41xw	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
3757eced41xw	xge_hal_stats_pcim_info_t	*pcim_info;
3767eced41xw
3777eced41xw	xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN);
3787eced41xw
3797eced41xw	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
3807eced41xw		return XGE_HAL_ERR_INVALID_DEVICE;
3817eced41xw	}
3827eced41xw
3837eced41xw	if (off > sizeof(xge_hal_stats_pcim_info_t)-8 ||
3847eced41xw	    size > 8) {
3857eced41xw		return XGE_HAL_ERR_INVALID_OFFSET;
3867eced41xw	}
3877eced41xw
3887eced41xw	if ((status = xge_hal_stats_pcim (devh, &pcim_info)) != XGE_HAL_OK) {
3897eced41xw		return status;
3907eced41xw	}
3917eced41xw
3927eced41xw	xge_os_memcpy(out, (char*)pcim_info + off, size);
3937eced41xw
3947eced41xw	return XGE_HAL_OK;
3957eced41xw}
3967eced41xw
3977eced41xw/**
398a23fd11yl * xge_hal_mgmt_sw_stats - Get per-device software statistics.
399a23fd11yl * @devh: HAL device handle.
400a23fd11yl * @sw_stats: Hardware statistics. Returned by HAL.
401a23fd11yl *            See xge_hal_stats_sw_err_t{}.
402a23fd11yl * @size: Size of the @sw_stats buffer. HAL will return an error
403a23fd11yl * if the size is smaller than sizeof(xge_hal_stats_sw_err_t).
404a23fd11yl * Get device software statistics, including ECC and Parity error
405a23fd11yl * counters, etc.
406a23fd11yl *
407a23fd11yl * Returns: XGE_HAL_OK - success.
408a23fd11yl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
409a23fd11yl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
410a23fd11yl *
411a23fd11yl * See also: xge_hal_stats_sw_err_t{}, xge_hal_mgmt_hw_stats().
412a23fd11yl */
413a23fd11ylxge_hal_status_e
414a23fd11ylxge_hal_mgmt_sw_stats(xge_hal_device_h devh, xge_hal_mgmt_sw_stats_t *sw_stats,
415a23fd11yl		int size)
416a23fd11yl{
417a23fd11yl	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
418a23fd11yl
419a23fd11yl	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
420a23fd11yl		return XGE_HAL_ERR_INVALID_DEVICE;
421a23fd11yl	}
422a23fd11yl
423a23fd11yl	if (size != sizeof(xge_hal_stats_sw_err_t)) {
424a23fd11yl		return XGE_HAL_ERR_VERSION_CONFLICT;
425a23fd11yl	}
426a23fd11yl
427a23fd11yl	if (!hldev->stats.is_initialized ||
428a23fd11yl	    !hldev->stats.is_enabled) {
429a23fd11yl		return XGE_HAL_INF_STATS_IS_NOT_READY;
430a23fd11yl	}
431a23fd11yl
4328347601yl	/* Updating xpak stats value */
4338347601yl	__hal_updt_stats_xpak(hldev);
4348347601yl
435a23fd11yl	xge_os_memcpy(sw_stats, &hldev->stats.sw_dev_err_stats,
436a23fd11yl	            sizeof(xge_hal_stats_sw_err_t));
437a23fd11yl
438a23fd11yl	return XGE_HAL_OK;
439a23fd11yl}
440a23fd11yl
441a23fd11yl/**
442a23fd11yl * xge_hal_mgmt_device_stats - Get HAL device statistics.
443a23fd11yl * @devh: HAL device handle.
444a23fd11yl * @device_stats: HAL device "soft" statistics. Maintained by HAL itself.
445a23fd11yl *            (as opposed to xge_hal_mgmt_hw_stats() - those are
446a23fd11yl *            maintained by the Xframe hardware).
447a23fd11yl *            Returned by HAL.
448a23fd11yl *            See xge_hal_stats_device_info_t{}.
449a23fd11yl * @size: Size of the @device_stats buffer. HAL will return an error
450a23fd11yl * if the size is smaller than sizeof(xge_hal_stats_device_info_t).
451a23fd11yl *
452a23fd11yl * Get HAL (layer) statistic counters.
453a23fd11yl * Returns: XGE_HAL_OK - success.
454a23fd11yl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
455a23fd11yl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
456a23fd11yl * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
457a23fd11yl * currently available.
458a23fd11yl *
459a23fd11yl */
460a23fd11ylxge_hal_status_e
461a23fd11ylxge_hal_mgmt_device_stats(xge_hal_device_h devh,
462a23fd11yl		xge_hal_mgmt_device_stats_t *device_stats, int size)
463a23fd11yl{
464a23fd11yl	xge_hal_status_e status;
465a23fd11yl	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
466a23fd11yl	xge_hal_stats_device_info_t *device_info;
467a23fd11yl
468a23fd11yl	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
469a23fd11yl		return XGE_HAL_ERR_INVALID_DEVICE;
470a23fd11yl	}
471a23fd11yl
472a23fd11yl	if (size != sizeof(xge_hal_stats_device_info_t)) {
473a23fd11yl		return XGE_HAL_ERR_VERSION_CONFLICT;
474a23fd11yl	}
475a23fd11yl
476a23fd11yl	if ((status = xge_hal_stats_device (devh, &device_info)) !=
477a23fd11yl	XGE_HAL_OK) {
478a23fd11yl		return status;
479a23fd11yl	}
480a23fd11yl
481a23fd11yl	xge_os_memcpy(device_stats, device_info,
482a23fd11yl		    sizeof(xge_hal_stats_device_info_t));
483a23fd11yl
484a23fd11yl	return XGE_HAL_OK;
485a23fd11yl}
486a23fd11yl
487a23fd11yl/*
488a23fd11yl * __hal_update_ring_bump - Update the ring bump counter for the
489a23fd11yl * particular channel.
490a23fd11yl * @hldev: HAL device handle.
491a23fd11yl * @queue: the queue who's data is to be collected.
492a23fd11yl * @chinfo: pointer to the statistics structure of the given channel.
493a23fd11yl * Usage: See xge_hal_aux_stats_hal_read{}
494a23fd11yl */
495a23fd11yl
496a23fd11ylstatic void
497a23fd11yl__hal_update_ring_bump(xge_hal_device_t *hldev, int queue,
498a23fd11yl	xge_hal_stats_channel_info_t *chinfo)
499a23fd11yl{
500a23fd11yl	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
501a23fd11yl	u64 rbc = 0;
502a23fd11yl	int reg = (queue / 4);
503a23fd11yl	void * addr;
504a23fd11yl
505a23fd11yl	addr = (reg == 1)? (&bar0->ring_bump_counter2) :
506a23fd11yl		(&bar0->ring_bump_counter1);
507a23fd11yl	rbc = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, addr);
508a23fd11yl	chinfo->ring_bump_cnt = XGE_HAL_RING_BUMP_CNT(queue, rbc);
509a23fd11yl}
510a23fd11yl
511a23fd11yl/**
512a23fd11yl * xge_hal_mgmt_channel_stats - Get HAL channel statistics.
513a23fd11yl * @channelh: HAL channel handle.
514a23fd11yl * @channel_stats: HAL channel statistics. Maintained by HAL itself
515a23fd11yl *            (as opposed to xge_hal_mgmt_hw_stats() - those are
516a23fd11yl *            maintained by the Xframe hardware).
517a23fd11yl *            Returned by HAL.
518a23fd11yl *            See xge_hal_stats_channel_info_t{}.
519a23fd11yl * @size: Size of the @channel_stats buffer. HAL will return an error
520a23fd11yl * if the size is smaller than sizeof(xge_hal_mgmt_channel_stats_t).
521a23fd11yl *
522a23fd11yl * Get HAL per-channel statistic counters.
523a23fd11yl *
524a23fd11yl * Returns: XGE_HAL_OK - success.
525a23fd11yl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
526a23fd11yl * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
527a23fd11yl * currently available.
528a23fd11yl *
529a23fd11yl */
530a23fd11ylxge_hal_status_e
531a23fd11ylxge_hal_mgmt_channel_stats(xge_hal_channel_h channelh,
532a23fd11yl		xge_hal_mgmt_channel_stats_t *channel_stats, int size)
533a23fd11yl{
534a23fd11yl	xge_hal_status_e status;
535a23fd11yl	xge_hal_stats_channel_info_t *channel_info;
5368347601yl	xge_hal_channel_t *channel = (xge_hal_channel_t* ) channelh;
537a23fd11yl
538a23fd11yl	if (size != sizeof(xge_hal_stats_channel_info_t)) {
539a23fd11yl		return XGE_HAL_ERR_VERSION_CONFLICT;
540a23fd11yl	}
541a23fd11yl
542a23fd11yl	if ((status = xge_hal_stats_channel (channelh, &channel_info)) !=
543a23fd11yl								XGE_HAL_OK) {
544a23fd11yl		return status;
545a23fd11yl	}
546a23fd11yl
547a23fd11yl	if (xge_hal_device_check_id(channel->devh) == XGE_HAL_CARD_HERC) {
5488347601yl        __hal_update_ring_bump( (xge_hal_device_t *) channel->devh, channel->post_qid, channel_info);
549a23fd11yl	}
550a23fd11yl
551a23fd11yl	xge_os_memcpy(channel_stats, channel_info,
552a23fd11yl		    sizeof(xge_hal_stats_channel_info_t));
553a23fd11yl
554a23fd11yl	return XGE_HAL_OK;
555a23fd11yl}
556a23fd11yl
557a23fd11yl/**
558a23fd11yl * xge_hal_mgmt_pcireg_read - Read PCI configuration at a specified
559a23fd11yl * offset.
560a23fd11yl * @devh: HAL device handle.
561a23fd11yl * @offset: Offset in the 256 byte PCI configuration space.
562a23fd11yl * @value_bits: 8, 16, or 32 (bits) to read.
563a23fd11yl * @value: Value returned by HAL.
564a23fd11yl *
565a23fd11yl * Read PCI configuration, given device and offset in the PCI space.
566a23fd11yl *
567a23fd11yl * Returns: XGE_HAL_OK - success.
568a23fd11yl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
569a23fd11yl * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
570a23fd11yl * valid.
571a23fd11yl * XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE - Invalid bits size. Valid
572a23fd11yl * values(8/16/32).
573a23fd11yl *
574a23fd11yl */
575a23fd11ylxge_hal_status_e
576a23fd11ylxge_hal_mgmt_pcireg_read(xge_hal_device_h devh, unsigned int offset,
577a23fd11yl		int value_bits, u32 *value)
578a23fd11yl{
579a23fd11yl	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
580a23fd11yl
581a23fd11yl	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
582a23fd11yl		return XGE_HAL_ERR_INVALID_DEVICE;
583a23fd11yl	}
584a23fd11yl
585a23fd11yl	if (offset > sizeof(xge_hal_pci_config_t)-value_bits/8) {
586a23fd11yl		return XGE_HAL_ERR_INVALID_OFFSET;
587a23fd11yl	}
588a23fd11yl
589a23fd11yl	if (value_bits == 8) {
590a23fd11yl		xge_os_pci_read8(hldev->pdev, hldev->cfgh, offset, (u8*)value);
591a23fd11yl	} else if (value_bits == 16) {
592a23fd11yl		xge_os_pci_read16(hldev->pdev, hldev->cfgh, offset,
593a23fd11yl		(u16*)value);
594a23fd11yl	} else if (value_bits == 32) {
595a23fd11yl		xge_os_pci_read32(hldev->pdev, hldev->cfgh, offset, value);
596a23fd11yl	} else {
597a23fd11yl		return XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE;
598a23fd11yl	}
599a23fd11yl
600a23fd11yl	return XGE_HAL_OK;
601a23fd11yl}
602a23fd11yl
603a23fd11yl/**
604a23fd11yl * xge_hal_mgmt_device_config - Retrieve device configuration.
605a23fd11yl * @devh: HAL device handle.
606a23fd11yl * @dev_config: Device configuration, see xge_hal_device_config_t{}.
607a23fd11yl * @size: Size of the @dev_config buffer. HAL will return an error
608a23fd11yl * if the size is smaller than sizeof(xge_hal_mgmt_device_config_t).
609a23fd11yl *
610a23fd11yl * Get device configuration. Permits to retrieve at run-time configuration
611a23fd11yl * values that were used to initialize and configure the device.
612a23fd11yl *
613a23fd11yl * Returns: XGE_HAL_OK - success.
614a23fd11yl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
615a23fd11yl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
616a23fd11yl *
617a23fd11yl * See also: xge_hal_device_config_t{}, xge_hal_mgmt_driver_config().
618a23fd11yl */
619a23fd11ylxge_hal_status_e
620a23fd11ylxge_hal_mgmt_device_config(xge_hal_device_h devh,
621a23fd11yl		xge_hal_mgmt_device_config_t	*dev_config, int size)
622a23fd11yl{
623a23fd11yl	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
624a23fd11yl
625a23fd11yl	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
626a23fd11yl		return XGE_HAL_ERR_INVALID_DEVICE;
627a23fd11yl	}
628a23fd11yl
629a23fd11yl	if (size != sizeof(xge_hal_mgmt_device_config_t)) {
630a23fd11yl		return XGE_HAL_ERR_VERSION_CONFLICT;
631a23fd11yl	}
632a23fd11yl
633a23fd11yl	xge_os_memcpy(dev_config, &hldev->config,
634a23fd11yl	sizeof(xge_hal_device_config_t));
635a23fd11yl
636a23fd11yl	return XGE_HAL_OK;
637a23fd11yl}
638a23fd11yl
639a23fd11yl/**
640a23fd11yl * xge_hal_mgmt_driver_config - Retrieve driver configuration.
641a23fd11yl * @drv_config: Device configuration, see xge_hal_driver_config_t{}.
642a23fd11yl * @size: Size of the @dev_config buffer. HAL will return an error
643a23fd11yl * if the size is smaller than sizeof(xge_hal_mgmt_driver_config_t).
644a23fd11yl *
645a23fd11yl * Get driver configuration. Permits to retrieve at run-time configuration
646a23fd11yl * values that were used to configure the device at load-time.
647a23fd11yl *
648a23fd11yl * Returns: XGE_HAL_OK - success.
649a23fd11yl * XGE_HAL_ERR_DRIVER_NOT_INITIALIZED - HAL is not initialized.
650a23fd11yl * XGE_HAL_ERR_VERSION_CONFLICT - Version is not maching.
651a23fd11yl *
652a23fd11yl * See also: xge_hal_driver_config_t{}, xge_hal_mgmt_device_config().
653a23fd11yl */
654a23fd11ylxge_hal_status_e
655a23fd11ylxge_hal_mgmt_driver_config(xge_hal_mgmt_driver_config_t *drv_config, int size)
656a23fd11yl{
657a23fd11yl
658a23fd11yl	if (g_xge_hal_driver == NULL) {
659a23fd11yl		return XGE_HAL_ERR_DRIVER_NOT_INITIALIZED;
660a23fd11yl	}
661a23fd11yl
662a23fd11yl	if (size != sizeof(xge_hal_mgmt_driver_config_t)) {
663a23fd11yl		return XGE_HAL_ERR_VERSION_CONFLICT;
664a23fd11yl	}
665a23fd11yl
666a23fd11yl	xge_os_memcpy(drv_config, &g_xge_hal_driver->config,
667a23fd11yl		    sizeof(xge_hal_mgmt_driver_config_t));
668a23fd11yl
669a23fd11yl	return XGE_HAL_OK;
670a23fd11yl}
671a23fd11yl
672a23fd11yl/**
673a23fd11yl * xge_hal_mgmt_pci_config - Retrieve PCI configuration.
674a23fd11yl * @devh: HAL device handle.
675a23fd11yl * @pci_config: 256 byte long buffer for PCI configuration space.
676a23fd11yl * @size: Size of the @ buffer. HAL will return an error
677a23fd11yl * if the size is smaller than sizeof(xge_hal_mgmt_pci_config_t).
678a23fd11yl *
679a23fd11yl * Get PCI configuration. Permits to retrieve at run-time configuration
680a23fd11yl * values that were used to configure the device at load-time.
681a23fd11yl *
682a23fd11yl * Returns: XGE_HAL_OK - success.
683a23fd11yl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
684a23fd11yl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
685a23fd11yl *
686a23fd11yl */
687a23fd11ylxge_hal_status_e
688a23fd11ylxge_hal_mgmt_pci_config(xge_hal_device_h devh,
689a23fd11yl		xge_hal_mgmt_pci_config_t *pci_config, int size)
690a23fd11yl{
691a23fd11yl	int i;
692a23fd11yl	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
693a23fd11yl
694a23fd11yl	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
695a23fd11yl		return XGE_HAL_ERR_INVALID_DEVICE;
696a23fd11yl	}
697a23fd11yl
698a23fd11yl	if (size != sizeof(xge_hal_mgmt_pci_config_t)) {
699a23fd11yl		return XGE_HAL_ERR_VERSION_CONFLICT;
700a23fd11yl	}
701a23fd11yl
702a23fd11yl	/* refresh PCI config space */
703a23fd11yl	for (i = 0; i < 0x68/4+1; i++) {
704a23fd11yl		xge_os_pci_read32(hldev->pdev, hldev->cfgh, i*4,
705a23fd11yl		                (u32*)&hldev->pci_config_space + i);
706a23fd11yl	}
707a23fd11yl
708a23fd11yl	xge_os_memcpy(pci_config, &hldev->pci_config_space,
709a23fd11yl		    sizeof(xge_hal_mgmt_pci_config_t));
710a23fd11yl
711a23fd11yl	return XGE_HAL_OK;
712a23fd11yl}
713a23fd11yl
714a23fd11yl#ifdef XGE_TRACE_INTO_CIRCULAR_ARR
715a23fd11yl/**
716a23fd11yl * xge_hal_mgmt_trace_read - Read trace buffer contents.
717a23fd11yl * @buffer: Buffer to store the trace buffer contents.
718a23fd11yl * @buf_size: Size of the buffer.
719a23fd11yl * @offset: Offset in the internal trace buffer to read data.
720a23fd11yl * @read_length: Size of the valid data in the buffer.
721a23fd11yl *
722a23fd11yl * Read  HAL trace buffer contents starting from the offset
723a23fd11yl * upto the size of the buffer or till EOF is reached.
724a23fd11yl *
725a23fd11yl * Returns: XGE_HAL_OK - success.
726a23fd11yl * XGE_HAL_EOF_TRACE_BUF - No more data in the trace buffer.
727a23fd11yl *
728a23fd11yl */
729a23fd11ylxge_hal_status_e
730a23fd11ylxge_hal_mgmt_trace_read (char		*buffer,
731a23fd11yl			unsigned	buf_size,
732a23fd11yl			unsigned	*offset,
733a23fd11yl			unsigned	*read_length)
734a23fd11yl{
735a23fd11yl	int data_offset;
736a23fd11yl	int start_offset;
737a23fd11yl
738a23fd11yl	if ((g_xge_os_tracebuf == NULL) ||
739a23fd11yl		(g_xge_os_tracebuf->offset == g_xge_os_tracebuf->size - 2)) {
740a23fd11yl		return XGE_HAL_EOF_TRACE_BUF;
741a23fd11yl	}
742a23fd11yl
743a23fd11yl	data_offset = g_xge_os_tracebuf->offset + 1;
744a23fd11yl
745a23fd11yl	if  (*offset >= (unsigned)xge_os_strlen(g_xge_os_tracebuf->data +
746a23fd11yl	data_offset)) {
747a23fd11yl
748a23fd11yl		return XGE_HAL_EOF_TRACE_BUF;
749a23fd11yl	}
750a23fd11yl
751a23fd11yl	xge_os_memzero(buffer, buf_size);
752a23fd11yl
753a23fd11yl	start_offset  =  data_offset + *offset;
754a23fd11yl	*read_length = xge_os_strlen(g_xge_os_tracebuf->data +
755a23fd11yl	start_offset);
756a23fd11yl
757a23fd11yl	if (*read_length  >=  buf_size) {
758a23fd11yl		*read_length = buf_size - 1;
759a23fd11yl	}
760a23fd11yl
761a23fd11yl	xge_os_memcpy(buffer, g_xge_os_tracebuf->data + start_offset,
762a23fd11yl	*read_length);
763a23fd11yl
764a23fd11yl	*offset += *read_length;
765a23fd11yl	(*read_length) ++;
766a23fd11yl
767a23fd11yl	return XGE_HAL_OK;
768a23fd11yl}
769a23fd11yl
770a23fd11yl#endif
771a23fd11yl
772a23fd11yl/**
773a23fd11yl * xge_hal_restore_link_led - Restore link LED to its original state.
774a23fd11yl * @devh: HAL device handle.
775a23fd11yl */
776a23fd11ylvoid
777a23fd11ylxge_hal_restore_link_led(xge_hal_device_h devh)
778a23fd11yl{
779a23fd11yl	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
780a23fd11yl	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
781a23fd11yl	u64 val64;
782a23fd11yl
783a23fd11yl	/*
784a23fd11yl	 * If the current link state is UP, switch on LED else make it
785a23fd11yl	 * off.
786a23fd11yl	 */
787a23fd11yl
788a23fd11yl	/*
789a23fd11yl	 * For Xena 3 and lower revision cards, adapter control needs to be
790a23fd11yl	 * used for making LED ON/OFF.
791a23fd11yl	 */
792a23fd11yl	if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
793a23fd11yl	   (xge_hal_device_rev(hldev) <= 3)) {
794a23fd11yl		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
795a23fd11yl					      &bar0->adapter_control);
796a23fd11yl		if (hldev->link_state == XGE_HAL_LINK_UP) {
797a23fd11yl			val64 |= XGE_HAL_ADAPTER_LED_ON;
798a23fd11yl		} else {
799a23fd11yl			val64 &= ~XGE_HAL_ADAPTER_LED_ON;
800a23fd11yl		}
801a23fd11yl
802a23fd11yl		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
803a23fd11yl					&bar0->adapter_control);
804a23fd11yl		return;
805a23fd11yl	}
806a23fd11yl
807a23fd11yl	/*
808a23fd11yl	 * Use beacon control register to control the LED.
809a23fd11yl	 * LED link output corresponds to bit 8 of the beacon control
810a23fd11yl	 * register. Note that, in the case of Xena, beacon control register
811a23fd11yl	 * represents the gpio control register. In the case of Herc, LED
812a23fd11yl	 * handling is done by beacon control register as opposed to gpio
8137eced41xw	 * control register in Xena. Beacon control is used only to toggle
8147eced41xw     * and the value written into it does not depend on the link state.
8157eced41xw     * It is upto the ULD to toggle the LED even number of times which
8167eced41xw     * brings the LED to it's original state.
817a23fd11yl	 */
818a23fd11yl	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
819a23fd11yl				      &bar0->beacon_control);
8207eced41xw    val64 |= 0x0000800000000000ULL;
8217eced41xw    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
8227eced41xw    		       val64, &bar0->beacon_control);
823a23fd11yl}
824a23fd11yl
825a23fd11yl/**
826a23fd11yl * xge_hal_flick_link_led - Flick (blink) link LED.
827a23fd11yl * @devh: HAL device handle.
828a23fd11yl *
829a23fd11yl * Depending on the card revision flicker the link LED by using the
830a23fd11yl * beacon control or the adapter_control register.
831a23fd11yl */
832a23fd11ylvoid
833a23fd11ylxge_hal_flick_link_led(xge_hal_device_h devh)
834a23fd11yl{
835a23fd11yl	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
836a23fd11yl	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
837a23fd11yl	u64 val64 = 0;
838a23fd11yl
839a23fd11yl	/*
840a23fd11yl	 * For Xena 3 and lower revision cards, adapter control needs to be
841a23fd11yl	 * used for making LED ON/OFF.
842a23fd11yl	 */
843a23fd11yl	if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
844a23fd11yl	   (xge_hal_device_rev(hldev) <= 3)) {
845a23fd11yl		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
846a23fd11yl					      &bar0->adapter_control);
847a23fd11yl		val64 ^= XGE_HAL_ADAPTER_LED_ON;
848a23fd11yl		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
849a23fd11yl					&bar0->adapter_control);
850a23fd11yl		return;
851a23fd11yl	}
852a23fd11yl
853a23fd11yl	/*
854a23fd11yl	 * Use beacon control register to control the Link LED.
855a23fd11yl	 * Note that, in the case of Xena, beacon control register represents
856a23fd11yl	 * the gpio control register. In the case of Herc, LED handling is
857a23fd11yl	 * done by beacon control register as opposed to gpio control register
858a23fd11yl	 * in Xena.
859a23fd11yl	 */
860a23fd11yl	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
861a23fd11yl				      &bar0->beacon_control);
862a23fd11yl	val64 ^= XGE_HAL_GPIO_CTRL_GPIO_0;
863a23fd11yl	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
864a23fd11yl			       &bar0->beacon_control);
865a23fd11yl}
866a23fd11yl
867a23fd11yl/**
868a23fd11yl * xge_hal_read_eeprom - Read 4 bytes of data from user given offset.
869a23fd11yl * @devh: HAL device handle.
870a23fd11yl * @off: offset at which the data must be written
871a23fd11yl * @data: output parameter where the data is stored.
872a23fd11yl *
873a23fd11yl * Read 4 bytes of data from the user given offset and return the
874a23fd11yl * read data.
875a23fd11yl * Note: will allow to read only part of the EEPROM visible through the
876a23fd11yl * I2C bus.
877a23fd11yl * Returns: -1 on failure, 0 on success.
878a23fd11yl */
879a23fd11ylxge_hal_status_e
8808347601ylxge_hal_read_eeprom(xge_hal_device_h devh, int off, u32* data)
881a23fd11yl{
882a23fd11yl	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
8838347601yl	xge_hal_status_e ret = XGE_HAL_FAIL;
884a23fd11yl	u32 exit_cnt = 0;
885a23fd11yl	u64 val64;
886a23fd11yl	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
887a23fd11yl
888a23fd11yl	val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) |
889a23fd11yl		XGE_HAL_I2C_CONTROL_ADDR(off) |
890a23fd11yl		XGE_HAL_I2C_CONTROL_BYTE_CNT(0x3) |
891a23fd11yl		XGE_HAL_I2C_CONTROL_READ | XGE_HAL_I2C_CONTROL_CNTL_START;
892a23fd11yl
8937eced41xw	__hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
894a23fd11yl
895a23fd11yl	while (exit_cnt < 5) {
8967eced41xw		val64 = __hal_serial_mem_read64(