1a23fd118Syl /*
2a23fd118Syl  * CDDL HEADER START
3a23fd118Syl  *
4a23fd118Syl  * The contents of this file are subject to the terms of the
5a23fd118Syl  * Common Development and Distribution License (the "License").
6a23fd118Syl  * You may not use this file except in compliance with the License.
7a23fd118Syl  *
8a23fd118Syl  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9a23fd118Syl  * or http://www.opensolaris.org/os/licensing.
10a23fd118Syl  * See the License for the specific language governing permissions
11a23fd118Syl  * and limitations under the License.
12a23fd118Syl  *
13a23fd118Syl  * When distributing Covered Code, include this CDDL HEADER in each
14a23fd118Syl  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15a23fd118Syl  * If applicable, add the following below this CDDL HEADER, with the
16a23fd118Syl  * fields enclosed by brackets "[]" replaced with your own identifying
17a23fd118Syl  * information: Portions Copyright [yyyy] [name of copyright owner]
18a23fd118Syl  *
19a23fd118Syl  * CDDL HEADER END
20a23fd118Syl  *
218347601bSyl  * Copyright (c) 2002-2006 Neterion, Inc.
22a23fd118Syl  */
23a23fd118Syl 
24a23fd118Syl #include "xgehal-mgmt.h"
25a23fd118Syl #include "xgehal-driver.h"
26a23fd118Syl #include "xgehal-device.h"
27a23fd118Syl 
28a23fd118Syl /**
29a23fd118Syl  * xge_hal_mgmt_about - Retrieve about info.
30a23fd118Syl  * @devh: HAL device handle.
31a23fd118Syl  * @about_info: Filled in by HAL. See xge_hal_mgmt_about_info_t{}.
32a23fd118Syl  * @size: Size of the @about_info buffer. HAL will return error if the
33a23fd118Syl  *        size is smaller than sizeof(xge_hal_mgmt_about_info_t).
34a23fd118Syl  *
35a23fd118Syl  * Retrieve information such as PCI device and vendor IDs, board
36a23fd118Syl  * revision number, HAL version number, etc.
37a23fd118Syl  *
38a23fd118Syl  * Returns: XGE_HAL_OK - success;
39a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
40a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
41a23fd118Syl  * XGE_HAL_FAIL - Failed to retrieve the information.
42a23fd118Syl  *
43a23fd118Syl  * See also: xge_hal_mgmt_about_info_t{}.
44a23fd118Syl  */
45a23fd118Syl xge_hal_status_e
xge_hal_mgmt_about(xge_hal_device_h devh,xge_hal_mgmt_about_info_t * about_info,int size)46a23fd118Syl xge_hal_mgmt_about(xge_hal_device_h devh, xge_hal_mgmt_about_info_t *about_info,
47a23fd118Syl 		int size)
48a23fd118Syl {
49a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
50a23fd118Syl 
51a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
52a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
53a23fd118Syl 	}
54a23fd118Syl 
55a23fd118Syl 	if (size != sizeof(xge_hal_mgmt_about_info_t)) {
56a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
57a23fd118Syl 	}
58a23fd118Syl 
59a23fd118Syl 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
60a23fd118Syl 		xge_offsetof(xge_hal_pci_config_le_t, vendor_id),
61a23fd118Syl 		&about_info->vendor);
62a23fd118Syl 
63a23fd118Syl 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
64a23fd118Syl 		xge_offsetof(xge_hal_pci_config_le_t, device_id),
65a23fd118Syl 		&about_info->device);
66a23fd118Syl 
67a23fd118Syl 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
68a23fd118Syl 		xge_offsetof(xge_hal_pci_config_le_t, subsystem_vendor_id),
69a23fd118Syl 		&about_info->subsys_vendor);
70a23fd118Syl 
71a23fd118Syl 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
72a23fd118Syl 		xge_offsetof(xge_hal_pci_config_le_t, subsystem_id),
73a23fd118Syl 		&about_info->subsys_device);
74a23fd118Syl 
75a23fd118Syl 	xge_os_pci_read8(hldev->pdev, hldev->cfgh,
76a23fd118Syl 		xge_offsetof(xge_hal_pci_config_le_t, revision),
77a23fd118Syl 		&about_info->board_rev);
78a23fd118Syl 
797eced415Sxw 	xge_os_strlcpy(about_info->vendor_name, XGE_DRIVER_VENDOR,
807eced415Sxw 	    sizeof(about_info->vendor_name));
81a23fd118Syl 
827eced415Sxw 	xge_os_strlcpy(about_info->chip_name, XGE_CHIP_FAMILY,
837eced415Sxw 	    sizeof(about_info->chip_name));
84a23fd118Syl 
857eced415Sxw 	xge_os_strlcpy(about_info->media, XGE_SUPPORTED_MEDIA_0,
867eced415Sxw 	    sizeof(about_info->media));
877eced415Sxw 
887eced415Sxw 	xge_os_strlcpy(about_info->hal_major, XGE_HAL_VERSION_MAJOR,
897eced415Sxw 	    sizeof(about_info->hal_major));
907eced415Sxw 
917eced415Sxw 	xge_os_strlcpy(about_info->hal_minor, XGE_HAL_VERSION_MINOR,
927eced415Sxw 	    sizeof(about_info->hal_minor));
937eced415Sxw 
947eced415Sxw 	xge_os_strlcpy(about_info->hal_fix,   XGE_HAL_VERSION_FIX,
957eced415Sxw 	    sizeof(about_info->hal_fix));
967eced415Sxw 
977eced415Sxw 	xge_os_strlcpy(about_info->hal_build, XGE_HAL_VERSION_BUILD,
987eced415Sxw 	    sizeof(about_info->hal_build));
997eced415Sxw 
1007eced415Sxw 	xge_os_strlcpy(about_info->ll_major, XGELL_VERSION_MAJOR,
1017eced415Sxw 	    sizeof(about_info->ll_major));
1027eced415Sxw 
1037eced415Sxw 	xge_os_strlcpy(about_info->ll_minor, XGELL_VERSION_MINOR,
1047eced415Sxw 	    sizeof(about_info->ll_minor));
1057eced415Sxw 
1067eced415Sxw 	xge_os_strlcpy(about_info->ll_fix,   XGELL_VERSION_FIX,
1077eced415Sxw 	    sizeof(about_info->ll_fix));
1087eced415Sxw 
1097eced415Sxw 	xge_os_strlcpy(about_info->ll_build, XGELL_VERSION_BUILD,
1107eced415Sxw 	    sizeof(about_info->ll_build));
111a23fd118Syl 
1128347601bSyl 	about_info->transponder_temperature =
1138347601bSyl 		xge_hal_read_xfp_current_temp(devh);
1148347601bSyl 
115a23fd118Syl 	return XGE_HAL_OK;
116a23fd118Syl }
117a23fd118Syl 
118a23fd118Syl /**
119a23fd118Syl  * xge_hal_mgmt_reg_read - Read Xframe register.
120a23fd118Syl  * @devh: HAL device handle.
121a23fd118Syl  * @bar_id: 0 - for BAR0, 1- for BAR1.
122a23fd118Syl  * @offset: Register offset in the Base Address Register (BAR) space.
123a23fd118Syl  * @value: Register value. Returned by HAL.
124a23fd118Syl  * Read Xframe register.
125a23fd118Syl  *
126a23fd118Syl  * Returns: XGE_HAL_OK - success.
127a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
128a23fd118Syl  * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
129a23fd118Syl  * valid.
130a23fd118Syl  * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
131a23fd118Syl  *
132a23fd118Syl  * See also: xge_hal_aux_bar0_read(), xge_hal_aux_bar1_read().
133a23fd118Syl  */
134a23fd118Syl xge_hal_status_e
xge_hal_mgmt_reg_read(xge_hal_device_h devh,int bar_id,unsigned int offset,u64 * value)135a23fd118Syl xge_hal_mgmt_reg_read(xge_hal_device_h devh, int bar_id, unsigned int offset,
136a23fd118Syl 		u64 *value)
137a23fd118Syl {
138a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
139a23fd118Syl 
140a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
141a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
142a23fd118Syl 	}
143a23fd118Syl 
144a23fd118Syl 	if (bar_id == 0) {
145a23fd118Syl 		if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
146a23fd118Syl 			return XGE_HAL_ERR_INVALID_OFFSET;
147a23fd118Syl 		}
148a23fd118Syl 		*value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
149a23fd118Syl 					     (void *)(hldev->bar0 + offset));
1507eced415Sxw 	} else if (bar_id == 1 &&
1517eced415Sxw 		   (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA ||
1527eced415Sxw 		    xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC))  {
153a23fd118Syl 		int i;
1547eced415Sxw 		for (i=0; i<XGE_HAL_MAX_FIFO_NUM_HERC; i++) {
155a23fd118Syl 			if (offset == i*0x2000 || offset == i*0x2000+0x18) {
156a23fd118Syl 				break;
157a23fd118Syl 			}
158a23fd118Syl 		}
1597eced415Sxw 		if (i == XGE_HAL_MAX_FIFO_NUM_HERC) {
160a23fd118Syl 			return XGE_HAL_ERR_INVALID_OFFSET;
161a23fd118Syl 		}
162a23fd118Syl 		*value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh1,
163a23fd118Syl 					     (void *)(hldev->bar1 + offset));
1647eced415Sxw 	} else if (bar_id == 1) {
1657eced415Sxw 		/* FIXME: check TITAN BAR1 offsets */
1667eced415Sxw 		return XGE_HAL_ERR_INVALID_DEVICE;
167a23fd118Syl 	} else {
168a23fd118Syl 		return XGE_HAL_ERR_INVALID_BAR_ID;
169a23fd118Syl 	}
170a23fd118Syl 
171a23fd118Syl 	return XGE_HAL_OK;
172a23fd118Syl }
173a23fd118Syl 
174a23fd118Syl /**
175a23fd118Syl  * xge_hal_mgmt_reg_write - Write Xframe register.
176a23fd118Syl  * @devh: HAL device handle.
177a23fd118Syl  * @bar_id: 0 - for BAR0, 1- for BAR1.
178a23fd118Syl  * @offset: Register offset in the Base Address Register (BAR) space.
179a23fd118Syl  * @value: Register value.
180a23fd118Syl  *
181a23fd118Syl  * Write Xframe register.
182a23fd118Syl  *
183a23fd118Syl  * Returns: XGE_HAL_OK - success.
184a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
185a23fd118Syl  * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
186a23fd118Syl  * valid.
187a23fd118Syl  * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
188a23fd118Syl  *
189a23fd118Syl  * See also: xge_hal_aux_bar0_write().
190a23fd118Syl  */
191a23fd118Syl xge_hal_status_e
xge_hal_mgmt_reg_write(xge_hal_device_h devh,int bar_id,unsigned int offset,u64 value)192a23fd118Syl xge_hal_mgmt_reg_write(xge_hal_device_h devh, int bar_id, unsigned int offset,
193a23fd118Syl 		u64 value)
194a23fd118Syl {
195a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
196a23fd118Syl 
197a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
198a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
199a23fd118Syl 	}
200a23fd118Syl 
201a23fd118Syl 	if (bar_id == 0) {
202a23fd118Syl 		if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
203a23fd118Syl 			return XGE_HAL_ERR_INVALID_OFFSET;
204a23fd118Syl 		}
205a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, value,
206a23fd118Syl 				     (void *)(hldev->bar0 + offset));
2077eced415Sxw 	} else if (bar_id == 1 &&
2087eced415Sxw 		   (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA ||
2097eced415Sxw 		    xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC))  {
210a23fd118Syl 		int i;
2117eced415Sxw 		for (i=0; i<XGE_HAL_MAX_FIFO_NUM_HERC; i++) {
212a23fd118Syl 			if (offset == i*0x2000 || offset == i*0x2000+0x18) {
213a23fd118Syl 				break;
214a23fd118Syl 			}
215a23fd118Syl 		}
2167eced415Sxw 		if (i == XGE_HAL_MAX_FIFO_NUM_HERC) {
217a23fd118Syl 			return XGE_HAL_ERR_INVALID_OFFSET;
218a23fd118Syl 		}
219a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh1, value,
220a23fd118Syl 				     (void *)(hldev->bar1 + offset));
2217eced415Sxw 	} else if (bar_id == 1) {
2227eced415Sxw 		/* FIXME: check TITAN BAR1 offsets */
2237eced415Sxw 		return XGE_HAL_ERR_INVALID_DEVICE;
224a23fd118Syl 	} else {
225a23fd118Syl 		return XGE_HAL_ERR_INVALID_BAR_ID;
226a23fd118Syl 	}
227a23fd118Syl 
228a23fd118Syl 	return XGE_HAL_OK;
229a23fd118Syl }
230a23fd118Syl 
231a23fd118Syl /**
232a23fd118Syl  * xge_hal_mgmt_hw_stats - Get Xframe hardware statistics.
233a23fd118Syl  * @devh: HAL device handle.
234a23fd118Syl  * @hw_stats: Hardware statistics. Returned by HAL.
235a23fd118Syl  *            See xge_hal_stats_hw_info_t{}.
236a23fd118Syl  * @size: Size of the @hw_stats buffer. HAL will return an error
237a23fd118Syl  * if the size is smaller than sizeof(xge_hal_stats_hw_info_t).
238a23fd118Syl  * Get Xframe hardware statistics.
239a23fd118Syl  *
240a23fd118Syl  * Returns: XGE_HAL_OK - success.
241a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
242a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
243a23fd118Syl  *
244a23fd118Syl  * See also: xge_hal_mgmt_sw_stats().
245a23fd118Syl  */
246a23fd118Syl xge_hal_status_e
xge_hal_mgmt_hw_stats(xge_hal_device_h devh,xge_hal_mgmt_hw_stats_t * hw_stats,int size)247a23fd118Syl xge_hal_mgmt_hw_stats(xge_hal_device_h devh, xge_hal_mgmt_hw_stats_t *hw_stats,
248a23fd118Syl 		int size)
249a23fd118Syl {
250a23fd118Syl 	xge_hal_status_e status;
251a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
252a23fd118Syl 	xge_hal_stats_hw_info_t	*hw_info;
253a23fd118Syl 
2547eced415Sxw 	xge_assert(xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN);
2557eced415Sxw 
256a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
257a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
258a23fd118Syl 	}
259a23fd118Syl 
260a23fd118Syl 	if (size != sizeof(xge_hal_stats_hw_info_t)) {
261a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
262a23fd118Syl 	}
263a23fd118Syl 
264a23fd118Syl 	if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
265a23fd118Syl 		return status;
266a23fd118Syl 	}
267a23fd118Syl 
268a23fd118Syl 	xge_os_memcpy(hw_stats, hw_info, sizeof(xge_hal_stats_hw_info_t));
269a23fd118Syl 
270a23fd118Syl 	return XGE_HAL_OK;
271a23fd118Syl }
272a23fd118Syl 
273a23fd118Syl /**
2748347601bSyl  * xge_hal_mgmt_hw_stats_off - TBD.
2758347601bSyl  * @devh: HAL device handle.
2768347601bSyl  * @off: TBD
2778347601bSyl  * @size: TBD
2788347601bSyl  * @out: TBD
2798347601bSyl  *
2808347601bSyl  * Returns: XGE_HAL_OK - success.
2818347601bSyl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
2828347601bSyl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
2838347601bSyl  *
2848347601bSyl  * See also: xge_hal_mgmt_sw_stats().
285a23fd118Syl  */
286a23fd118Syl xge_hal_status_e
xge_hal_mgmt_hw_stats_off(xge_hal_device_h devh,int off,int size,char * out)287a23fd118Syl xge_hal_mgmt_hw_stats_off(xge_hal_device_h devh, int off, int size, char *out)
288a23fd118Syl {
289a23fd118Syl 	xge_hal_status_e status;
290a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
291a23fd118Syl 	xge_hal_stats_hw_info_t	*hw_info;
292a23fd118Syl 
2937eced415Sxw 	xge_assert(xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN);
2947eced415Sxw 
295a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
296a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
297a23fd118Syl 	}
298a23fd118Syl 
299a23fd118Syl 	if (off > sizeof(xge_hal_stats_hw_info_t)-4 ||
300a23fd118Syl 	    size > 8) {
301a23fd118Syl 		return XGE_HAL_ERR_INVALID_OFFSET;
302a23fd118Syl 	}
303a23fd118Syl 
304a23fd118Syl 	if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
305a23fd118Syl 		return status;
306a23fd118Syl 	}
307a23fd118Syl 
308a23fd118Syl 	xge_os_memcpy(out, (char*)hw_info + off, size);
309a23fd118Syl 
310a23fd118Syl 	return XGE_HAL_OK;
311a23fd118Syl }
312a23fd118Syl 
3137eced415Sxw /**
3147eced415Sxw  * xge_hal_mgmt_pcim_stats - Get Titan hardware statistics.
3157eced415Sxw  * @devh: HAL device handle.
3167eced415Sxw  * @pcim_stats: PCIM statistics. Returned by HAL.
3177eced415Sxw  *            See xge_hal_stats_hw_info_t{}.
3187eced415Sxw  * @size: Size of the @hw_stats buffer. HAL will return an error
3197eced415Sxw  * if the size is smaller than sizeof(xge_hal_stats_hw_info_t).
3207eced415Sxw  * Get Xframe hardware statistics.
3217eced415Sxw  *
3227eced415Sxw  * Returns: XGE_HAL_OK - success.
3237eced415Sxw  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
3247eced415Sxw  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
3257eced415Sxw  *
3267eced415Sxw  * See also: xge_hal_mgmt_sw_stats().
3277eced415Sxw  */
3287eced415Sxw xge_hal_status_e
xge_hal_mgmt_pcim_stats(xge_hal_device_h devh,xge_hal_mgmt_pcim_stats_t * pcim_stats,int size)3297eced415Sxw xge_hal_mgmt_pcim_stats(xge_hal_device_h devh,
3307eced415Sxw 		xge_hal_mgmt_pcim_stats_t *pcim_stats, int size)
3317eced415Sxw {
3327eced415Sxw 	xge_hal_status_e status;
3337eced415Sxw 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
3347eced415Sxw 	xge_hal_stats_pcim_info_t	*pcim_info;
3357eced415Sxw 
3367eced415Sxw 	xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN);
3377eced415Sxw 
3387eced415Sxw 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
3397eced415Sxw 		return XGE_HAL_ERR_INVALID_DEVICE;
3407eced415Sxw 	}
3417eced415Sxw 
3427eced415Sxw 	if (size != sizeof(xge_hal_stats_pcim_info_t)) {
3437eced415Sxw 		return XGE_HAL_ERR_VERSION_CONFLICT;
3447eced415Sxw 	}
3457eced415Sxw 
3467eced415Sxw 	if ((status = xge_hal_stats_pcim (devh, &pcim_info)) != XGE_HAL_OK) {
3477eced415Sxw 		return status;
3487eced415Sxw 	}
3497eced415Sxw 
3507eced415Sxw 	xge_os_memcpy(pcim_stats, pcim_info,
3517eced415Sxw 		sizeof(xge_hal_stats_pcim_info_t));
3527eced415Sxw 
3537eced415Sxw 	return XGE_HAL_OK;
3547eced415Sxw }
3557eced415Sxw 
3567eced415Sxw /**
3577eced415Sxw  * xge_hal_mgmt_pcim_stats_off - TBD.
3587eced415Sxw  * @devh: HAL device handle.
3597eced415Sxw  * @off: TBD
3607eced415Sxw  * @size: TBD
3617eced415Sxw  * @out: TBD
3627eced415Sxw  *
3637eced415Sxw  * Returns: XGE_HAL_OK - success.
3647eced415Sxw  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
3657eced415Sxw  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
3667eced415Sxw  *
3677eced415Sxw  * See also: xge_hal_mgmt_sw_stats().
3687eced415Sxw  */
3697eced415Sxw xge_hal_status_e
xge_hal_mgmt_pcim_stats_off(xge_hal_device_h devh,int off,int size,char * out)3707eced415Sxw xge_hal_mgmt_pcim_stats_off(xge_hal_device_h devh, int off, int size,
3717eced415Sxw 			    char *out)
3727eced415Sxw {
3737eced415Sxw 	xge_hal_status_e status;
3747eced415Sxw 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
3757eced415Sxw 	xge_hal_stats_pcim_info_t	*pcim_info;
3767eced415Sxw 
3777eced415Sxw 	xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN);
3787eced415Sxw 
3797eced415Sxw 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
3807eced415Sxw 		return XGE_HAL_ERR_INVALID_DEVICE;
3817eced415Sxw 	}
3827eced415Sxw 
3837eced415Sxw 	if (off > sizeof(xge_hal_stats_pcim_info_t)-8 ||
3847eced415Sxw 	    size > 8) {
3857eced415Sxw 		return XGE_HAL_ERR_INVALID_OFFSET;
3867eced415Sxw 	}
3877eced415Sxw 
3887eced415Sxw 	if ((status = xge_hal_stats_pcim (devh, &pcim_info)) != XGE_HAL_OK) {
3897eced415Sxw 		return status;
3907eced415Sxw 	}
3917eced415Sxw 
3927eced415Sxw 	xge_os_memcpy(out, (char*)pcim_info + off, size);
3937eced415Sxw 
3947eced415Sxw 	return XGE_HAL_OK;
3957eced415Sxw }
3967eced415Sxw 
397a23fd118Syl /**
398a23fd118Syl  * xge_hal_mgmt_sw_stats - Get per-device software statistics.
399a23fd118Syl  * @devh: HAL device handle.
400a23fd118Syl  * @sw_stats: Hardware statistics. Returned by HAL.
401a23fd118Syl  *            See xge_hal_stats_sw_err_t{}.
402a23fd118Syl  * @size: Size of the @sw_stats buffer. HAL will return an error
403a23fd118Syl  * if the size is smaller than sizeof(xge_hal_stats_sw_err_t).
404a23fd118Syl  * Get device software statistics, including ECC and Parity error
405a23fd118Syl  * counters, etc.
406a23fd118Syl  *
407a23fd118Syl  * Returns: XGE_HAL_OK - success.
408a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
409a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
410a23fd118Syl  *
411a23fd118Syl  * See also: xge_hal_stats_sw_err_t{}, xge_hal_mgmt_hw_stats().
412a23fd118Syl  */
413a23fd118Syl xge_hal_status_e
xge_hal_mgmt_sw_stats(xge_hal_device_h devh,xge_hal_mgmt_sw_stats_t * sw_stats,int size)414a23fd118Syl xge_hal_mgmt_sw_stats(xge_hal_device_h devh, xge_hal_mgmt_sw_stats_t *sw_stats,
415a23fd118Syl 		int size)
416a23fd118Syl {
417a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
418a23fd118Syl 
419a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
420a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
421a23fd118Syl 	}
422a23fd118Syl 
423a23fd118Syl 	if (size != sizeof(xge_hal_stats_sw_err_t)) {
424a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
425a23fd118Syl 	}
426a23fd118Syl 
427a23fd118Syl 	if (!hldev->stats.is_initialized ||
428a23fd118Syl 	    !hldev->stats.is_enabled) {
429a23fd118Syl 		return XGE_HAL_INF_STATS_IS_NOT_READY;
430a23fd118Syl 	}
431a23fd118Syl 
4328347601bSyl 	/* Updating xpak stats value */
4338347601bSyl 	__hal_updt_stats_xpak(hldev);
4348347601bSyl 
435a23fd118Syl 	xge_os_memcpy(sw_stats, &hldev->stats.sw_dev_err_stats,
436a23fd118Syl 	            sizeof(xge_hal_stats_sw_err_t));
437a23fd118Syl 
438a23fd118Syl 	return XGE_HAL_OK;
439a23fd118Syl }
440a23fd118Syl 
441a23fd118Syl /**
442a23fd118Syl  * xge_hal_mgmt_device_stats - Get HAL device statistics.
443a23fd118Syl  * @devh: HAL device handle.
444a23fd118Syl  * @device_stats: HAL device "soft" statistics. Maintained by HAL itself.
445a23fd118Syl  *            (as opposed to xge_hal_mgmt_hw_stats() - those are
446a23fd118Syl  *            maintained by the Xframe hardware).
447a23fd118Syl  *            Returned by HAL.
448a23fd118Syl  *            See xge_hal_stats_device_info_t{}.
449a23fd118Syl  * @size: Size of the @device_stats buffer. HAL will return an error
450a23fd118Syl  * if the size is smaller than sizeof(xge_hal_stats_device_info_t).
451a23fd118Syl  *
452a23fd118Syl  * Get HAL (layer) statistic counters.
453a23fd118Syl  * Returns: XGE_HAL_OK - success.
454a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
455a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
456a23fd118Syl  * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
457a23fd118Syl  * currently available.
458a23fd118Syl  *
459a23fd118Syl  */
460a23fd118Syl xge_hal_status_e
xge_hal_mgmt_device_stats(xge_hal_device_h devh,xge_hal_mgmt_device_stats_t * device_stats,int size)461a23fd118Syl xge_hal_mgmt_device_stats(xge_hal_device_h devh,
462a23fd118Syl 		xge_hal_mgmt_device_stats_t *device_stats, int size)
463a23fd118Syl {
464a23fd118Syl 	xge_hal_status_e status;
465a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
466a23fd118Syl 	xge_hal_stats_device_info_t *device_info;
467a23fd118Syl 
468a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
469a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
470a23fd118Syl 	}
471a23fd118Syl 
472a23fd118Syl 	if (size != sizeof(xge_hal_stats_device_info_t)) {
473a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
474a23fd118Syl 	}
475a23fd118Syl 
476a23fd118Syl 	if ((status = xge_hal_stats_device (devh, &device_info)) !=
477a23fd118Syl 	XGE_HAL_OK) {
478a23fd118Syl 		return status;
479a23fd118Syl 	}
480a23fd118Syl 
481a23fd118Syl 	xge_os_memcpy(device_stats, device_info,
482a23fd118Syl 		    sizeof(xge_hal_stats_device_info_t));
483a23fd118Syl 
484a23fd118Syl 	return XGE_HAL_OK;
485a23fd118Syl }
486a23fd118Syl 
487a23fd118Syl /*
488a23fd118Syl  * __hal_update_ring_bump - Update the ring bump counter for the
489a23fd118Syl  * particular channel.
490a23fd118Syl  * @hldev: HAL device handle.
491a23fd118Syl  * @queue: the queue who's data is to be collected.
492a23fd118Syl  * @chinfo: pointer to the statistics structure of the given channel.
493a23fd118Syl  * Usage: See xge_hal_aux_stats_hal_read{}
494a23fd118Syl  */
495a23fd118Syl 
496a23fd118Syl static void
__hal_update_ring_bump(xge_hal_device_t * hldev,int queue,xge_hal_stats_channel_info_t * chinfo)497a23fd118Syl __hal_update_ring_bump(xge_hal_device_t *hldev, int queue,
498a23fd118Syl 	xge_hal_stats_channel_info_t *chinfo)
499a23fd118Syl {
500a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
501a23fd118Syl 	u64 rbc = 0;
502a23fd118Syl 	int reg = (queue / 4);
503a23fd118Syl 	void * addr;
504a23fd118Syl 
505a23fd118Syl 	addr = (reg == 1)? (&bar0->ring_bump_counter2) :
506a23fd118Syl 		(&bar0->ring_bump_counter1);
507a23fd118Syl 	rbc = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, addr);
508a23fd118Syl 	chinfo->ring_bump_cnt = XGE_HAL_RING_BUMP_CNT(queue, rbc);
509a23fd118Syl }
510a23fd118Syl 
511a23fd118Syl /**
512a23fd118Syl  * xge_hal_mgmt_channel_stats - Get HAL channel statistics.
513a23fd118Syl  * @channelh: HAL channel handle.
514a23fd118Syl  * @channel_stats: HAL channel statistics. Maintained by HAL itself
515a23fd118Syl  *            (as opposed to xge_hal_mgmt_hw_stats() - those are
516a23fd118Syl  *            maintained by the Xframe hardware).
517a23fd118Syl  *            Returned by HAL.
518a23fd118Syl  *            See xge_hal_stats_channel_info_t{}.
519a23fd118Syl  * @size: Size of the @channel_stats buffer. HAL will return an error
520a23fd118Syl  * if the size is smaller than sizeof(xge_hal_mgmt_channel_stats_t).
521a23fd118Syl  *
522a23fd118Syl  * Get HAL per-channel statistic counters.
523a23fd118Syl  *
524a23fd118Syl  * Returns: XGE_HAL_OK - success.
525a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
526a23fd118Syl  * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
527a23fd118Syl  * currently available.
528a23fd118Syl  *
529a23fd118Syl  */
530a23fd118Syl xge_hal_status_e
xge_hal_mgmt_channel_stats(xge_hal_channel_h channelh,xge_hal_mgmt_channel_stats_t * channel_stats,int size)531a23fd118Syl xge_hal_mgmt_channel_stats(xge_hal_channel_h channelh,
532a23fd118Syl 		xge_hal_mgmt_channel_stats_t *channel_stats, int size)
533a23fd118Syl {
534a23fd118Syl 	xge_hal_status_e status;
535a23fd118Syl 	xge_hal_stats_channel_info_t *channel_info;
5368347601bSyl 	xge_hal_channel_t *channel = (xge_hal_channel_t* ) channelh;
537a23fd118Syl 
538a23fd118Syl 	if (size != sizeof(xge_hal_stats_channel_info_t)) {
539a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
540a23fd118Syl 	}
541a23fd118Syl 
542a23fd118Syl 	if ((status = xge_hal_stats_channel (channelh, &channel_info)) !=
543a23fd118Syl 								XGE_HAL_OK) {
544a23fd118Syl 		return status;
545a23fd118Syl 	}
546a23fd118Syl 
547a23fd118Syl 	if (xge_hal_device_check_id(channel->devh) == XGE_HAL_CARD_HERC) {
5488347601bSyl         __hal_update_ring_bump( (xge_hal_device_t *) channel->devh, channel->post_qid, channel_info);
549a23fd118Syl 	}
550a23fd118Syl 
551a23fd118Syl 	xge_os_memcpy(channel_stats, channel_info,
552a23fd118Syl 		    sizeof(xge_hal_stats_channel_info_t));
553a23fd118Syl 
554a23fd118Syl 	return XGE_HAL_OK;
555a23fd118Syl }
556a23fd118Syl 
557a23fd118Syl /**
558a23fd118Syl  * xge_hal_mgmt_pcireg_read - Read PCI configuration at a specified
559a23fd118Syl  * offset.
560a23fd118Syl  * @devh: HAL device handle.
561a23fd118Syl  * @offset: Offset in the 256 byte PCI configuration space.
562a23fd118Syl  * @value_bits: 8, 16, or 32 (bits) to read.
563a23fd118Syl  * @value: Value returned by HAL.
564a23fd118Syl  *
565a23fd118Syl  * Read PCI configuration, given device and offset in the PCI space.
566a23fd118Syl  *
567a23fd118Syl  * Returns: XGE_HAL_OK - success.
568a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
569a23fd118Syl  * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
570a23fd118Syl  * valid.
571a23fd118Syl  * XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE - Invalid bits size. Valid
572a23fd118Syl  * values(8/16/32).
573a23fd118Syl  *
574a23fd118Syl  */
575a23fd118Syl xge_hal_status_e
xge_hal_mgmt_pcireg_read(xge_hal_device_h devh,unsigned int offset,int value_bits,u32 * value)576a23fd118Syl xge_hal_mgmt_pcireg_read(xge_hal_device_h devh, unsigned int offset,
577a23fd118Syl 		int value_bits, u32 *value)
578a23fd118Syl {
579a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
580a23fd118Syl 
581a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
582a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
583a23fd118Syl 	}
584a23fd118Syl 
585a23fd118Syl 	if (offset > sizeof(xge_hal_pci_config_t)-value_bits/8) {
586a23fd118Syl 		return XGE_HAL_ERR_INVALID_OFFSET;
587a23fd118Syl 	}
588a23fd118Syl 
589a23fd118Syl 	if (value_bits == 8) {
590a23fd118Syl 		xge_os_pci_read8(hldev->pdev, hldev->cfgh, offset, (u8*)value);
591a23fd118Syl 	} else if (value_bits == 16) {
592a23fd118Syl 		xge_os_pci_read16(hldev->pdev, hldev->cfgh, offset,
593a23fd118Syl 		(u16*)value);
594a23fd118Syl 	} else if (value_bits == 32) {
595a23fd118Syl 		xge_os_pci_read32(hldev->pdev, hldev->cfgh, offset, value);
596a23fd118Syl 	} else {
597a23fd118Syl 		return XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE;
598a23fd118Syl 	}
599a23fd118Syl 
600a23fd118Syl 	return XGE_HAL_OK;
601a23fd118Syl }
602a23fd118Syl 
603a23fd118Syl /**
604a23fd118Syl  * xge_hal_mgmt_device_config - Retrieve device configuration.
605a23fd118Syl  * @devh: HAL device handle.
606a23fd118Syl  * @dev_config: Device configuration, see xge_hal_device_config_t{}.
607a23fd118Syl  * @size: Size of the @dev_config buffer. HAL will return an error
608a23fd118Syl  * if the size is smaller than sizeof(xge_hal_mgmt_device_config_t).
609a23fd118Syl  *
610a23fd118Syl  * Get device configuration. Permits to retrieve at run-time configuration
611a23fd118Syl  * values that were used to initialize and configure the device.
612a23fd118Syl  *
613a23fd118Syl  * Returns: XGE_HAL_OK - success.
614a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
615a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
616a23fd118Syl  *
617a23fd118Syl  * See also: xge_hal_device_config_t{}, xge_hal_mgmt_driver_config().
618a23fd118Syl  */
619a23fd118Syl xge_hal_status_e
xge_hal_mgmt_device_config(xge_hal_device_h devh,xge_hal_mgmt_device_config_t * dev_config,int size)620a23fd118Syl xge_hal_mgmt_device_config(xge_hal_device_h devh,
621a23fd118Syl 		xge_hal_mgmt_device_config_t	*dev_config, int size)
622a23fd118Syl {
623a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
624a23fd118Syl 
625a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
626a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
627a23fd118Syl 	}
628a23fd118Syl 
629a23fd118Syl 	if (size != sizeof(xge_hal_mgmt_device_config_t)) {
630a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
631a23fd118Syl 	}
632a23fd118Syl 
633a23fd118Syl 	xge_os_memcpy(dev_config, &hldev->config,
634a23fd118Syl 	sizeof(xge_hal_device_config_t));
635a23fd118Syl 
636a23fd118Syl 	return XGE_HAL_OK;
637a23fd118Syl }
638a23fd118Syl 
639a23fd118Syl /**
640a23fd118Syl  * xge_hal_mgmt_driver_config - Retrieve driver configuration.
641a23fd118Syl  * @drv_config: Device configuration, see xge_hal_driver_config_t{}.
642a23fd118Syl  * @size: Size of the @dev_config buffer. HAL will return an error
643a23fd118Syl  * if the size is smaller than sizeof(xge_hal_mgmt_driver_config_t).
644a23fd118Syl  *
645a23fd118Syl  * Get driver configuration. Permits to retrieve at run-time configuration
646a23fd118Syl  * values that were used to configure the device at load-time.
647a23fd118Syl  *
648a23fd118Syl  * Returns: XGE_HAL_OK - success.
649a23fd118Syl  * XGE_HAL_ERR_DRIVER_NOT_INITIALIZED - HAL is not initialized.
650a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version is not maching.
651a23fd118Syl  *
652a23fd118Syl  * See also: xge_hal_driver_config_t{}, xge_hal_mgmt_device_config().
653a23fd118Syl  */
654a23fd118Syl xge_hal_status_e
xge_hal_mgmt_driver_config(xge_hal_mgmt_driver_config_t * drv_config,int size)655a23fd118Syl xge_hal_mgmt_driver_config(xge_hal_mgmt_driver_config_t *drv_config, int size)
656a23fd118Syl {
657a23fd118Syl 
658a23fd118Syl 	if (g_xge_hal_driver == NULL) {
659a23fd118Syl 		return XGE_HAL_ERR_DRIVER_NOT_INITIALIZED;
660a23fd118Syl 	}
661a23fd118Syl 
662a23fd118Syl 	if (size != sizeof(xge_hal_mgmt_driver_config_t)) {
663a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
664a23fd118Syl 	}
665a23fd118Syl 
666a23fd118Syl 	xge_os_memcpy(drv_config, &g_xge_hal_driver->config,
667a23fd118Syl 		    sizeof(xge_hal_mgmt_driver_config_t));
668a23fd118Syl 
669a23fd118Syl 	return XGE_HAL_OK;
670a23fd118Syl }
671a23fd118Syl 
672a23fd118Syl /**
673a23fd118Syl  * xge_hal_mgmt_pci_config - Retrieve PCI configuration.
674a23fd118Syl  * @devh: HAL device handle.
675a23fd118Syl  * @pci_config: 256 byte long buffer for PCI configuration space.
676a23fd118Syl  * @size: Size of the @ buffer. HAL will return an error
677a23fd118Syl  * if the size is smaller than sizeof(xge_hal_mgmt_pci_config_t).
678a23fd118Syl  *
679a23fd118Syl  * Get PCI configuration. Permits to retrieve at run-time configuration
680a23fd118Syl  * values that were used to configure the device at load-time.
681a23fd118Syl  *
682a23fd118Syl  * Returns: XGE_HAL_OK - success.
683a23fd118Syl  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
684a23fd118Syl  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
685a23fd118Syl  *
686a23fd118Syl  */
687a23fd118Syl xge_hal_status_e
xge_hal_mgmt_pci_config(xge_hal_device_h devh,xge_hal_mgmt_pci_config_t * pci_config,int size)688a23fd118Syl xge_hal_mgmt_pci_config(xge_hal_device_h devh,
689a23fd118Syl 		xge_hal_mgmt_pci_config_t *pci_config, int size)
690a23fd118Syl {
691a23fd118Syl 	int i;
692a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
693a23fd118Syl 
694a23fd118Syl 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
695a23fd118Syl 		return XGE_HAL_ERR_INVALID_DEVICE;
696a23fd118Syl 	}
697a23fd118Syl 
698a23fd118Syl 	if (size != sizeof(xge_hal_mgmt_pci_config_t)) {
699a23fd118Syl 		return XGE_HAL_ERR_VERSION_CONFLICT;
700a23fd118Syl 	}
701a23fd118Syl 
702a23fd118Syl 	/* refresh PCI config space */
703a23fd118Syl 	for (i = 0; i < 0x68/4+1; i++) {
704a23fd118Syl 		xge_os_pci_read32(hldev->pdev, hldev->cfgh, i*4,
705a23fd118Syl 		                (u32*)&hldev->pci_config_space + i);
706a23fd118Syl 	}
707a23fd118Syl 
708a23fd118Syl 	xge_os_memcpy(pci_config, &hldev->pci_config_space,
709a23fd118Syl 		    sizeof(xge_hal_mgmt_pci_config_t));
710a23fd118Syl 
711a23fd118Syl 	return XGE_HAL_OK;
712a23fd118Syl }
713a23fd118Syl 
714a23fd118Syl #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
715a23fd118Syl /**
716a23fd118Syl  * xge_hal_mgmt_trace_read - Read trace buffer contents.
717a23fd118Syl  * @buffer: Buffer to store the trace buffer contents.
718a23fd118Syl  * @buf_size: Size of the buffer.
719a23fd118Syl  * @offset: Offset in the internal trace buffer to read data.
720a23fd118Syl  * @read_length: Size of the valid data in the buffer.
721a23fd118Syl  *
722a23fd118Syl  * Read  HAL trace buffer contents starting from the offset
723a23fd118Syl  * upto the size of the buffer or till EOF is reached.
724a23fd118Syl  *
725a23fd118Syl  * Returns: XGE_HAL_OK - success.
726a23fd118Syl  * XGE_HAL_EOF_TRACE_BUF - No more data in the trace buffer.
727a23fd118Syl  *
728a23fd118Syl  */
729a23fd118Syl xge_hal_status_e
xge_hal_mgmt_trace_read(char * buffer,unsigned buf_size,unsigned * offset,unsigned * read_length)730a23fd118Syl xge_hal_mgmt_trace_read (char		*buffer,
731a23fd118Syl 			unsigned	buf_size,
732a23fd118Syl 			unsigned	*offset,
733a23fd118Syl 			unsigned	*read_length)
734a23fd118Syl {
735a23fd118Syl 	int data_offset;
736a23fd118Syl 	int start_offset;
737a23fd118Syl 
738a23fd118Syl 	if ((g_xge_os_tracebuf == NULL) ||
739a23fd118Syl 		(g_xge_os_tracebuf->offset == g_xge_os_tracebuf->size - 2)) {
740a23fd118Syl 		return XGE_HAL_EOF_TRACE_BUF;
741a23fd118Syl 	}
742a23fd118Syl 
743a23fd118Syl 	data_offset = g_xge_os_tracebuf->offset + 1;
744a23fd118Syl 
745a23fd118Syl 	if  (*offset >= (unsigned)xge_os_strlen(g_xge_os_tracebuf->data +
746a23fd118Syl 	data_offset)) {
747a23fd118Syl 
748a23fd118Syl 		return XGE_HAL_EOF_TRACE_BUF;
749a23fd118Syl 	}
750a23fd118Syl 
751a23fd118Syl 	xge_os_memzero(buffer, buf_size);
752a23fd118Syl 
753a23fd118Syl 	start_offset  =  data_offset + *offset;
754a23fd118Syl 	*read_length = xge_os_strlen(g_xge_os_tracebuf->data +
755a23fd118Syl 	start_offset);
756a23fd118Syl 
757a23fd118Syl 	if (*read_length  >=  buf_size) {
758a23fd118Syl 		*read_length = buf_size - 1;
759a23fd118Syl 	}
760a23fd118Syl 
761a23fd118Syl 	xge_os_memcpy(buffer, g_xge_os_tracebuf->data + start_offset,
762a23fd118Syl 	*read_length);
763a23fd118Syl 
764a23fd118Syl 	*offset += *read_length;
765a23fd118Syl 	(*read_length) ++;
766a23fd118Syl 
767a23fd118Syl 	return XGE_HAL_OK;
768a23fd118Syl }
769a23fd118Syl 
770a23fd118Syl #endif
771a23fd118Syl 
772a23fd118Syl /**
773a23fd118Syl  * xge_hal_restore_link_led - Restore link LED to its original state.
774a23fd118Syl  * @devh: HAL device handle.
775a23fd118Syl  */
776a23fd118Syl void
xge_hal_restore_link_led(xge_hal_device_h devh)777a23fd118Syl xge_hal_restore_link_led(xge_hal_device_h devh)
778a23fd118Syl {
779a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
780a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
781a23fd118Syl 	u64 val64;
782a23fd118Syl 
783a23fd118Syl 	/*
784a23fd118Syl 	 * If the current link state is UP, switch on LED else make it
785a23fd118Syl 	 * off.
786a23fd118Syl 	 */
787a23fd118Syl 
788a23fd118Syl 	/*
789a23fd118Syl 	 * For Xena 3 and lower revision cards, adapter control needs to be
790a23fd118Syl 	 * used for making LED ON/OFF.
791a23fd118Syl 	 */
792a23fd118Syl 	if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
793a23fd118Syl 	   (xge_hal_device_rev(hldev) <= 3)) {
794a23fd118Syl 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
795a23fd118Syl 					      &bar0->adapter_control);
796a23fd118Syl 		if (hldev->link_state == XGE_HAL_LINK_UP) {
797a23fd118Syl 			val64 |= XGE_HAL_ADAPTER_LED_ON;
798a23fd118Syl 		} else {
799a23fd118Syl 			val64 &= ~XGE_HAL_ADAPTER_LED_ON;
800a23fd118Syl 		}
801a23fd118Syl 
802a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
803a23fd118Syl 					&bar0->adapter_control);
804a23fd118Syl 		return;
805a23fd118Syl 	}
806a23fd118Syl 
807a23fd118Syl 	/*
808a23fd118Syl 	 * Use beacon control register to control the LED.
809a23fd118Syl 	 * LED link output corresponds to bit 8 of the beacon control
810a23fd118Syl 	 * register. Note that, in the case of Xena, beacon control register
811a23fd118Syl 	 * represents the gpio control register. In the case of Herc, LED
812a23fd118Syl 	 * handling is done by beacon control register as opposed to gpio
8137eced415Sxw 	 * control register in Xena. Beacon control is used only to toggle
8147eced415Sxw      * and the value written into it does not depend on the link state.
815*55fea89dSDan Cross      * It is upto the ULD to toggle the LED even number of times which
816*55fea89dSDan Cross      * brings the LED to it's original state.
817a23fd118Syl 	 */
818a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
819a23fd118Syl 				      &bar0->beacon_control);
8207eced415Sxw     val64 |= 0x0000800000000000ULL;
8217eced415Sxw     xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
8227eced415Sxw     		       val64, &bar0->beacon_control);
823a23fd118Syl }
824a23fd118Syl 
825a23fd118Syl /**
826a23fd118Syl  * xge_hal_flick_link_led - Flick (blink) link LED.
827a23fd118Syl  * @devh: HAL device handle.
828a23fd118Syl  *
829a23fd118Syl  * Depending on the card revision flicker the link LED by using the
830a23fd118Syl  * beacon control or the adapter_control register.
831a23fd118Syl  */
832a23fd118Syl void
xge_hal_flick_link_led(xge_hal_device_h devh)833a23fd118Syl xge_hal_flick_link_led(xge_hal_device_h devh)
834a23fd118Syl {
835a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
836a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
837a23fd118Syl 	u64 val64 = 0;
838a23fd118Syl 
839a23fd118Syl 	/*
840a23fd118Syl 	 * For Xena 3 and lower revision cards, adapter control needs to be
841a23fd118Syl 	 * used for making LED ON/OFF.
842a23fd118Syl 	 */
843a23fd118Syl 	if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
844a23fd118Syl 	   (xge_hal_device_rev(hldev) <= 3)) {
845a23fd118Syl 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
846a23fd118Syl 					      &bar0->adapter_control);
847a23fd118Syl 		val64 ^= XGE_HAL_ADAPTER_LED_ON;
848a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
849a23fd118Syl 					&bar0->adapter_control);
850a23fd118Syl 		return;
851a23fd118Syl 	}
852a23fd118Syl 
853a23fd118Syl 	/*
854a23fd118Syl 	 * Use beacon control register to control the Link LED.
855a23fd118Syl 	 * Note that, in the case of Xena, beacon control register represents
856a23fd118Syl 	 * the gpio control register. In the case of Herc, LED handling is
857a23fd118Syl 	 * done by beacon control register as opposed to gpio control register
858a23fd118Syl 	 * in Xena.
859a23fd118Syl 	 */
860a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
861a23fd118Syl 				      &bar0->beacon_control);
862a23fd118Syl 	val64 ^= XGE_HAL_GPIO_CTRL_GPIO_0;
863a23fd118Syl 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
864a23fd118Syl 			       &bar0->beacon_control);
865a23fd118Syl }
866a23fd118Syl 
867a23fd118Syl /**
868a23fd118Syl  * xge_hal_read_eeprom - Read 4 bytes of data from user given offset.
869a23fd118Syl  * @devh: HAL device handle.
870a23fd118Syl  * @off: offset at which the data must be written
871a23fd118Syl  * @data: output parameter where the data is stored.
872a23fd118Syl  *
873a23fd118Syl  * Read 4 bytes of data from the user given offset and return the
874a23fd118Syl  * read data.
875a23fd118Syl  * Note: will allow to read only part of the EEPROM visible through the
876a23fd118Syl  * I2C bus.
877a23fd118Syl  * Returns: -1 on failure, 0 on success.
878a23fd118Syl  */
879a23fd118Syl xge_hal_status_e
xge_hal_read_eeprom(xge_hal_device_h devh,int off,u32 * data)8808347601bSyl xge_hal_read_eeprom(xge_hal_device_h devh, int off, u32* data)
881a23fd118Syl {
882a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
8838347601bSyl 	xge_hal_status_e ret = XGE_HAL_FAIL;
884a23fd118Syl 	u32 exit_cnt = 0;
885a23fd118Syl 	u64 val64;
886a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
887a23fd118Syl 
888a23fd118Syl 	val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) |
889a23fd118Syl 		XGE_HAL_I2C_CONTROL_ADDR(off) |
890a23fd118Syl 		XGE_HAL_I2C_CONTROL_BYTE_CNT(0x3) |
891a23fd118Syl 		XGE_HAL_I2C_CONTROL_READ | XGE_HAL_I2C_CONTROL_CNTL_START;
892a23fd118Syl 
8937eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
894a23fd118Syl 
895a23fd118Syl 	while (exit_cnt < 5) {
8967eced415Sxw 		val64 = __hal_serial_mem_read64(hldev, &bar0->i2c_control);
897a23fd118Syl 		if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) {
898a23fd118Syl 			*data = XGE_HAL_I2C_CONTROL_GET_DATA(val64);
899a23fd118Syl 			ret = XGE_HAL_OK;
900a23fd118Syl 			break;
901a23fd118Syl 		}
902a23fd118Syl 		exit_cnt++;
903a23fd118Syl 	}
904a23fd118Syl 
905a23fd118Syl 	return ret;
906a23fd118Syl }
907a23fd118Syl 
908a23fd118Syl /*
909a23fd118Syl  * xge_hal_write_eeprom - actually writes the relevant part of the data
910a23fd118Syl  value.
911a23fd118Syl  * @devh: HAL device handle.
912a23fd118Syl  * @off: offset at which the data must be written
913a23fd118Syl  * @data : The data that is to be written
914a23fd118Syl  * @cnt : Number of bytes of the data that are actually to be written into
915a23fd118Syl  * the Eeprom. (max of 3)
916a23fd118Syl  *
917a23fd118Syl  * Actually writes the relevant part of the data value into the Eeprom
918a23fd118Syl  * through the I2C bus.
919a23fd118Syl  * Return value:
920a23fd118Syl  * 0 on success, -1 on failure.
921a23fd118Syl  */
922a23fd118Syl 
923a23fd118Syl xge_hal_status_e
xge_hal_write_eeprom(xge_hal_device_h devh,int off,u32 data,int cnt)924a23fd118Syl xge_hal_write_eeprom(xge_hal_device_h devh, int off, u32 data, int cnt)
925a23fd118Syl {
926a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
9278347601bSyl 	xge_hal_status_e ret = XGE_HAL_FAIL;
9288347601bSyl 	u32 exit_cnt = 0;
929a23fd118Syl 	u64 val64;
930a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
931a23fd118Syl 
932a23fd118Syl 	val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) |
933a23fd118Syl 		XGE_HAL_I2C_CONTROL_ADDR(off) |
934a23fd118Syl 		XGE_HAL_I2C_CONTROL_BYTE_CNT(cnt) |
935a23fd118Syl 		XGE_HAL_I2C_CONTROL_SET_DATA(data) |
936a23fd118Syl 		XGE_HAL_I2C_CONTROL_CNTL_START;
9377eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
938a23fd118Syl 
939a23fd118Syl 	while (exit_cnt < 5) {
9407eced415Sxw 		val64 = __hal_serial_mem_read64(hldev, &bar0->i2c_control);
941a23fd118Syl 		if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) {
942a23fd118Syl 			if (!(val64 & XGE_HAL_I2C_CONTROL_NACK))
943a23fd118Syl 				ret = XGE_HAL_OK;
944a23fd118Syl 			break;
945a23fd118Syl 		}
946a23fd118Syl 		exit_cnt++;
947a23fd118Syl 	}
948a23fd118Syl 
949a23fd118Syl 	return ret;
950a23fd118Syl }
951a23fd118Syl 
952a23fd118Syl /*
953a23fd118Syl  * xge_hal_register_test - reads and writes into all clock domains.
954a23fd118Syl  * @hldev : private member of the device structure.
955a23fd118Syl  * xge_nic structure.
956a23fd118Syl  * @data : variable that returns the result of each of the test conducted b
957a23fd118Syl  * by the driver.
958a23fd118Syl  *
959a23fd118Syl  * Read and write into all clock domains. The NIC has 3 clock domains,
960a23fd118Syl  * see that registers in all the three regions are accessible.
961a23fd118Syl  * Return value:
962a23fd118Syl  * 0 on success.
963a23fd118Syl  */
964a23fd118Syl xge_hal_status_e
xge_hal_register_test(xge_hal_device_h devh,u64 * data)965a23fd118Syl xge_hal_register_test(xge_hal_device_h devh, u64 *data)
966a23fd118Syl {
967a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
968a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
969a23fd118Syl 	u64 val64 = 0;
970a23fd118Syl 	int fail = 0;
971a23fd118Syl 
972a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
973a23fd118Syl 			&bar0->pif_rd_swapper_fb);
974a23fd118Syl 	if (val64 != 0x123456789abcdefULL) {
975a23fd118Syl 		fail = 1;
9767eced415Sxw 		xge_debug_osdep(XGE_TRACE, "Read Test level 1 fails");
977a23fd118Syl 	}
978a23fd118Syl 
979a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
980a23fd118Syl 			&bar0->rmac_pause_cfg);
981a23fd118Syl 	if (val64 != 0xc000ffff00000000ULL) {
982a23fd118Syl 		fail = 1;
9837eced415Sxw 		xge_debug_osdep(XGE_TRACE, "Read Test level 2 fails");
984a23fd118Syl 	}
985a23fd118Syl 
986a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
987a23fd118Syl 			&bar0->rx_queue_cfg);
988a23fd118Syl 	if (val64 != 0x0808080808080808ULL) {
989a23fd118Syl 		fail = 1;
9907eced415Sxw 		xge_debug_osdep(XGE_TRACE, "Read Test level 3 fails");
991a23fd118Syl 	}
992a23fd118Syl 
993a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
994a23fd118Syl 			&bar0->xgxs_efifo_cfg);
995a23fd118Syl 	if (val64 != 0x000000001923141EULL) {
996a23fd118Syl 		fail = 1;
9977eced415Sxw 		xge_debug_osdep(XGE_TRACE, "Read Test level 4 fails");
998a23fd118Syl 	}
999a23fd118Syl 
1000a23fd118Syl 	val64 = 0x5A5A5A5A5A5A5A5AULL;
1001a23fd118Syl 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1002a23fd118Syl 			&bar0->xmsi_data);
1003a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1004a23fd118Syl 			&bar0->xmsi_data);
1005a23fd118Syl 	if (val64 != 0x5A5A5A5A5A5A5A5AULL) {
1006a23fd118Syl 		fail = 1;
10077eced415Sxw 		xge_debug_osdep(XGE_ERR, "Write Test level 1 fails");
1008a23fd118Syl 	}
1009a23fd118Syl 
1010a23fd118Syl 	val64 = 0xA5A5A5A5A5A5A5A5ULL;
1011a23fd118Syl 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1012a23fd118Syl 			&bar0->xmsi_data);
1013a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1014a23fd118Syl 			&bar0->xmsi_data);
1015a23fd118Syl 	if (val64 != 0xA5A5A5A5A5A5A5A5ULL) {
1016a23fd118Syl 		fail = 1;
10177eced415Sxw 		xge_debug_osdep(XGE_ERR, "Write Test level 2 fails");
1018a23fd118Syl 	}
1019a23fd118Syl 
1020a23fd118Syl 	*data = fail;
1021a23fd118Syl 	return XGE_HAL_OK;
1022a23fd118Syl }
1023a23fd118Syl 
1024a23fd118Syl /*
1025a23fd118Syl  * xge_hal_rldram_test - offline test for access to the RldRam chip on
1026a23fd118Syl  the NIC
1027a23fd118Syl  * @devh: HAL device handle.
1028a23fd118Syl  * @data: variable that returns the result of each of the test
1029a23fd118Syl  * conducted by the driver.
1030a23fd118Syl  *
1031a23fd118Syl  * This is one of the offline test that tests the read and write
1032a23fd118Syl  * access to the RldRam chip on the NIC.
1033a23fd118Syl  * Return value:
1034a23fd118Syl  * 0 on success.
1035a23fd118Syl  */
1036a23fd118Syl xge_hal_status_e
xge_hal_rldram_test(xge_hal_device_h devh,u64 * data)10378347601bSyl xge_hal_rldram_test(xge_hal_device_h devh, u64 *data)
1038a23fd118Syl {
1039a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1040a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1041a23fd118Syl 	u64 val64;
1042a23fd118Syl 	int cnt, iteration = 0, test_pass = 0;
1043a23fd118Syl 
1044a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1045a23fd118Syl 			&bar0->adapter_control);
1046a23fd118Syl 	val64 &= ~XGE_HAL_ADAPTER_ECC_EN;
1047a23fd118Syl 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1048a23fd118Syl 			&bar0->adapter_control);
1049a23fd118Syl 
1050a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1051a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
1052a23fd118Syl 	val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE;
1053a23fd118Syl 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1054a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
1055a23fd118Syl 
1056a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1057a23fd118Syl 			&bar0->mc_rldram_mrs);
1058a23fd118Syl 	val64 |= XGE_HAL_MC_RLDRAM_QUEUE_SIZE_ENABLE;
10597eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
1060a23fd118Syl 
1061a23fd118Syl 	val64 |= XGE_HAL_MC_RLDRAM_MRS_ENABLE;
10627eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
1063a23fd118Syl 
1064a23fd118Syl 	while (iteration < 2) {
1065a23fd118Syl 		val64 = 0x55555555aaaa0000ULL;
1066a23fd118Syl 		if (iteration == 1) {
1067a23fd118Syl 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
1068a23fd118Syl 		}
1069a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1070a23fd118Syl 			&bar0->mc_rldram_test_d0);
1071a23fd118Syl 
1072a23fd118Syl 		val64 = 0xaaaa5a5555550000ULL;
1073a23fd118Syl 		if (iteration == 1) {
1074a23fd118Syl 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
1075a23fd118Syl 		}
1076a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1077a23fd118Syl 			&bar0->mc_rldram_test_d1);
1078a23fd118Syl 
1079a23fd118Syl 		val64 = 0x55aaaaaaaa5a0000ULL;
1080a23fd118Syl 		if (iteration == 1) {
1081a23fd118Syl 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
1082a23fd118Syl 		}
1083a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1084a23fd118Syl 			&bar0->mc_rldram_test_d2);
1085a23fd118Syl 
1086a23fd118Syl 		val64 = (u64) (0x0000003fffff0000ULL);
1087a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1088a23fd118Syl 			&bar0->mc_rldram_test_add);
1089a23fd118Syl 
1090a23fd118Syl 
1091a23fd118Syl 		val64 = XGE_HAL_MC_RLDRAM_TEST_MODE;
1092a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1093a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
1094a23fd118Syl 
1095a23fd118Syl 		val64 |=
1096a23fd118Syl 		    XGE_HAL_MC_RLDRAM_TEST_MODE | XGE_HAL_MC_RLDRAM_TEST_WRITE |
1097a23fd118Syl 		    XGE_HAL_MC_RLDRAM_TEST_GO;
1098a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1099a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
1100a23fd118Syl 
1101a23fd118Syl 		for (cnt = 0; cnt < 5; cnt++) {
1102a23fd118Syl 			val64 = xge_os_pio_mem_read64(hldev->pdev,
1103a23fd118Syl 				hldev->regh0, &bar0->mc_rldram_test_ctrl);
1104a23fd118Syl 			if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE)
1105a23fd118Syl 				break;
1106a23fd118Syl 			xge_os_mdelay(200);
1107a23fd118Syl 		}
1108a23fd118Syl 
1109a23fd118Syl 		if (cnt == 5)
1110a23fd118Syl 			break;
1111a23fd118Syl 
1112a23fd118Syl 		val64 = XGE_HAL_MC_RLDRAM_TEST_MODE;
1113a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1114a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
1115a23fd118Syl 
1116a23fd118Syl 		val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE |
1117a23fd118Syl 		XGE_HAL_MC_RLDRAM_TEST_GO;
1118a23fd118Syl 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1119a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
1120a23fd118Syl 
1121a23fd118Syl 		for (cnt = 0; cnt < 5; cnt++) {
1122a23fd118Syl 			val64 = xge_os_pio_mem_read64(hldev->pdev,
1123a23fd118Syl 				hldev->regh0, &bar0->mc_rldram_test_ctrl);
1124a23fd118Syl 			if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE)
1125a23fd118Syl 				break;
1126a23fd118Syl 			xge_os_mdelay(500);
1127a23fd118Syl 		}
1128a23fd118Syl 
1129a23fd118Syl 		if (cnt == 5)
1130a23fd118Syl 			break;
1131a23fd118Syl 
1132a23fd118Syl 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1133a23fd118Syl 			&bar0->mc_rldram_test_ctrl);
1134a23fd118Syl 		if (val64 & XGE_HAL_MC_RLDRAM_TEST_PASS)
1135a23fd118Syl 			test_pass = 1;
1136a23fd118Syl 
1137a23fd118Syl 		iteration++;
1138a23fd118Syl 	}
1139a23fd118Syl 
1140a23fd118Syl 	if (!test_pass)
1141a23fd118Syl 		*data = 1;
1142a23fd118Syl 	else
1143a23fd118Syl 		*data = 0;
1144a23fd118Syl 
1145a23fd118Syl 	return XGE_HAL_OK;
1146a23fd118Syl }
1147a23fd118Syl 
11488347601bSyl /*
11498347601bSyl  * xge_hal_pma_loopback - Enable or disable PMA loopback
11508347601bSyl  * @devh: HAL device handle.
11518347601bSyl  * @enable:Boolean set to 1 to enable and 0 to disable.
11528347601bSyl  *
11538347601bSyl  * Enable or disable PMA loopback.
11548347601bSyl  * Return value:
11558347601bSyl  * 0 on success.
11568347601bSyl  */
11578347601bSyl xge_hal_status_e
xge_hal_pma_loopback(xge_hal_device_h devh,int enable)11588347601bSyl xge_hal_pma_loopback( xge_hal_device_h devh, int enable )
11598347601bSyl {
11608347601bSyl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
11618347601bSyl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
11628347601bSyl 	u64 val64;
11638347601bSyl 	u16 data;
11648347601bSyl 
11658347601bSyl 	/*
11668347601bSyl 	 * This code if for MAC loopbak
11678347601bSyl 	 * Should be enabled through another parameter
11688347601bSyl 	 */
11698347601bSyl #if 0
11708347601bSyl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
11718347601bSyl 	&bar0->mac_cfg);
11728347601bSyl     if ( enable )
11738347601bSyl     {
11748347601bSyl         val64 |= ( XGE_HAL_MAC_CFG_TMAC_LOOPBACK | XGE_HAL_MAC_CFG_RMAC_PROM_ENABLE );
11758347601bSyl     }
11768347601bSyl 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
11778347601bSyl 		    (u32)(val64 >> 32), (char*)&bar0->mac_cfg);
11788347601bSyl 	xge_os_mdelay(1);
11798347601bSyl #endif
11808347601bSyl 
11818347601bSyl 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
11828347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
11838347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
11848347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_CTRL(0)       |
11858347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
11867eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
11877eced415Sxw 
11888347601bSyl 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
11897eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
11908347601bSyl 
11918347601bSyl 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
11928347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
11938347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
11948347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_CTRL(0)       |
11958347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_READ);
11967eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
11977eced415Sxw 
11988347601bSyl 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
11997eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
12008347601bSyl 
12017eced415Sxw 	val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
12028347601bSyl 
12038347601bSyl 	data = (u16)XGE_HAL_MDIO_CONTROL_MMD_DATA_GET(val64);
12048347601bSyl 
12058347601bSyl #define _HAL_LOOPBK_PMA         1
12068347601bSyl 
12078347601bSyl 	if( enable )
12088347601bSyl 		data |= 1;
12098347601bSyl 	else
12108347601bSyl 		data &= 0xfe;
12118347601bSyl 
12128347601bSyl 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
12138347601bSyl 		 XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
12148347601bSyl 		 XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
12158347601bSyl 		 XGE_HAL_MDIO_CONTROL_MMD_CTRL(0)       |
12168347601bSyl 		 XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
12177eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
12187eced415Sxw 
12198347601bSyl 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
12207eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
12218347601bSyl 
12228347601bSyl 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
12238347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
12248347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
12258347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_DATA(data)    |
12268347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_CTRL(0x0)     |
12278347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_WRITE);
12287eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
12297eced415Sxw 
12308347601bSyl 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
12317eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
12328347601bSyl 
12338347601bSyl 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
12348347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
12358347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
12368347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_CTRL(0x0)     |
12378347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_READ);
12387eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
12397eced415Sxw 
12408347601bSyl 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
12417eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
12428347601bSyl 
12438347601bSyl     return XGE_HAL_OK;
12448347601bSyl }
12458347601bSyl 
12468347601bSyl u16
xge_hal_mdio_read(xge_hal_device_h devh,u32 mmd_type,u64 addr)12478347601bSyl xge_hal_mdio_read( xge_hal_device_h devh, u32 mmd_type, u64 addr )
12488347601bSyl {
12498347601bSyl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
12508347601bSyl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
12518347601bSyl 	u64 val64 = 0x0;
12528347601bSyl 	u16 rval16 = 0x0;
12538347601bSyl 	u8  i = 0;
12548347601bSyl 
12558347601bSyl 	/* address transaction */
12568347601bSyl 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr)  |
12578347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type)   |
12588347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
12598347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
12607eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
12618347601bSyl 
12628347601bSyl 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
12637eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
12648347601bSyl 	do
12658347601bSyl 	{
12667eced415Sxw 		val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
12678347601bSyl 		if (i++ > 10)
12688347601bSyl 		{
12698347601bSyl 			break;
12708347601bSyl 		}
12718347601bSyl 	}while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) != XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
12728347601bSyl 
12738347601bSyl 	/* Data transaction */
12748347601bSyl 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr)  |
12758347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type)   |
12768347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
12778347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_READ);
12787eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
12798347601bSyl 
12808347601bSyl 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
12817eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
12828347601bSyl 
12838347601bSyl 	i = 0;
12848347601bSyl 
12858347601bSyl 	do
12868347601bSyl 	{
12877eced415Sxw 		val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
12888347601bSyl 		if (i++ > 10)
12898347601bSyl 		{
12908347601bSyl 			break;
12918347601bSyl 		}
12928347601bSyl 	}while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) != XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
12938347601bSyl 
12948347601bSyl 	rval16 = (u16)XGE_HAL_MDIO_CONTROL_MMD_DATA_GET(val64);
12958347601bSyl 
12968347601bSyl 	return rval16;
12978347601bSyl }
12988347601bSyl 
12998347601bSyl xge_hal_status_e
xge_hal_mdio_write(xge_hal_device_h devh,u32 mmd_type,u64 addr,u32 value)13008347601bSyl xge_hal_mdio_write( xge_hal_device_h devh, u32 mmd_type, u64 addr, u32 value )
13018347601bSyl {
13028347601bSyl 	u64 val64 = 0x0;
13038347601bSyl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
13048347601bSyl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
13058347601bSyl 	u8  i = 0;
13068347601bSyl 	/* address transaction */
13078347601bSyl 
13088347601bSyl 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr)  |
13098347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type)   |
13108347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
13118347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
13127eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
13138347601bSyl 
13148347601bSyl 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
13157eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
13168347601bSyl 
13178347601bSyl 	do
13188347601bSyl 	{
13197eced415Sxw 		val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
13208347601bSyl 		if (i++ > 10)
13218347601bSyl 		{
13228347601bSyl 			break;
13238347601bSyl 		}
13248347601bSyl 	} while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) !=
13258347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
13268347601bSyl 
13278347601bSyl 	/* Data transaction */
13288347601bSyl 
13298347601bSyl 	val64 = 0x0;
13308347601bSyl 
13318347601bSyl 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr)    |
13328347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type) |
13338347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)        |
13348347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_DATA(value)        |
13358347601bSyl 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_WRITE);
13367eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
13378347601bSyl 
13388347601bSyl 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
13397eced415Sxw 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
13408347601bSyl 
13418347601bSyl 	i = 0;
13428347601bSyl 
13438347601bSyl 	do
13448347601bSyl 	{
13457eced415Sxw 		val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
13468347601bSyl 		if (i++ > 10)
13478347601bSyl 		{
13488347601bSyl 			break;
13498347601bSyl 		}
13508347601bSyl 	}while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) != XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
13518347601bSyl 
13528347601bSyl 	return XGE_HAL_OK;
13538347601bSyl }
13548347601bSyl 
1355a23fd118Syl /*
1356a23fd118Syl  * xge_hal_eeprom_test - to verify that EEprom in the xena can be
1357a23fd118Syl  programmed.
1358a23fd118Syl  * @devh: HAL device handle.
1359a23fd118Syl  * @data:variable that returns the result of each of the test conducted by
1360a23fd118Syl  * the driver.
1361a23fd118Syl  *
1362a23fd118Syl  * Verify that EEPROM in the xena can be programmed using I2C_CONTROL
1363a23fd118Syl  * register.
1364a23fd118Syl  * Return value:
1365a23fd118Syl  * 0 on success.
1366a23fd118Syl  */
1367a23fd118Syl xge_hal_status_e
xge_hal_eeprom_test(xge_hal_device_h devh,u64 * data)1368a23fd118Syl xge_hal_eeprom_test(xge_hal_device_h devh, u64 *data)
1369a23fd118Syl {
1370a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
13717eced415Sxw 	int fail     = 0;
13727eced415Sxw 	u32 ret_data = 0;
1373a23fd118Syl 
1374a23fd118Syl 	/* Test Write Error at offset 0 */
1375a23fd118Syl 	if (!xge_hal_write_eeprom(hldev, 0, 0, 3))
1376a23fd118Syl 		fail = 1;
1377a23fd118Syl 
1378a23fd118Syl 	/* Test Write at offset 4f0 */
1379a23fd118Syl 	if (xge_hal_write_eeprom(hldev, 0x4F0, 0x01234567, 3))
1380a23fd118Syl 		fail = 1;
1381a23fd118Syl 	if (xge_hal_read_eeprom(hldev, 0x4F0, &ret_data))
1382a23fd118Syl 		fail = 1;
1383a23fd118Syl 
1384a23fd118Syl 	if (ret_data != 0x01234567)
1385a23fd118Syl 		fail = 1;
1386a23fd118Syl 
1387a23fd118Syl 	/* Reset the EEPROM data go FFFF */
1388a23fd118Syl 	(void) xge_hal_write_eeprom(hldev, 0x4F0, 0xFFFFFFFF, 3);
1389a23fd118Syl 
1390a23fd118Syl 	/* Test Write Request Error at offset 0x7c */
1391a23fd118Syl 	if (!xge_hal_write_eeprom(hldev, 0x07C, 0, 3))
1392a23fd118Syl 		fail = 1;
1393a23fd118Syl 
1394a23fd118Syl 	/* Test Write Request at offset 0x7fc */
1395a23fd118Syl 	if (xge_hal_write_eeprom(hldev, 0x7FC, 0x01234567, 3))
1396a23fd118Syl 		fail = 1;
1397a23fd118Syl 	if (xge_hal_read_eeprom(hldev, 0x7FC, &ret_data))
1398a23fd118Syl 		fail = 1;
1399a23fd118Syl 
1400a23fd118Syl 	if (ret_data != 0x01234567)
1401a23fd118Syl 		fail = 1;
1402a23fd118Syl 
1403a23fd118Syl 	/* Reset the EEPROM data go FFFF */
1404a23fd118Syl 	(void) xge_hal_write_eeprom(hldev, 0x7FC, 0xFFFFFFFF, 3);
1405a23fd118Syl 
1406a23fd118Syl 	/* Test Write Error at offset 0x80 */
1407a23fd118Syl 	if (!xge_hal_write_eeprom(hldev, 0x080, 0, 3))
1408a23fd118Syl 		fail = 1;
1409a23fd118Syl 
1410a23fd118Syl 	/* Test Write Error at offset 0xfc */
1411a23fd118Syl 	if (!xge_hal_write_eeprom(hldev, 0x0FC, 0, 3))
1412a23fd118Syl 		fail = 1;
1413a23fd118Syl 
1414a23fd118Syl 	/* Test Write Error at offset 0x100 */
1415a23fd118Syl 	if (!xge_hal_write_eeprom(hldev, 0x100, 0, 3))
1416a23fd118Syl 		fail = 1;
1417a23fd118Syl 
1418a23fd118Syl 	/* Test Write Error at offset 4ec */
1419a23fd118Syl 	if (!xge_hal_write_eeprom(hldev, 0x4EC, 0, 3))
1420a23fd118Syl 		fail = 1;
1421a23fd118Syl 
1422a23fd118Syl 	*data = fail;
1423a23fd118Syl 	return XGE_HAL_OK;
1424a23fd118Syl }
1425a23fd118Syl 
1426a23fd118Syl /*
1427a23fd118Syl  * xge_hal_bist_test - invokes the MemBist test of the card .
1428a23fd118Syl  * @devh: HAL device handle.
1429a23fd118Syl  * xge_nic structure.
1430a23fd118Syl  * @data:variable that returns the result of each of the test conducted by
1431a23fd118Syl  * the driver.
1432a23fd118Syl  *
1433a23fd118Syl  * This invokes the MemBist test of the card. We give around
1434a23fd118Syl  * 2 secs time for the Test to complete. If it's still not complete
1435a23fd118Syl  * within this peiod, we consider that the test failed.
1436a23fd118Syl  * Return value:
1437a23fd118Syl  * 0 on success and -1 on failure.
1438a23fd118Syl  */
1439a23fd118Syl xge_hal_status_e
xge_hal_bist_test(xge_hal_device_h devh,u64 * data)1440a23fd118Syl xge_hal_bist_test(xge_hal_device_h devh, u64 *data)
1441a23fd118Syl {
1442a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1443a23fd118Syl 	u8 bist = 0;
14448347601bSyl 	int cnt = 0;
14458347601bSyl 	xge_hal_status_e ret = XGE_HAL_FAIL;
1446a23fd118Syl 
1447a23fd118Syl 	xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist);
1448a23fd118Syl 	bist |= 0x40;
1449a23fd118Syl 	xge_os_pci_write8(hldev->pdev, hldev->cfgh, 0x0f, bist);
1450a23fd118Syl 
1451a23fd118Syl 	while (cnt < 20) {
1452a23fd118Syl 		xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist);
1453a23fd118Syl 		if (!(bist & 0x40)) {
1454a23fd118Syl 			*data = (bist & 0x0f);
1455a23fd118Syl 			ret = XGE_HAL_OK;
1456a23fd118Syl 			break;
1457a23fd118Syl 		}
1458a23fd118Syl 		xge_os_mdelay(100);
1459a23fd118Syl 		cnt++;
1460a23fd118Syl 	}
1461a23fd118Syl 
1462a23fd118Syl 	return ret;
1463a23fd118Syl }
1464a23fd118Syl 
1465a23fd118Syl /*
1466a23fd118Syl  * xge_hal_link_test - verifies the link state of the nic
1467a23fd118Syl  * @devh: HAL device handle.
1468a23fd118Syl  * @data: variable that returns the result of each of the test conducted by
1469a23fd118Syl  * the driver.
1470a23fd118Syl  *
1471a23fd118Syl  * Verify the link state of the NIC and updates the input
1472a23fd118Syl  * argument 'data' appropriately.
1473a23fd118Syl  * Return value:
1474a23fd118Syl  * 0 on success.
1475a23fd118Syl  */
1476a23fd118Syl xge_hal_status_e
xge_hal_link_test(xge_hal_device_h devh,u64 * data)1477a23fd118Syl xge_hal_link_test(xge_hal_device_h devh, u64 *data)
1478a23fd118Syl {
1479a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1480a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1481a23fd118Syl 	u64 val64;
1482a23fd118Syl 
1483a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1484a23fd118Syl 			&bar0->adapter_status);
1485a23fd118Syl 	if (val64 & XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)
1486a23fd118Syl 		*data = 1;
1487a23fd118Syl 
1488a23fd118Syl 	return XGE_HAL_OK;
1489a23fd118Syl }
1490a23fd118Syl 
1491a23fd118Syl 
1492a23fd118Syl /**
1493a23fd118Syl  * xge_hal_getpause_data -Pause frame frame generation and reception.
1494a23fd118Syl  * @devh: HAL device handle.
1495a23fd118Syl  * @tx : A field to return the pause generation capability of the NIC.
1496a23fd118Syl  * @rx : A field to return the pause reception capability of the NIC.
1497a23fd118Syl  *
1498a23fd118Syl  * Returns the Pause frame generation and reception capability of the NIC.
1499a23fd118Syl  * Return value:
1500a23fd118Syl  *  void
1501a23fd118Syl  */
xge_hal_getpause_data(xge_hal_device_h devh,int * tx,int * rx)1502a23fd118Syl void xge_hal_getpause_data(xge_hal_device_h devh, int *tx, int *rx)
1503a23fd118Syl {
1504a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1505a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1506a23fd118Syl 	u64 val64;
1507a23fd118Syl 
1508a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1509a23fd118Syl 				&bar0->rmac_pause_cfg);
1510a23fd118Syl 	if (val64 & XGE_HAL_RMAC_PAUSE_GEN_EN)
1511a23fd118Syl 		*tx = 1;
1512a23fd118Syl 	if (val64 & XGE_HAL_RMAC_PAUSE_RCV_EN)
1513a23fd118Syl 		*rx = 1;
1514a23fd118Syl }
1515a23fd118Syl 
1516a23fd118Syl /**
1517a23fd118Syl  * xge_hal_setpause_data -  set/reset pause frame generation.
1518a23fd118Syl  * @devh: HAL device handle.
1519a23fd118Syl  * @tx: A field that indicates the pause generation capability to be
1520a23fd118Syl  * set on the NIC.
1521a23fd118Syl  * @rx: A field that indicates the pause reception capability to be
1522a23fd118Syl  * set on the NIC.
1523a23fd118Syl  *
1524a23fd118Syl  * It can be used to set or reset Pause frame generation or reception
1525a23fd118Syl  * support of the NIC.
1526a23fd118Syl  * Return value:
1527a23fd118Syl  * int, returns 0 on Success
1528a23fd118Syl  */
1529a23fd118Syl 
xge_hal_setpause_data(xge_hal_device_h devh,int tx,int rx)1530a23fd118Syl int xge_hal_setpause_data(xge_hal_device_h devh, int tx, int rx)
1531a23fd118Syl {
1532a23fd118Syl 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1533a23fd118Syl 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1534a23fd118Syl 	u64 val64;
1535a23fd118Syl 
1536a23fd118Syl 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1537a23fd118Syl 				    &bar0->rmac_pause_cfg);
1538a23fd118Syl 	if (tx)
1539a23fd118Syl 		val64 |= XGE_HAL_RMAC_PAUSE_GEN_EN;
1540a23fd118Syl 	else
1541a23fd118Syl 		val64 &= ~XGE_HAL_RMAC_PAUSE_GEN_EN;
1542a23fd118Syl 	if (rx)
1543a23fd118Syl 		val64 |= XGE_HAL_RMAC_PAUSE_RCV_EN;
1544a23fd118Syl 	else
1545a23fd118Syl 		val64 &= ~XGE_HAL_RMAC_PAUSE_RCV_EN;
1546a23fd118Syl 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1547a23fd118Syl 			     val64, &bar0->rmac_pause_cfg);
1548a23fd118Syl 	return 0;
1549a23fd118Syl }
1550a23fd118Syl 
15518347601bSyl /**
15528347601bSyl  * xge_hal_read_xfp_current_temp -
15538347601bSyl  * @hldev: HAL device handle.
15548347601bSyl  *
15558347601bSyl  * This routine only gets the temperature for XFP modules. Also, updating of the
15568347601bSyl  * NVRAM can sometimes fail and so the reading we might get may not be uptodate.
15578347601bSyl  */
xge_hal_read_xfp_current_temp(xge_hal_device_h hldev)15588347601bSyl u32 xge_hal_read_xfp_current_temp(xge_hal_device_h hldev)
15598347601bSyl {
15608347601bSyl     u16 val_1, val_2, i = 0;
15618347601bSyl     u32 actual;
15628347601bSyl 
15638347601bSyl     /* First update the NVRAM table of XFP. */
15648347601bSyl 
15658347601bSyl     (void) xge_hal_mdio_write(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8000, 0x3);
15668347601bSyl 
15678347601bSyl 
15688347601bSyl     /* Now wait for the transfer to complete */
15698347601bSyl     do
15708347601bSyl     {
15718347601bSyl         xge_os_mdelay( 50 ); // wait 50 milliseonds
15728347601bSyl 
15738347601bSyl         val_1 =  xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8000);
15748347601bSyl 
15758347601bSyl         if ( i++ > 10 )
15768347601bSyl         {
15778347601bSyl             // waited 500 ms which should be plenty of time.
15788347601bSyl             break;
15798347601bSyl         }
15808347601bSyl     }while (( val_1 & 0x000C ) != 0x0004);
15818347601bSyl 
15828347601bSyl     /* Now NVRAM table of XFP should be updated, so read the temp */
15838347601bSyl     val_1 =  (u8) xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8067);
15848347601bSyl     val_2 =  (u8) xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8068);
15858347601bSyl 
15868347601bSyl     actual = ((val_1 << 8) | val_2);
15878347601bSyl 
15888347601bSyl     if (actual >= 32768)
15898347601bSyl         actual = actual- 65536;
15908347601bSyl     actual =  actual/256;
15918347601bSyl 
15928347601bSyl     return actual;
15938347601bSyl }
15948347601bSyl 
15958347601bSyl /**
15968347601bSyl  * __hal_chk_xpak_counter -  check the Xpak error count and log the msg.
15978347601bSyl  * @hldev: pointer to xge_hal_device_t structure
15988347601bSyl  * @type:  xpak stats error type
15998347601bSyl  * @value: xpak stats value
16008347601bSyl  *
16018347601bSyl  * It is used to log the error message based on the xpak stats value
16028347601bSyl  * Return value:
16038347601bSyl  * None
16048347601bSyl  */
16058347601bSyl 
__hal_chk_xpak_counter(xge_hal_device_t * hldev,int type,u32 value)16068347601bSyl void __hal_chk_xpak_counter(xge_hal_device_t *hldev, int type, u32 value)
16078347601bSyl {
16087eced415Sxw 	/*
16098347601bSyl 	 * If the value is high for three consecutive cylce,
16108347601bSyl 	 * log a error message
16118347601bSyl 	 */
16128347601bSyl 	if(value == 3)
16138347601bSyl 	{
16148347601bSyl 		switch(type)
16158347601bSyl 		{
16168347601bSyl 		case 1:
16178347601bSyl 			hldev->stats.sw_dev_err_stats.xpak_counter.
16188347601bSyl 				excess_temp = 0;
16198347601bSyl 
16208347601bSyl 			/*
16218347601bSyl 			 * Notify the ULD on Excess Xpak temperature alarm msg
16228347601bSyl 			 */
16238347601bSyl 			if (g_xge_hal_driver->uld_callbacks.xpak_alarm_log) {
16248347601bSyl 				g_xge_hal_driver->uld_callbacks.xpak_alarm_log(
16258347601bSyl 					hldev->upper_layer_info,
16268347601bSyl 					XGE_HAL_XPAK_ALARM_EXCESS_TEMP);
16278347601bSyl 			}
16288347601bSyl 			break;
16298347601bSyl 		case 2:
16308347601bSyl 			hldev->stats.sw_dev_err_stats.xpak_counter.
16318347601bSyl 				excess_bias_current = 0;
16328347601bSyl 
16338347601bSyl 			/*
16348347601bSyl 			 * Notify the ULD on Excess  xpak bias current alarm msg
16358347601bSyl 			 */
16368347601bSyl 			if (g_xge_hal_driver->uld_callbacks.xpak_alarm_log) {
16378347601bSyl 				g_xge_hal_driver->uld_callbacks.xpak_alarm_log(
16388347601bSyl 					hldev->upper_layer_info,
16398347601bSyl 					XGE_HAL_XPAK_ALARM_EXCESS_BIAS_CURRENT);
16408347601bSyl 			}
16418347601bSyl 			break;
16428347601bSyl 		case 3:
16438347601bSyl 			hldev->stats.sw_dev_err_stats.xpak_counter.
16448347601bSyl 				excess_laser_output = 0;
16458347601bSyl 
16468347601bSyl 			/*
16477eced415Sxw 			 * Notify the ULD on Excess Xpak Laser o/p power
16488347601bSyl 			 * alarm msg
16498347601bSyl 			 */
16508347601bSyl 			if (g_xge_hal_driver->uld_callbacks.xpak_alarm_log) {
16518347601bSyl 				g_xge_hal_driver->uld_callbacks.xpak_alarm_log(
16528347601bSyl 					hldev->upper_layer_info,
16538347601bSyl 					XGE_HAL_XPAK_ALARM_EXCESS_LASER_OUTPUT);
16548347601bSyl 			}
16558347601bSyl 			break;
16568347601bSyl 		default:
16578347601bSyl 			xge_debug_osdep(XGE_TRACE, "Incorrect XPAK Alarm "
16587eced415Sxw 			"type ");
16598347601bSyl 		}
16607eced415Sxw 	}
16618347601bSyl 
16628347601bSyl }
16638347601bSyl 
16648347601bSyl /**
16658347601bSyl  * __hal_updt_stats_xpak -  update the Xpak error count.
16668347601bSyl  * @hldev: pointer to xge_hal_device_t structure
16678347601bSyl  *
16688347601bSyl  * It is used to update the xpak stats value
16698347601bSyl  * Return value:
16708347601bSyl  * None
16718347601bSyl  */
__hal_updt_stats_xpak(xge_hal_device_t * hldev)16728347601bSyl void __hal_updt_stats_xpak(xge_hal_device_t *hldev)
16738347601bSyl {
16748347601bSyl 	u16 val_1;
16758347601bSyl 	u64 addr;
16768347601bSyl 
16778347601bSyl 	/* Check the communication with the MDIO slave */
16788347601bSyl 	addr = 0x0000;
16798347601bSyl 	val_1 = 0x0;
16808347601bSyl 	val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
16818347601bSyl 	if((val_1 == 0xFFFF) || (val_1 == 0x0000))
16828347601bSyl         {
16838347601bSyl                 xge_debug_osdep(XGE_TRACE, "ERR: MDIO slave access failed - "
16847eced415Sxw                           "Returned %x", val_1);
16858347601bSyl                 return;
16868347601bSyl         }
16878347601bSyl 
16888347601bSyl 	/* Check for the expected value of 2040 at PMA address 0x0000 */
16898347601bSyl 	if(val_1 != 0x2040)
16908347601bSyl         {
16918347601bSyl                 xge_debug_osdep(XGE_TRACE, "Incorrect value at PMA address 0x0000 - ");
16927eced415Sxw                 xge_debug_osdep(XGE_TRACE, "Returned: %llx- Expected: 0x2040",
16937eced415Sxw 				(unsigned long long)(unsigned long)val_1);
16948347601bSyl                 return;
16958347601bSyl         }
16968347601bSyl 
16978347601bSyl 	/* Loading the DOM register to MDIO register */
16988347601bSyl         addr = 0xA100;
16998347601bSyl         (void) xge_hal_mdio_write(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr, 0x0);
17008347601bSyl         val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
17018347601bSyl 
17028347601bSyl 	/*
17038347601bSyl 	 * Reading the Alarm flags
17048347601bSyl 	 */
17058347601bSyl         addr = 0xA070;
17068347601bSyl         val_1 = 0x0;
17078347601bSyl         val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
17088347601bSyl 	if(CHECKBIT(val_1, 0x7))
17098347601bSyl 	{
17108347601bSyl 		hldev->stats.sw_dev_err_stats.stats_xpak.
17118347601bSyl 			alarm_transceiver_temp_high++;
17128347601bSyl 		hldev->stats.sw_dev_err_stats.xpak_counter.excess_temp++;
17138347601bSyl 		__hal_chk_xpak_counter(hldev, 0x1,
17148347601bSyl 			hldev->stats.sw_dev_err_stats.xpak_counter.excess_temp);
17158347601bSyl 	} else {
17168347601bSyl 		hldev->stats.sw_dev_err_stats.xpak_counter.excess_temp = 0;
17178347601bSyl 	}
17188347601bSyl 	if(CHECKBIT(val_1, 0x6))
17198347601bSyl 		hldev->stats.sw_dev_err_stats.stats_xpak.
17208347601bSyl 			alarm_transceiver_temp_low++;
17218347601bSyl 
17228347601bSyl 	if(CHECKBIT(val_1, 0x3))
17238347601bSyl 	{
17248347601bSyl 		hldev->stats.sw_dev_err_stats.stats_xpak.
17258347601bSyl 			alarm_laser_bias_current_high++;
17268347601bSyl 		hldev->stats.sw_dev_err_stats.xpak_counter.
17278347601bSyl 			excess_bias_current++;
17288347601bSyl 		__hal_chk_xpak_counter(hldev, 0x2,
17298347601bSyl 			hldev->stats.sw_dev_err_stats.xpak_counter.
17308347601bSyl 			excess_bias_current);
17318347601bSyl 	} else {
17328347601bSyl 		hldev->stats.sw_dev_err_stats.xpak_counter.
17338347601bSyl 			excess_bias_current = 0;
17348347601bSyl 	}
17358347601bSyl 	if(CHECKBIT(val_1, 0x2))
17368347601bSyl 		hldev->stats.sw_dev_err_stats.stats_xpak.
17378347601bSyl 			alarm_laser_bias_current_low++;
17388347601bSyl 
17398347601bSyl 	if(CHECKBIT(val_1, 0x1))
17408347601bSyl 	{
17418347601bSyl 		hldev->stats.sw_dev_err_stats.stats_xpak.
17428347601bSyl 			alarm_laser_output_power_high++;
17438347601bSyl 		hldev->stats.sw_dev_err_stats.xpak_counter.
17448347601bSyl 			excess_laser_output++;
17458347601bSyl 		__hal_chk_xpak_counter(hldev, 0x3,
17468347601bSyl 			hldev->stats.sw_dev_err_stats.xpak_counter.
17478347601bSyl 				excess_laser_output);
17488347601bSyl 	} else {
17498347601bSyl 		hldev->stats.sw_dev_err_stats.xpak_counter.
17508347601bSyl 				excess_laser_output = 0;
17518347601bSyl 	}
17528347601bSyl 	if(CHECKBIT(val_1, 0x0))
17538347601bSyl 		hldev->stats.sw_dev_err_stats.stats_xpak.
17548347601bSyl 				alarm_laser_output_power_low++;
17558347601bSyl 
17568347601bSyl 	/*
17578347601bSyl 	 * Reading the warning flags
17588347601bSyl 	 */
17598347601bSyl         addr = 0xA074;
17608347601bSyl         val_1 = 0x0;
17618347601bSyl         val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
17628347601bSyl 	if(CHECKBIT(val_1, 0x7))
17638347601bSyl 		hldev->stats.sw_dev_err_stats.stats_xpak.
17648347601bSyl 			warn_transceiver_temp_high++;
17658347601bSyl 	if(CHECKBIT(val_1, 0x6))
17668347601bSyl 		hldev->stats.sw_dev_err_stats.stats_xpak.
17678347601bSyl 			warn_transceiver_temp_low++;
17688347601bSyl 	if(CHECKBIT(val_1, 0x3))
17698347601bSyl 		hldev->stats.sw_dev_err_stats.stats_xpak.
17708347601bSyl 			warn_laser_bias_current_high++;
17718347601bSyl 	if(CHECKBIT(val_1, 0x2))
17728347601bSyl 		hldev->stats.sw_dev_err_stats.stats_xpak.
17738347601bSyl 			warn_laser_bias_current_low++;
17748347601bSyl 	if(CHECKBIT(val_1, 0x1))
17758347601bSyl 		hldev->stats.sw_dev_err_stats.stats_xpak.
17768347601bSyl 			warn_laser_output_power_high++;
17778347601bSyl 	if(CHECKBIT(val_1, 0x0))
17788347601bSyl 		hldev->stats.sw_dev_err_stats.stats_xpak.
17798347601bSyl 			warn_laser_output_power_low++;
17808347601bSyl }
1781