1171095Ssam/*-
2171095Ssam * Copyright (c) 2002-2007 Neterion, Inc.
3171095Ssam * All rights reserved.
4171095Ssam *
5171095Ssam * Redistribution and use in source and binary forms, with or without
6171095Ssam * modification, are permitted provided that the following conditions
7171095Ssam * are met:
8171095Ssam * 1. Redistributions of source code must retain the above copyright
9171095Ssam *    notice, this list of conditions and the following disclaimer.
10171095Ssam * 2. Redistributions in binary form must reproduce the above copyright
11171095Ssam *    notice, this list of conditions and the following disclaimer in the
12171095Ssam *    documentation and/or other materials provided with the distribution.
13171095Ssam *
14171095Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15171095Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16171095Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17171095Ssam * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18171095Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19171095Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20171095Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21171095Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22171095Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23171095Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24171095Ssam * SUCH DAMAGE.
25171095Ssam *
26171095Ssam * $FreeBSD$
27171095Ssam */
28171095Ssam
29171095Ssam#include <dev/nxge/include/xgehal-mgmt.h>
30171095Ssam#include <dev/nxge/include/xgehal-driver.h>
31171095Ssam#include <dev/nxge/include/xgehal-device.h>
32171095Ssam
33171095Ssam/**
34171095Ssam * xge_hal_mgmt_about - Retrieve about info.
35171095Ssam * @devh: HAL device handle.
36171095Ssam * @about_info: Filled in by HAL. See xge_hal_mgmt_about_info_t{}.
37171095Ssam * @size: Size of the @about_info buffer. HAL will return error if the
38171095Ssam *        size is smaller than sizeof(xge_hal_mgmt_about_info_t).
39171095Ssam *
40171095Ssam * Retrieve information such as PCI device and vendor IDs, board
41171095Ssam * revision number, HAL version number, etc.
42171095Ssam *
43171095Ssam * Returns: XGE_HAL_OK - success;
44171095Ssam * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
45171095Ssam * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
46171095Ssam * XGE_HAL_FAIL - Failed to retrieve the information.
47171095Ssam *
48171095Ssam * See also: xge_hal_mgmt_about_info_t{}.
49171095Ssam */
50171095Ssamxge_hal_status_e
51171095Ssamxge_hal_mgmt_about(xge_hal_device_h devh, xge_hal_mgmt_about_info_t *about_info,
52173139Srwatson	    int size)
53171095Ssam{
54171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
55171095Ssam
56171095Ssam	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
57173139Srwatson	    return XGE_HAL_ERR_INVALID_DEVICE;
58171095Ssam	}
59171095Ssam
60171095Ssam	if (size != sizeof(xge_hal_mgmt_about_info_t)) {
61173139Srwatson	    return XGE_HAL_ERR_VERSION_CONFLICT;
62171095Ssam	}
63171095Ssam
64171095Ssam	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
65173139Srwatson	    xge_offsetof(xge_hal_pci_config_le_t, vendor_id),
66173139Srwatson	    &about_info->vendor);
67171095Ssam
68171095Ssam	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
69173139Srwatson	    xge_offsetof(xge_hal_pci_config_le_t, device_id),
70173139Srwatson	    &about_info->device);
71171095Ssam
72171095Ssam	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
73173139Srwatson	    xge_offsetof(xge_hal_pci_config_le_t, subsystem_vendor_id),
74173139Srwatson	    &about_info->subsys_vendor);
75171095Ssam
76171095Ssam	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
77173139Srwatson	    xge_offsetof(xge_hal_pci_config_le_t, subsystem_id),
78173139Srwatson	    &about_info->subsys_device);
79171095Ssam
80171095Ssam	xge_os_pci_read8(hldev->pdev, hldev->cfgh,
81173139Srwatson	    xge_offsetof(xge_hal_pci_config_le_t, revision),
82173139Srwatson	    &about_info->board_rev);
83171095Ssam
84171095Ssam	xge_os_strcpy(about_info->vendor_name, XGE_DRIVER_VENDOR);
85171095Ssam	xge_os_strcpy(about_info->chip_name, XGE_CHIP_FAMILY);
86171095Ssam	xge_os_strcpy(about_info->media, XGE_SUPPORTED_MEDIA_0);
87171095Ssam
88171095Ssam	xge_os_strcpy(about_info->hal_major, XGE_HAL_VERSION_MAJOR);
89171095Ssam	xge_os_strcpy(about_info->hal_minor, XGE_HAL_VERSION_MINOR);
90171095Ssam	xge_os_strcpy(about_info->hal_fix,   XGE_HAL_VERSION_FIX);
91171095Ssam	xge_os_strcpy(about_info->hal_build, XGE_HAL_VERSION_BUILD);
92171095Ssam
93171095Ssam	xge_os_strcpy(about_info->ll_major, XGELL_VERSION_MAJOR);
94171095Ssam	xge_os_strcpy(about_info->ll_minor, XGELL_VERSION_MINOR);
95171095Ssam	xge_os_strcpy(about_info->ll_fix,   XGELL_VERSION_FIX);
96171095Ssam	xge_os_strcpy(about_info->ll_build, XGELL_VERSION_BUILD);
97171095Ssam
98171095Ssam	about_info->transponder_temperature =
99173139Srwatson	    xge_hal_read_xfp_current_temp(devh);
100171095Ssam
101171095Ssam	return XGE_HAL_OK;
102171095Ssam}
103171095Ssam
104171095Ssam/**
105171095Ssam * xge_hal_mgmt_reg_read - Read Xframe register.
106171095Ssam * @devh: HAL device handle.
107171095Ssam * @bar_id: 0 - for BAR0, 1- for BAR1.
108171095Ssam * @offset: Register offset in the Base Address Register (BAR) space.
109171095Ssam * @value: Register value. Returned by HAL.
110171095Ssam * Read Xframe register.
111171095Ssam *
112171095Ssam * Returns: XGE_HAL_OK - success.
113171095Ssam * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
114171095Ssam * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
115171095Ssam * valid.
116171095Ssam * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
117171095Ssam *
118171095Ssam * See also: xge_hal_aux_bar0_read(), xge_hal_aux_bar1_read().
119171095Ssam */
120171095Ssamxge_hal_status_e
121171095Ssamxge_hal_mgmt_reg_read(xge_hal_device_h devh, int bar_id, unsigned int offset,
122173139Srwatson	    u64 *value)
123171095Ssam{
124171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
125171095Ssam
126171095Ssam	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
127173139Srwatson	    return XGE_HAL_ERR_INVALID_DEVICE;
128171095Ssam	}
129171095Ssam
130171095Ssam	if (bar_id == 0) {
131173139Srwatson	    if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
132173139Srwatson	        return XGE_HAL_ERR_INVALID_OFFSET;
133173139Srwatson	    }
134173139Srwatson	    *value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
135173139Srwatson	                     (void *)(hldev->bar0 + offset));
136171095Ssam	} else if (bar_id == 1 &&
137173139Srwatson	       (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA ||
138173139Srwatson	        xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC))  {
139173139Srwatson	    int i;
140173139Srwatson	    for (i=0; i<XGE_HAL_MAX_FIFO_NUM_HERC; i++) {
141173139Srwatson	        if (offset == i*0x2000 || offset == i*0x2000+0x18) {
142173139Srwatson	            break;
143173139Srwatson	        }
144173139Srwatson	    }
145173139Srwatson	    if (i == XGE_HAL_MAX_FIFO_NUM_HERC) {
146173139Srwatson	        return XGE_HAL_ERR_INVALID_OFFSET;
147173139Srwatson	    }
148173139Srwatson	    *value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh1,
149173139Srwatson	                     (void *)(hldev->bar1 + offset));
150171095Ssam	} else if (bar_id == 1) {
151173139Srwatson	    /* FIXME: check TITAN BAR1 offsets */
152171095Ssam	} else {
153173139Srwatson	    return XGE_HAL_ERR_INVALID_BAR_ID;
154171095Ssam	}
155171095Ssam
156171095Ssam	return XGE_HAL_OK;
157171095Ssam}
158171095Ssam
159171095Ssam/**
160171095Ssam * xge_hal_mgmt_reg_write - Write Xframe register.
161171095Ssam * @devh: HAL device handle.
162171095Ssam * @bar_id: 0 - for BAR0, 1- for BAR1.
163171095Ssam * @offset: Register offset in the Base Address Register (BAR) space.
164171095Ssam * @value: Register value.
165171095Ssam *
166171095Ssam * Write Xframe register.
167171095Ssam *
168171095Ssam * Returns: XGE_HAL_OK - success.
169171095Ssam * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
170171095Ssam * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
171171095Ssam * valid.
172171095Ssam * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
173171095Ssam *
174171095Ssam * See also: xge_hal_aux_bar0_write().
175171095Ssam */
176171095Ssamxge_hal_status_e
177171095Ssamxge_hal_mgmt_reg_write(xge_hal_device_h devh, int bar_id, unsigned int offset,
178173139Srwatson	    u64 value)
179171095Ssam{
180171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
181171095Ssam
182171095Ssam	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
183173139Srwatson	    return XGE_HAL_ERR_INVALID_DEVICE;
184171095Ssam	}
185171095Ssam
186171095Ssam	if (bar_id == 0) {
187173139Srwatson	    if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
188173139Srwatson	        return XGE_HAL_ERR_INVALID_OFFSET;
189173139Srwatson	    }
190173139Srwatson	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, value,
191173139Srwatson	                 (void *)(hldev->bar0 + offset));
192171095Ssam	} else if (bar_id == 1 &&
193173139Srwatson	       (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA ||
194173139Srwatson	        xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC))  {
195173139Srwatson	    int i;
196173139Srwatson	    for (i=0; i<XGE_HAL_MAX_FIFO_NUM_HERC; i++) {
197173139Srwatson	        if (offset == i*0x2000 || offset == i*0x2000+0x18) {
198173139Srwatson	            break;
199173139Srwatson	        }
200173139Srwatson	    }
201173139Srwatson	    if (i == XGE_HAL_MAX_FIFO_NUM_HERC) {
202173139Srwatson	        return XGE_HAL_ERR_INVALID_OFFSET;
203173139Srwatson	    }
204173139Srwatson	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh1, value,
205173139Srwatson	                 (void *)(hldev->bar1 + offset));
206171095Ssam	} else if (bar_id == 1) {
207173139Srwatson	    /* FIXME: check TITAN BAR1 offsets */
208171095Ssam	} else {
209173139Srwatson	    return XGE_HAL_ERR_INVALID_BAR_ID;
210171095Ssam	}
211171095Ssam
212171095Ssam	return XGE_HAL_OK;
213171095Ssam}
214171095Ssam
215171095Ssam/**
216171095Ssam * xge_hal_mgmt_hw_stats - Get Xframe hardware statistics.
217171095Ssam * @devh: HAL device handle.
218171095Ssam * @hw_stats: Hardware statistics. Returned by HAL.
219171095Ssam *            See xge_hal_stats_hw_info_t{}.
220171095Ssam * @size: Size of the @hw_stats buffer. HAL will return an error
221171095Ssam * if the size is smaller than sizeof(xge_hal_stats_hw_info_t).
222171095Ssam * Get Xframe hardware statistics.
223171095Ssam *
224171095Ssam * Returns: XGE_HAL_OK - success.
225171095Ssam * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
226171095Ssam * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
227171095Ssam *
228171095Ssam * See also: xge_hal_mgmt_sw_stats().
229171095Ssam */
230171095Ssamxge_hal_status_e
231171095Ssamxge_hal_mgmt_hw_stats(xge_hal_device_h devh, xge_hal_mgmt_hw_stats_t *hw_stats,
232173139Srwatson	    int size)
233171095Ssam{
234171095Ssam	xge_hal_status_e status;
235171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
236173139Srwatson	xge_hal_stats_hw_info_t *hw_info;
237171095Ssam
238171095Ssam	xge_assert(xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN);
239171095Ssam
240171095Ssam	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
241173139Srwatson	    return XGE_HAL_ERR_INVALID_DEVICE;
242171095Ssam	}
243171095Ssam
244171095Ssam	if (size != sizeof(xge_hal_stats_hw_info_t)) {
245173139Srwatson	    return XGE_HAL_ERR_VERSION_CONFLICT;
246171095Ssam	}
247171095Ssam
248171095Ssam	if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
249173139Srwatson	    return status;
250171095Ssam	}
251171095Ssam
252171095Ssam	xge_os_memcpy(hw_stats, hw_info, sizeof(xge_hal_stats_hw_info_t));
253171095Ssam
254171095Ssam	return XGE_HAL_OK;
255171095Ssam}
256171095Ssam
257171095Ssam/**
258171095Ssam * xge_hal_mgmt_hw_stats_off - TBD.
259171095Ssam * @devh: HAL device handle.
260171095Ssam * @off: TBD
261171095Ssam * @size: TBD
262171095Ssam * @out: TBD
263171095Ssam *
264171095Ssam * Returns: XGE_HAL_OK - success.
265171095Ssam * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
266171095Ssam * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
267171095Ssam *
268171095Ssam * See also: xge_hal_mgmt_sw_stats().
269171095Ssam */
270171095Ssamxge_hal_status_e
271171095Ssamxge_hal_mgmt_hw_stats_off(xge_hal_device_h devh, int off, int size, char *out)
272171095Ssam{
273171095Ssam	xge_hal_status_e status;
274171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
275173139Srwatson	xge_hal_stats_hw_info_t *hw_info;
276171095Ssam
277171095Ssam	xge_assert(xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN);
278171095Ssam
279171095Ssam	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
280173139Srwatson	    return XGE_HAL_ERR_INVALID_DEVICE;
281171095Ssam	}
282171095Ssam
283171095Ssam	if (off > sizeof(xge_hal_stats_hw_info_t)-4 ||
284171095Ssam	    size > 8) {
285173139Srwatson	    return XGE_HAL_ERR_INVALID_OFFSET;
286171095Ssam	}
287171095Ssam
288171095Ssam	if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
289173139Srwatson	    return status;
290171095Ssam	}
291171095Ssam
292171095Ssam	xge_os_memcpy(out, (char*)hw_info + off, size);
293171095Ssam
294171095Ssam	return XGE_HAL_OK;
295171095Ssam}
296171095Ssam
297171095Ssam/**
298171095Ssam * xge_hal_mgmt_pcim_stats - Get Titan hardware statistics.
299171095Ssam * @devh: HAL device handle.
300171095Ssam * @pcim_stats: PCIM statistics. Returned by HAL.
301171095Ssam *            See xge_hal_stats_hw_info_t{}.
302171095Ssam * @size: Size of the @hw_stats buffer. HAL will return an error
303171095Ssam * if the size is smaller than sizeof(xge_hal_stats_hw_info_t).
304171095Ssam * Get Xframe hardware statistics.
305171095Ssam *
306171095Ssam * Returns: XGE_HAL_OK - success.
307171095Ssam * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
308171095Ssam * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
309171095Ssam *
310171095Ssam * See also: xge_hal_mgmt_sw_stats().
311171095Ssam */
312171095Ssamxge_hal_status_e
313171095Ssamxge_hal_mgmt_pcim_stats(xge_hal_device_h devh,
314173139Srwatson	    xge_hal_mgmt_pcim_stats_t *pcim_stats, int size)
315171095Ssam{
316171095Ssam	xge_hal_status_e status;
317171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
318173139Srwatson	xge_hal_stats_pcim_info_t   *pcim_info;
319171095Ssam
320171095Ssam	xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN);
321171095Ssam
322171095Ssam	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
323173139Srwatson	    return XGE_HAL_ERR_INVALID_DEVICE;
324171095Ssam	}
325171095Ssam
326171095Ssam	if (size != sizeof(xge_hal_stats_pcim_info_t)) {
327173139Srwatson	    return XGE_HAL_ERR_VERSION_CONFLICT;
328171095Ssam	}
329171095Ssam
330171095Ssam	if ((status = xge_hal_stats_pcim (devh, &pcim_info)) != XGE_HAL_OK) {
331173139Srwatson	    return status;
332171095Ssam	}
333171095Ssam
334171095Ssam	xge_os_memcpy(pcim_stats, pcim_info,
335173139Srwatson	    sizeof(xge_hal_stats_pcim_info_t));
336171095Ssam
337171095Ssam	return XGE_HAL_OK;
338171095Ssam}
339171095Ssam
340171095Ssam/**
341171095Ssam * xge_hal_mgmt_pcim_stats_off - TBD.
342171095Ssam * @devh: HAL device handle.
343171095Ssam * @off: TBD
344171095Ssam * @size: TBD
345171095Ssam * @out: TBD
346171095Ssam *
347171095Ssam * Returns: XGE_HAL_OK - success.
348171095Ssam * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
349171095Ssam * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
350171095Ssam *
351171095Ssam * See also: xge_hal_mgmt_sw_stats().
352171095Ssam */
353171095Ssamxge_hal_status_e
354171095Ssamxge_hal_mgmt_pcim_stats_off(xge_hal_device_h devh, int off, int size,
355173139Srwatson	            char *out)
356171095Ssam{
357171095Ssam	xge_hal_status_e status;
358171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
359173139Srwatson	xge_hal_stats_pcim_info_t   *pcim_info;
360171095Ssam
361171095Ssam	xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN);
362171095Ssam
363171095Ssam	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
364173139Srwatson	    return XGE_HAL_ERR_INVALID_DEVICE;
365171095Ssam	}
366171095Ssam
367171095Ssam	if (off > sizeof(xge_hal_stats_pcim_info_t)-8 ||
368171095Ssam	    size > 8) {
369173139Srwatson	    return XGE_HAL_ERR_INVALID_OFFSET;
370171095Ssam	}
371171095Ssam
372171095Ssam	if ((status = xge_hal_stats_pcim (devh, &pcim_info)) != XGE_HAL_OK) {
373173139Srwatson	    return status;
374171095Ssam	}
375171095Ssam
376171095Ssam	xge_os_memcpy(out, (char*)pcim_info + off, size);
377171095Ssam
378171095Ssam	return XGE_HAL_OK;
379171095Ssam}
380171095Ssam
381171095Ssam/**
382171095Ssam * xge_hal_mgmt_sw_stats - Get per-device software statistics.
383171095Ssam * @devh: HAL device handle.
384171095Ssam * @sw_stats: Hardware statistics. Returned by HAL.
385171095Ssam *            See xge_hal_stats_sw_err_t{}.
386171095Ssam * @size: Size of the @sw_stats buffer. HAL will return an error
387171095Ssam * if the size is smaller than sizeof(xge_hal_stats_sw_err_t).
388171095Ssam * Get device software statistics, including ECC and Parity error
389171095Ssam * counters, etc.
390171095Ssam *
391171095Ssam * Returns: XGE_HAL_OK - success.
392171095Ssam * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
393171095Ssam * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
394171095Ssam *
395171095Ssam * See also: xge_hal_stats_sw_err_t{}, xge_hal_mgmt_hw_stats().
396171095Ssam */
397171095Ssamxge_hal_status_e
398171095Ssamxge_hal_mgmt_sw_stats(xge_hal_device_h devh, xge_hal_mgmt_sw_stats_t *sw_stats,
399173139Srwatson	    int size)
400171095Ssam{
401171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
402171095Ssam
403171095Ssam	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
404173139Srwatson	    return XGE_HAL_ERR_INVALID_DEVICE;
405171095Ssam	}
406171095Ssam
407171095Ssam	if (size != sizeof(xge_hal_stats_sw_err_t)) {
408173139Srwatson	    return XGE_HAL_ERR_VERSION_CONFLICT;
409171095Ssam	}
410171095Ssam
411171095Ssam	if (!hldev->stats.is_initialized ||
412171095Ssam	    !hldev->stats.is_enabled) {
413173139Srwatson	    return XGE_HAL_INF_STATS_IS_NOT_READY;
414171095Ssam	}
415171095Ssam
416171095Ssam	/* Updating xpak stats value */
417171095Ssam	__hal_updt_stats_xpak(hldev);
418171095Ssam
419171095Ssam	xge_os_memcpy(sw_stats, &hldev->stats.sw_dev_err_stats,
420171095Ssam	            sizeof(xge_hal_stats_sw_err_t));
421171095Ssam
422171095Ssam	return XGE_HAL_OK;
423171095Ssam}
424171095Ssam
425171095Ssam/**
426171095Ssam * xge_hal_mgmt_device_stats - Get HAL device statistics.
427171095Ssam * @devh: HAL device handle.
428171095Ssam * @device_stats: HAL device "soft" statistics. Maintained by HAL itself.
429171095Ssam *            (as opposed to xge_hal_mgmt_hw_stats() - those are
430171095Ssam *            maintained by the Xframe hardware).
431171095Ssam *            Returned by HAL.
432171095Ssam *            See xge_hal_stats_device_info_t{}.
433171095Ssam * @size: Size of the @device_stats buffer. HAL will return an error
434171095Ssam * if the size is smaller than sizeof(xge_hal_stats_device_info_t).
435171095Ssam *
436171095Ssam * Get HAL (layer) statistic counters.
437171095Ssam * Returns: XGE_HAL_OK - success.
438171095Ssam * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
439171095Ssam * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
440171095Ssam * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
441171095Ssam * currently available.
442171095Ssam *
443171095Ssam */
444171095Ssamxge_hal_status_e
445171095Ssamxge_hal_mgmt_device_stats(xge_hal_device_h devh,
446173139Srwatson	    xge_hal_mgmt_device_stats_t *device_stats, int size)
447171095Ssam{
448171095Ssam	xge_hal_status_e status;
449171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
450171095Ssam	xge_hal_stats_device_info_t *device_info;
451171095Ssam
452171095Ssam	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
453173139Srwatson	    return XGE_HAL_ERR_INVALID_DEVICE;
454171095Ssam	}
455171095Ssam
456171095Ssam	if (size != sizeof(xge_hal_stats_device_info_t)) {
457173139Srwatson	    return XGE_HAL_ERR_VERSION_CONFLICT;
458171095Ssam	}
459171095Ssam
460171095Ssam	if ((status = xge_hal_stats_device (devh, &device_info)) !=
461171095Ssam	XGE_HAL_OK) {
462173139Srwatson	    return status;
463171095Ssam	}
464171095Ssam
465171095Ssam	xge_os_memcpy(device_stats, device_info,
466173139Srwatson	        sizeof(xge_hal_stats_device_info_t));
467171095Ssam
468171095Ssam	return XGE_HAL_OK;
469171095Ssam}
470171095Ssam
471171095Ssam/*
472171095Ssam * __hal_update_ring_bump - Update the ring bump counter for the
473171095Ssam * particular channel.
474171095Ssam * @hldev: HAL device handle.
475171095Ssam * @queue: the queue who's data is to be collected.
476171095Ssam * @chinfo: pointer to the statistics structure of the given channel.
477171095Ssam * Usage: See xge_hal_aux_stats_hal_read{}
478171095Ssam */
479171095Ssam
480171095Ssamstatic void
481171095Ssam__hal_update_ring_bump(xge_hal_device_t *hldev, int queue,
482171095Ssam	xge_hal_stats_channel_info_t *chinfo)
483171095Ssam{
484171095Ssam	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
485171095Ssam	u64 rbc = 0;
486171095Ssam	int reg = (queue / 4);
487171095Ssam	void * addr;
488171095Ssam
489171095Ssam	addr = (reg == 1)? (&bar0->ring_bump_counter2) :
490173139Srwatson	    (&bar0->ring_bump_counter1);
491171095Ssam	rbc = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, addr);
492171095Ssam	chinfo->ring_bump_cnt = XGE_HAL_RING_BUMP_CNT(queue, rbc);
493171095Ssam}
494171095Ssam
495171095Ssam/**
496171095Ssam * xge_hal_mgmt_channel_stats - Get HAL channel statistics.
497171095Ssam * @channelh: HAL channel handle.
498171095Ssam * @channel_stats: HAL channel statistics. Maintained by HAL itself
499171095Ssam *            (as opposed to xge_hal_mgmt_hw_stats() - those are
500171095Ssam *            maintained by the Xframe hardware).
501171095Ssam *            Returned by HAL.
502171095Ssam *            See xge_hal_stats_channel_info_t{}.
503171095Ssam * @size: Size of the @channel_stats buffer. HAL will return an error
504171095Ssam * if the size is smaller than sizeof(xge_hal_mgmt_channel_stats_t).
505171095Ssam *
506171095Ssam * Get HAL per-channel statistic counters.
507171095Ssam *
508171095Ssam * Returns: XGE_HAL_OK - success.
509171095Ssam * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
510171095Ssam * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
511171095Ssam * currently available.
512171095Ssam *
513171095Ssam */
514171095Ssamxge_hal_status_e
515171095Ssamxge_hal_mgmt_channel_stats(xge_hal_channel_h channelh,
516173139Srwatson	    xge_hal_mgmt_channel_stats_t *channel_stats, int size)
517171095Ssam{
518171095Ssam	xge_hal_status_e status;
519171095Ssam	xge_hal_stats_channel_info_t *channel_info;
520171095Ssam	xge_hal_channel_t *channel = (xge_hal_channel_t* ) channelh;
521171095Ssam
522171095Ssam	if (size != sizeof(xge_hal_stats_channel_info_t)) {
523173139Srwatson	    return XGE_HAL_ERR_VERSION_CONFLICT;
524171095Ssam	}
525171095Ssam
526171095Ssam	if ((status = xge_hal_stats_channel (channelh, &channel_info)) !=
527173139Srwatson	                            XGE_HAL_OK) {
528173139Srwatson	    return status;
529171095Ssam	}
530171095Ssam
531171095Ssam	if (xge_hal_device_check_id(channel->devh) == XGE_HAL_CARD_HERC) {
532173139Srwatson	    __hal_update_ring_bump( (xge_hal_device_t *) channel->devh, channel->post_qid, channel_info);
533171095Ssam	}
534171095Ssam
535171095Ssam	xge_os_memcpy(channel_stats, channel_info,
536173139Srwatson	        sizeof(xge_hal_stats_channel_info_t));
537171095Ssam
538171095Ssam	return XGE_HAL_OK;
539171095Ssam}
540171095Ssam
541171095Ssam/**
542171095Ssam * xge_hal_mgmt_pcireg_read - Read PCI configuration at a specified
543171095Ssam * offset.
544171095Ssam * @devh: HAL device handle.
545171095Ssam * @offset: Offset in the 256 byte PCI configuration space.
546171095Ssam * @value_bits: 8, 16, or 32 (bits) to read.
547171095Ssam * @value: Value returned by HAL.
548171095Ssam *
549171095Ssam * Read PCI configuration, given device and offset in the PCI space.
550171095Ssam *
551171095Ssam * Returns: XGE_HAL_OK - success.
552171095Ssam * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
553171095Ssam * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
554171095Ssam * valid.
555171095Ssam * XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE - Invalid bits size. Valid
556171095Ssam * values(8/16/32).
557171095Ssam *
558171095Ssam */
559171095Ssamxge_hal_status_e
560171095Ssamxge_hal_mgmt_pcireg_read(xge_hal_device_h devh, unsigned int offset,
561173139Srwatson	    int value_bits, u32 *value)
562171095Ssam{
563171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
564171095Ssam
565171095Ssam	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
566173139Srwatson	    return XGE_HAL_ERR_INVALID_DEVICE;
567171095Ssam	}
568171095Ssam
569171095Ssam	if (offset > sizeof(xge_hal_pci_config_t)-value_bits/8) {
570173139Srwatson	    return XGE_HAL_ERR_INVALID_OFFSET;
571171095Ssam	}
572171095Ssam
573171095Ssam	if (value_bits == 8) {
574173139Srwatson	    xge_os_pci_read8(hldev->pdev, hldev->cfgh, offset, (u8*)value);
575171095Ssam	} else if (value_bits == 16) {
576173139Srwatson	    xge_os_pci_read16(hldev->pdev, hldev->cfgh, offset,
577173139Srwatson	    (u16*)value);
578171095Ssam	} else if (value_bits == 32) {
579173139Srwatson	    xge_os_pci_read32(hldev->pdev, hldev->cfgh, offset, value);
580171095Ssam	} else {
581173139Srwatson	    return XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE;
582171095Ssam	}
583171095Ssam
584171095Ssam	return XGE_HAL_OK;
585171095Ssam}
586171095Ssam
587171095Ssam/**
588171095Ssam * xge_hal_mgmt_device_config - Retrieve device configuration.
589171095Ssam * @devh: HAL device handle.
590171095Ssam * @dev_config: Device configuration, see xge_hal_device_config_t{}.
591171095Ssam * @size: Size of the @dev_config buffer. HAL will return an error
592171095Ssam * if the size is smaller than sizeof(xge_hal_mgmt_device_config_t).
593171095Ssam *
594171095Ssam * Get device configuration. Permits to retrieve at run-time configuration
595171095Ssam * values that were used to initialize and configure the device.
596171095Ssam *
597171095Ssam * Returns: XGE_HAL_OK - success.
598171095Ssam * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
599171095Ssam * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
600171095Ssam *
601171095Ssam * See also: xge_hal_device_config_t{}, xge_hal_mgmt_driver_config().
602171095Ssam */
603171095Ssamxge_hal_status_e
604171095Ssamxge_hal_mgmt_device_config(xge_hal_device_h devh,
605173139Srwatson	    xge_hal_mgmt_device_config_t    *dev_config, int size)
606171095Ssam{
607171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
608171095Ssam
609171095Ssam	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
610173139Srwatson	    return XGE_HAL_ERR_INVALID_DEVICE;
611171095Ssam	}
612171095Ssam
613171095Ssam	if (size != sizeof(xge_hal_mgmt_device_config_t)) {
614173139Srwatson	    return XGE_HAL_ERR_VERSION_CONFLICT;
615171095Ssam	}
616171095Ssam
617171095Ssam	xge_os_memcpy(dev_config, &hldev->config,
618171095Ssam	sizeof(xge_hal_device_config_t));
619171095Ssam
620171095Ssam	return XGE_HAL_OK;
621171095Ssam}
622171095Ssam
623171095Ssam/**
624171095Ssam * xge_hal_mgmt_driver_config - Retrieve driver configuration.
625171095Ssam * @drv_config: Device configuration, see xge_hal_driver_config_t{}.
626171095Ssam * @size: Size of the @dev_config buffer. HAL will return an error
627171095Ssam * if the size is smaller than sizeof(xge_hal_mgmt_driver_config_t).
628171095Ssam *
629171095Ssam * Get driver configuration. Permits to retrieve at run-time configuration
630171095Ssam * values that were used to configure the device at load-time.
631171095Ssam *
632171095Ssam * Returns: XGE_HAL_OK - success.
633171095Ssam * XGE_HAL_ERR_DRIVER_NOT_INITIALIZED - HAL is not initialized.
634171095Ssam * XGE_HAL_ERR_VERSION_CONFLICT - Version is not maching.
635171095Ssam *
636171095Ssam * See also: xge_hal_driver_config_t{}, xge_hal_mgmt_device_config().
637171095Ssam */
638171095Ssamxge_hal_status_e
639171095Ssamxge_hal_mgmt_driver_config(xge_hal_mgmt_driver_config_t *drv_config, int size)
640171095Ssam{
641171095Ssam
642171095Ssam	if (g_xge_hal_driver == NULL) {
643173139Srwatson	    return XGE_HAL_ERR_DRIVER_NOT_INITIALIZED;
644171095Ssam	}
645171095Ssam
646171095Ssam	if (size != sizeof(xge_hal_mgmt_driver_config_t)) {
647173139Srwatson	    return XGE_HAL_ERR_VERSION_CONFLICT;
648171095Ssam	}
649171095Ssam
650171095Ssam	xge_os_memcpy(drv_config, &g_xge_hal_driver->config,
651173139Srwatson	        sizeof(xge_hal_mgmt_driver_config_t));
652171095Ssam
653171095Ssam	return XGE_HAL_OK;
654171095Ssam}
655171095Ssam
656171095Ssam/**
657171095Ssam * xge_hal_mgmt_pci_config - Retrieve PCI configuration.
658171095Ssam * @devh: HAL device handle.
659171095Ssam * @pci_config: 256 byte long buffer for PCI configuration space.
660171095Ssam * @size: Size of the @ buffer. HAL will return an error
661171095Ssam * if the size is smaller than sizeof(xge_hal_mgmt_pci_config_t).
662171095Ssam *
663171095Ssam * Get PCI configuration. Permits to retrieve at run-time configuration
664171095Ssam * values that were used to configure the device at load-time.
665171095Ssam *
666171095Ssam * Returns: XGE_HAL_OK - success.
667171095Ssam * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
668171095Ssam * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
669171095Ssam *
670171095Ssam */
671171095Ssamxge_hal_status_e
672171095Ssamxge_hal_mgmt_pci_config(xge_hal_device_h devh,
673173139Srwatson	    xge_hal_mgmt_pci_config_t *pci_config, int size)
674171095Ssam{
675171095Ssam	int i;
676171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
677171095Ssam
678171095Ssam	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
679173139Srwatson	    return XGE_HAL_ERR_INVALID_DEVICE;
680171095Ssam	}
681171095Ssam
682171095Ssam	if (size != sizeof(xge_hal_mgmt_pci_config_t)) {
683173139Srwatson	    return XGE_HAL_ERR_VERSION_CONFLICT;
684171095Ssam	}
685171095Ssam
686171095Ssam	/* refresh PCI config space */
687171095Ssam	for (i = 0; i < 0x68/4+1; i++) {
688173139Srwatson	    xge_os_pci_read32(hldev->pdev, hldev->cfgh, i*4,
689173139Srwatson	                    (u32*)&hldev->pci_config_space + i);
690171095Ssam	}
691171095Ssam
692171095Ssam	xge_os_memcpy(pci_config, &hldev->pci_config_space,
693173139Srwatson	        sizeof(xge_hal_mgmt_pci_config_t));
694171095Ssam
695171095Ssam	return XGE_HAL_OK;
696171095Ssam}
697171095Ssam
698171095Ssam#ifdef XGE_TRACE_INTO_CIRCULAR_ARR
699171095Ssam/**
700171095Ssam * xge_hal_mgmt_trace_read - Read trace buffer contents.
701171095Ssam * @buffer: Buffer to store the trace buffer contents.
702171095Ssam * @buf_size: Size of the buffer.
703171095Ssam * @offset: Offset in the internal trace buffer to read data.
704171095Ssam * @read_length: Size of the valid data in the buffer.
705171095Ssam *
706171095Ssam * Read  HAL trace buffer contents starting from the offset
707171095Ssam * upto the size of the buffer or till EOF is reached.
708171095Ssam *
709171095Ssam * Returns: XGE_HAL_OK - success.
710171095Ssam * XGE_HAL_EOF_TRACE_BUF - No more data in the trace buffer.
711171095Ssam *
712171095Ssam */
713171095Ssamxge_hal_status_e
714173139Srwatsonxge_hal_mgmt_trace_read (char       *buffer,
715173139Srwatson	        unsigned    buf_size,
716173139Srwatson	        unsigned    *offset,
717173139Srwatson	        unsigned    *read_length)
718171095Ssam{
719171095Ssam	int data_offset;
720171095Ssam	int start_offset;
721171095Ssam
722171095Ssam	if ((g_xge_os_tracebuf == NULL) ||
723173139Srwatson	    (g_xge_os_tracebuf->offset == g_xge_os_tracebuf->size - 2)) {
724173139Srwatson	    return XGE_HAL_EOF_TRACE_BUF;
725171095Ssam	}
726171095Ssam
727171095Ssam	data_offset = g_xge_os_tracebuf->offset + 1;
728171095Ssam
729171095Ssam	if  (*offset >= (unsigned)xge_os_strlen(g_xge_os_tracebuf->data +
730171095Ssam	data_offset)) {
731171095Ssam
732173139Srwatson	    return XGE_HAL_EOF_TRACE_BUF;
733171095Ssam	}
734171095Ssam
735171095Ssam	xge_os_memzero(buffer, buf_size);
736171095Ssam
737171095Ssam	start_offset  =  data_offset + *offset;
738171095Ssam	*read_length = xge_os_strlen(g_xge_os_tracebuf->data +
739171095Ssam	start_offset);
740171095Ssam
741171095Ssam	if (*read_length  >=  buf_size) {
742173139Srwatson	    *read_length = buf_size - 1;
743171095Ssam	}
744171095Ssam
745171095Ssam	xge_os_memcpy(buffer, g_xge_os_tracebuf->data + start_offset,
746171095Ssam	*read_length);
747171095Ssam
748171095Ssam	*offset += *read_length;
749171095Ssam	(*read_length) ++;
750171095Ssam
751171095Ssam	return XGE_HAL_OK;
752171095Ssam}
753171095Ssam
754171095Ssam#endif
755171095Ssam
756171095Ssam/**
757171095Ssam * xge_hal_restore_link_led - Restore link LED to its original state.
758171095Ssam * @devh: HAL device handle.
759171095Ssam */
760171095Ssamvoid
761171095Ssamxge_hal_restore_link_led(xge_hal_device_h devh)
762171095Ssam{
763171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
764171095Ssam	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
765171095Ssam	u64 val64;
766171095Ssam
767171095Ssam	/*
768171095Ssam	 * If the current link state is UP, switch on LED else make it
769171095Ssam	 * off.
770171095Ssam	 */
771171095Ssam
772171095Ssam	/*
773171095Ssam	 * For Xena 3 and lower revision cards, adapter control needs to be
774171095Ssam	 * used for making LED ON/OFF.
775171095Ssam	 */
776171095Ssam	if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
777171095Ssam	   (xge_hal_device_rev(hldev) <= 3)) {
778173139Srwatson	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
779173139Srwatson	                      &bar0->adapter_control);
780173139Srwatson	    if (hldev->link_state == XGE_HAL_LINK_UP) {
781173139Srwatson	        val64 |= XGE_HAL_ADAPTER_LED_ON;
782173139Srwatson	    } else {
783173139Srwatson	        val64 &= ~XGE_HAL_ADAPTER_LED_ON;
784173139Srwatson	    }
785171095Ssam
786173139Srwatson	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
787173139Srwatson	                &bar0->adapter_control);
788173139Srwatson	    return;
789171095Ssam	}
790171095Ssam
791171095Ssam	/*
792171095Ssam	 * Use beacon control register to control the LED.
793171095Ssam	 * LED link output corresponds to bit 8 of the beacon control
794171095Ssam	 * register. Note that, in the case of Xena, beacon control register
795171095Ssam	 * represents the gpio control register. In the case of Herc, LED
796171095Ssam	 * handling is done by beacon control register as opposed to gpio
797171095Ssam	 * control register in Xena. Beacon control is used only to toggle
798173139Srwatson	 * and the value written into it does not depend on the link state.
799173139Srwatson	 * It is upto the ULD to toggle the LED even number of times which
800173139Srwatson	 * brings the LED to it's original state.
801171095Ssam	 */
802171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
803173139Srwatson	                  &bar0->beacon_control);
804173139Srwatson	val64 |= 0x0000800000000000ULL;
805173139Srwatson	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
806173139Srwatson	               val64, &bar0->beacon_control);
807171095Ssam}
808171095Ssam
809171095Ssam/**
810171095Ssam * xge_hal_flick_link_led - Flick (blink) link LED.
811171095Ssam * @devh: HAL device handle.
812171095Ssam *
813171095Ssam * Depending on the card revision flicker the link LED by using the
814171095Ssam * beacon control or the adapter_control register.
815171095Ssam */
816171095Ssamvoid
817171095Ssamxge_hal_flick_link_led(xge_hal_device_h devh)
818171095Ssam{
819171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
820171095Ssam	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
821171095Ssam	u64 val64 = 0;
822171095Ssam
823171095Ssam	/*
824171095Ssam	 * For Xena 3 and lower revision cards, adapter control needs to be
825171095Ssam	 * used for making LED ON/OFF.
826171095Ssam	 */
827171095Ssam	if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
828171095Ssam	   (xge_hal_device_rev(hldev) <= 3)) {
829173139Srwatson	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
830173139Srwatson	                      &bar0->adapter_control);
831173139Srwatson	    val64 ^= XGE_HAL_ADAPTER_LED_ON;
832173139Srwatson	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
833173139Srwatson	                &bar0->adapter_control);
834173139Srwatson	    return;
835171095Ssam	}
836171095Ssam
837171095Ssam	/*
838171095Ssam	 * Use beacon control register to control the Link LED.
839171095Ssam	 * Note that, in the case of Xena, beacon control register represents
840171095Ssam	 * the gpio control register. In the case of Herc, LED handling is
841171095Ssam	 * done by beacon control register as opposed to gpio control register
842171095Ssam	 * in Xena.
843171095Ssam	 */
844171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
845173139Srwatson	                  &bar0->beacon_control);
846171095Ssam	val64 ^= XGE_HAL_GPIO_CTRL_GPIO_0;
847171095Ssam	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
848173139Srwatson	               &bar0->beacon_control);
849171095Ssam}
850171095Ssam
851171095Ssam/**
852171095Ssam * xge_hal_read_eeprom - Read 4 bytes of data from user given offset.
853171095Ssam * @devh: HAL device handle.
854171095Ssam * @off: offset at which the data must be written
855171095Ssam * @data: output parameter where the data is stored.
856171095Ssam *
857171095Ssam * Read 4 bytes of data from the user given offset and return the
858171095Ssam * read data.
859171095Ssam * Note: will allow to read only part of the EEPROM visible through the
860171095Ssam * I2C bus.
861171095Ssam * Returns: -1 on failure, 0 on success.
862171095Ssam */
863171095Ssamxge_hal_status_e
864171095Ssamxge_hal_read_eeprom(xge_hal_device_h devh, int off, u32* data)
865171095Ssam{
866171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
867171095Ssam	xge_hal_status_e ret = XGE_HAL_FAIL;
868171095Ssam	u32 exit_cnt = 0;
869171095Ssam	u64 val64;
870171095Ssam	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
871171095Ssam
872171095Ssam	val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) |
873173139Srwatson	    XGE_HAL_I2C_CONTROL_ADDR(off) |
874173139Srwatson	    XGE_HAL_I2C_CONTROL_BYTE_CNT(0x3) |
875173139Srwatson	    XGE_HAL_I2C_CONTROL_READ | XGE_HAL_I2C_CONTROL_CNTL_START;
876171095Ssam
877171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
878171095Ssam
879171095Ssam	while (exit_cnt < 5) {
880173139Srwatson	    val64 = __hal_serial_mem_read64(hldev, &bar0->i2c_control);
881173139Srwatson	    if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) {
882173139Srwatson	        *data = XGE_HAL_I2C_CONTROL_GET_DATA(val64);
883173139Srwatson	        ret = XGE_HAL_OK;
884173139Srwatson	        break;
885173139Srwatson	    }
886173139Srwatson	    exit_cnt++;
887171095Ssam	}
888171095Ssam
889171095Ssam	return ret;
890171095Ssam}
891171095Ssam
892171095Ssam/*
893171095Ssam * xge_hal_write_eeprom - actually writes the relevant part of the data
894171095Ssam value.
895171095Ssam * @devh: HAL device handle.
896171095Ssam * @off: offset at which the data must be written
897171095Ssam * @data : The data that is to be written
898171095Ssam * @cnt : Number of bytes of the data that are actually to be written into
899171095Ssam * the Eeprom. (max of 3)
900171095Ssam *
901171095Ssam * Actually writes the relevant part of the data value into the Eeprom
902171095Ssam * through the I2C bus.
903171095Ssam * Return value:
904171095Ssam * 0 on success, -1 on failure.
905171095Ssam */
906171095Ssam
907171095Ssamxge_hal_status_e
908171095Ssamxge_hal_write_eeprom(xge_hal_device_h devh, int off, u32 data, int cnt)
909171095Ssam{
910171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
911171095Ssam	xge_hal_status_e ret = XGE_HAL_FAIL;
912171095Ssam	u32 exit_cnt = 0;
913171095Ssam	u64 val64;
914171095Ssam	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
915171095Ssam
916171095Ssam	val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) |
917173139Srwatson	    XGE_HAL_I2C_CONTROL_ADDR(off) |
918173139Srwatson	    XGE_HAL_I2C_CONTROL_BYTE_CNT(cnt) |
919173139Srwatson	    XGE_HAL_I2C_CONTROL_SET_DATA(data) |
920173139Srwatson	    XGE_HAL_I2C_CONTROL_CNTL_START;
921171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
922171095Ssam
923171095Ssam	while (exit_cnt < 5) {
924173139Srwatson	    val64 = __hal_serial_mem_read64(hldev, &bar0->i2c_control);
925173139Srwatson	    if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) {
926173139Srwatson	        if (!(val64 & XGE_HAL_I2C_CONTROL_NACK))
927173139Srwatson	            ret = XGE_HAL_OK;
928173139Srwatson	        break;
929173139Srwatson	    }
930173139Srwatson	    exit_cnt++;
931171095Ssam	}
932171095Ssam
933171095Ssam	return ret;
934171095Ssam}
935171095Ssam
936171095Ssam/*
937171095Ssam * xge_hal_register_test - reads and writes into all clock domains.
938171095Ssam * @hldev : private member of the device structure.
939171095Ssam * xge_nic structure.
940171095Ssam * @data : variable that returns the result of each of the test conducted b
941171095Ssam * by the driver.
942171095Ssam *
943171095Ssam * Read and write into all clock domains. The NIC has 3 clock domains,
944171095Ssam * see that registers in all the three regions are accessible.
945171095Ssam * Return value:
946171095Ssam * 0 on success.
947171095Ssam */
948171095Ssamxge_hal_status_e
949171095Ssamxge_hal_register_test(xge_hal_device_h devh, u64 *data)
950171095Ssam{
951171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
952171095Ssam	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
953171095Ssam	u64 val64 = 0;
954171095Ssam	int fail = 0;
955171095Ssam
956171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
957173139Srwatson	        &bar0->pif_rd_swapper_fb);
958171095Ssam	if (val64 != 0x123456789abcdefULL) {
959173139Srwatson	    fail = 1;
960173139Srwatson	    xge_debug_osdep(XGE_TRACE, "Read Test level 1 fails");
961171095Ssam	}
962171095Ssam
963171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
964173139Srwatson	        &bar0->rmac_pause_cfg);
965171095Ssam	if (val64 != 0xc000ffff00000000ULL) {
966173139Srwatson	    fail = 1;
967173139Srwatson	    xge_debug_osdep(XGE_TRACE, "Read Test level 2 fails");
968171095Ssam	}
969171095Ssam
970171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
971173139Srwatson	        &bar0->rx_queue_cfg);
972171095Ssam	if (val64 != 0x0808080808080808ULL) {
973173139Srwatson	    fail = 1;
974173139Srwatson	    xge_debug_osdep(XGE_TRACE, "Read Test level 3 fails");
975171095Ssam	}
976171095Ssam
977171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
978173139Srwatson	        &bar0->xgxs_efifo_cfg);
979171095Ssam	if (val64 != 0x000000001923141EULL) {
980173139Srwatson	    fail = 1;
981173139Srwatson	    xge_debug_osdep(XGE_TRACE, "Read Test level 4 fails");
982171095Ssam	}
983171095Ssam
984171095Ssam	val64 = 0x5A5A5A5A5A5A5A5AULL;
985171095Ssam	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
986173139Srwatson	        &bar0->xmsi_data);
987171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
988173139Srwatson	        &bar0->xmsi_data);
989171095Ssam	if (val64 != 0x5A5A5A5A5A5A5A5AULL) {
990173139Srwatson	    fail = 1;
991173139Srwatson	    xge_debug_osdep(XGE_ERR, "Write Test level 1 fails");
992171095Ssam	}
993171095Ssam
994171095Ssam	val64 = 0xA5A5A5A5A5A5A5A5ULL;
995171095Ssam	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
996173139Srwatson	        &bar0->xmsi_data);
997171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
998173139Srwatson	        &bar0->xmsi_data);
999171095Ssam	if (val64 != 0xA5A5A5A5A5A5A5A5ULL) {
1000173139Srwatson	    fail = 1;
1001173139Srwatson	    xge_debug_osdep(XGE_ERR, "Write Test level 2 fails");
1002171095Ssam	}
1003171095Ssam
1004171095Ssam	*data = fail;
1005171095Ssam	return XGE_HAL_OK;
1006171095Ssam}
1007171095Ssam
1008171095Ssam/*
1009171095Ssam * xge_hal_rldram_test - offline test for access to the RldRam chip on
1010171095Ssam the NIC
1011171095Ssam * @devh: HAL device handle.
1012171095Ssam * @data: variable that returns the result of each of the test
1013171095Ssam * conducted by the driver.
1014171095Ssam *
1015171095Ssam * This is one of the offline test that tests the read and write
1016171095Ssam * access to the RldRam chip on the NIC.
1017171095Ssam * Return value:
1018171095Ssam * 0 on success.
1019171095Ssam */
1020171095Ssamxge_hal_status_e
1021171095Ssamxge_hal_rldram_test(xge_hal_device_h devh, u64 *data)
1022171095Ssam{
1023171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1024171095Ssam	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1025171095Ssam	u64 val64;
1026171095Ssam	int cnt, iteration = 0, test_pass = 0;
1027171095Ssam
1028171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1029173139Srwatson	        &bar0->adapter_control);
1030171095Ssam	val64 &= ~XGE_HAL_ADAPTER_ECC_EN;
1031171095Ssam	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1032173139Srwatson	        &bar0->adapter_control);
1033171095Ssam
1034171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1035173139Srwatson	        &bar0->mc_rldram_test_ctrl);
1036171095Ssam	val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE;
1037171095Ssam	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1038173139Srwatson	        &bar0->mc_rldram_test_ctrl);
1039171095Ssam
1040171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1041173139Srwatson	        &bar0->mc_rldram_mrs);
1042171095Ssam	val64 |= XGE_HAL_MC_RLDRAM_QUEUE_SIZE_ENABLE;
1043171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
1044171095Ssam
1045171095Ssam	val64 |= XGE_HAL_MC_RLDRAM_MRS_ENABLE;
1046171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
1047171095Ssam
1048171095Ssam	while (iteration < 2) {
1049173139Srwatson	    val64 = 0x55555555aaaa0000ULL;
1050173139Srwatson	    if (iteration == 1) {
1051173139Srwatson	        val64 ^= 0xFFFFFFFFFFFF0000ULL;
1052173139Srwatson	    }
1053173139Srwatson	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1054173139Srwatson	        &bar0->mc_rldram_test_d0);
1055171095Ssam
1056173139Srwatson	    val64 = 0xaaaa5a5555550000ULL;
1057173139Srwatson	    if (iteration == 1) {
1058173139Srwatson	        val64 ^= 0xFFFFFFFFFFFF0000ULL;
1059173139Srwatson	    }
1060173139Srwatson	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1061173139Srwatson	        &bar0->mc_rldram_test_d1);
1062171095Ssam
1063173139Srwatson	    val64 = 0x55aaaaaaaa5a0000ULL;
1064173139Srwatson	    if (iteration == 1) {
1065173139Srwatson	        val64 ^= 0xFFFFFFFFFFFF0000ULL;
1066173139Srwatson	    }
1067173139Srwatson	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1068173139Srwatson	        &bar0->mc_rldram_test_d2);
1069171095Ssam
1070173139Srwatson	    val64 = (u64) (0x0000003fffff0000ULL);
1071173139Srwatson	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1072173139Srwatson	        &bar0->mc_rldram_test_add);
1073171095Ssam
1074171095Ssam
1075173139Srwatson	    val64 = XGE_HAL_MC_RLDRAM_TEST_MODE;
1076173139Srwatson	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1077173139Srwatson	        &bar0->mc_rldram_test_ctrl);
1078171095Ssam
1079173139Srwatson	    val64 |=
1080173139Srwatson	        XGE_HAL_MC_RLDRAM_TEST_MODE | XGE_HAL_MC_RLDRAM_TEST_WRITE |
1081173139Srwatson	        XGE_HAL_MC_RLDRAM_TEST_GO;
1082173139Srwatson	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1083173139Srwatson	        &bar0->mc_rldram_test_ctrl);
1084171095Ssam
1085173139Srwatson	    for (cnt = 0; cnt < 5; cnt++) {
1086173139Srwatson	        val64 = xge_os_pio_mem_read64(hldev->pdev,
1087173139Srwatson	            hldev->regh0, &bar0->mc_rldram_test_ctrl);
1088173139Srwatson	        if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE)
1089173139Srwatson	            break;
1090173139Srwatson	        xge_os_mdelay(200);
1091173139Srwatson	    }
1092171095Ssam
1093173139Srwatson	    if (cnt == 5)
1094173139Srwatson	        break;
1095171095Ssam
1096173139Srwatson	    val64 = XGE_HAL_MC_RLDRAM_TEST_MODE;
1097173139Srwatson	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1098173139Srwatson	        &bar0->mc_rldram_test_ctrl);
1099171095Ssam
1100173139Srwatson	    val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE |
1101173139Srwatson	    XGE_HAL_MC_RLDRAM_TEST_GO;
1102173139Srwatson	    xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1103173139Srwatson	        &bar0->mc_rldram_test_ctrl);
1104171095Ssam
1105173139Srwatson	    for (cnt = 0; cnt < 5; cnt++) {
1106173139Srwatson	        val64 = xge_os_pio_mem_read64(hldev->pdev,
1107173139Srwatson	            hldev->regh0, &bar0->mc_rldram_test_ctrl);
1108173139Srwatson	        if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE)
1109173139Srwatson	            break;
1110173139Srwatson	        xge_os_mdelay(500);
1111173139Srwatson	    }
1112171095Ssam
1113173139Srwatson	    if (cnt == 5)
1114173139Srwatson	        break;
1115171095Ssam
1116173139Srwatson	    val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1117173139Srwatson	        &bar0->mc_rldram_test_ctrl);
1118173139Srwatson	    if (val64 & XGE_HAL_MC_RLDRAM_TEST_PASS)
1119173139Srwatson	        test_pass = 1;
1120171095Ssam
1121173139Srwatson	    iteration++;
1122171095Ssam	}
1123171095Ssam
1124171095Ssam	if (!test_pass)
1125173139Srwatson	    *data = 1;
1126171095Ssam	else
1127173139Srwatson	    *data = 0;
1128171095Ssam
1129171095Ssam	return XGE_HAL_OK;
1130171095Ssam}
1131171095Ssam
1132171095Ssam/*
1133171095Ssam * xge_hal_pma_loopback - Enable or disable PMA loopback
1134171095Ssam * @devh: HAL device handle.
1135171095Ssam * @enable:Boolean set to 1 to enable and 0 to disable.
1136171095Ssam *
1137171095Ssam * Enable or disable PMA loopback.
1138171095Ssam * Return value:
1139171095Ssam * 0 on success.
1140171095Ssam */
1141171095Ssamxge_hal_status_e
1142171095Ssamxge_hal_pma_loopback( xge_hal_device_h devh, int enable )
1143171095Ssam{
1144171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1145171095Ssam	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1146171095Ssam	u64 val64;
1147171095Ssam	u16 data;
1148171095Ssam
1149171095Ssam	/*
1150171095Ssam	 * This code if for MAC loopbak
1151171095Ssam	 * Should be enabled through another parameter
1152171095Ssam	 */
1153171095Ssam#if 0
1154171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1155171095Ssam	&bar0->mac_cfg);
1156173139Srwatson	if ( enable )
1157173139Srwatson	{
1158173139Srwatson	    val64 |= ( XGE_HAL_MAC_CFG_TMAC_LOOPBACK | XGE_HAL_MAC_CFG_RMAC_PROM_ENABLE );
1159173139Srwatson	}
1160171095Ssam	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
1161173139Srwatson	        (u32)(val64 >> 32), (char*)&bar0->mac_cfg);
1162171095Ssam	xge_os_mdelay(1);
1163171095Ssam#endif
1164171095Ssam
1165171095Ssam	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
1166173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
1167173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1168173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_CTRL(0)       |
1169173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
1170171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1171171095Ssam
1172171095Ssam	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1173171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1174171095Ssam
1175171095Ssam	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
1176173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
1177173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1178173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_CTRL(0)       |
1179173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_READ);
1180171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1181171095Ssam
1182171095Ssam	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1183171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1184171095Ssam
1185171095Ssam	val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1186171095Ssam
1187171095Ssam	data = (u16)XGE_HAL_MDIO_CONTROL_MMD_DATA_GET(val64);
1188171095Ssam
1189171095Ssam#define _HAL_LOOPBK_PMA         1
1190171095Ssam
1191171095Ssam	if( enable )
1192173139Srwatson	    data |= 1;
1193171095Ssam	else
1194173139Srwatson	    data &= 0xfe;
1195171095Ssam
1196171095Ssam	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
1197173139Srwatson	     XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
1198173139Srwatson	     XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1199173139Srwatson	     XGE_HAL_MDIO_CONTROL_MMD_CTRL(0)       |
1200173139Srwatson	     XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
1201171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1202171095Ssam
1203171095Ssam	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1204171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1205171095Ssam
1206171095Ssam	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
1207173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
1208173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1209173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_DATA(data)    |
1210173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_CTRL(0x0)     |
1211173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_WRITE);
1212171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1213171095Ssam
1214171095Ssam	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1215171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1216171095Ssam
1217171095Ssam	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
1218173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
1219173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1220173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_CTRL(0x0)     |
1221173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_READ);
1222171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1223171095Ssam
1224171095Ssam	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1225171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1226171095Ssam
1227173139Srwatson	return XGE_HAL_OK;
1228171095Ssam}
1229171095Ssam
1230171095Ssamu16
1231171095Ssamxge_hal_mdio_read( xge_hal_device_h devh, u32 mmd_type, u64 addr )
1232171095Ssam{
1233171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1234171095Ssam	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1235171095Ssam	u64 val64 = 0x0;
1236171095Ssam	u16 rval16 = 0x0;
1237171095Ssam	u8  i = 0;
1238171095Ssam
1239171095Ssam	/* address transaction */
1240171095Ssam	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr)  |
1241173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type)   |
1242173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1243173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
1244171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1245171095Ssam
1246171095Ssam	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1247171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1248171095Ssam	do
1249171095Ssam	{
1250173139Srwatson	    val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1251173139Srwatson	    if (i++ > 10)
1252173139Srwatson	    {
1253173139Srwatson	        break;
1254173139Srwatson	    }
1255171095Ssam	}while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) != XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
1256171095Ssam
1257171095Ssam	/* Data transaction */
1258171095Ssam	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr)  |
1259173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type)   |
1260173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1261173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_READ);
1262171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1263171095Ssam
1264171095Ssam	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1265171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1266171095Ssam
1267171095Ssam	i = 0;
1268171095Ssam
1269171095Ssam	do
1270171095Ssam	{
1271173139Srwatson	    val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1272173139Srwatson	    if (i++ > 10)
1273173139Srwatson	    {
1274173139Srwatson	        break;
1275173139Srwatson	    }
1276171095Ssam	}while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) != XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
1277171095Ssam
1278171095Ssam	rval16 = (u16)XGE_HAL_MDIO_CONTROL_MMD_DATA_GET(val64);
1279171095Ssam
1280171095Ssam	return rval16;
1281171095Ssam}
1282171095Ssam
1283171095Ssamxge_hal_status_e
1284171095Ssamxge_hal_mdio_write( xge_hal_device_h devh, u32 mmd_type, u64 addr, u32 value )
1285171095Ssam{
1286171095Ssam	u64 val64 = 0x0;
1287171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1288171095Ssam	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1289171095Ssam	u8  i = 0;
1290171095Ssam	/* address transaction */
1291171095Ssam
1292171095Ssam	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr)  |
1293173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type)   |
1294173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1295173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
1296171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1297171095Ssam
1298171095Ssam	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1299171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1300171095Ssam
1301171095Ssam	do
1302171095Ssam	{
1303173139Srwatson	    val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1304173139Srwatson	    if (i++ > 10)
1305173139Srwatson	    {
1306173139Srwatson	        break;
1307173139Srwatson	    }
1308171095Ssam	} while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) !=
1309173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
1310171095Ssam
1311171095Ssam	/* Data transaction */
1312171095Ssam
1313171095Ssam	val64 = 0x0;
1314171095Ssam
1315171095Ssam	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr)    |
1316173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type) |
1317173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)        |
1318173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_DATA(value)        |
1319173139Srwatson	    XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_WRITE);
1320171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1321171095Ssam
1322171095Ssam	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1323171095Ssam	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1324171095Ssam
1325171095Ssam	i = 0;
1326171095Ssam
1327171095Ssam	do
1328171095Ssam	{
1329173139Srwatson	    val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1330173139Srwatson	    if (i++ > 10)
1331173139Srwatson	    {
1332173139Srwatson	        break;
1333173139Srwatson	    }
1334171095Ssam	}while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) != XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
1335171095Ssam
1336171095Ssam	return XGE_HAL_OK;
1337171095Ssam}
1338171095Ssam
1339171095Ssam/*
1340171095Ssam * xge_hal_eeprom_test - to verify that EEprom in the xena can be
1341171095Ssam programmed.
1342171095Ssam * @devh: HAL device handle.
1343171095Ssam * @data:variable that returns the result of each of the test conducted by
1344171095Ssam * the driver.
1345171095Ssam *
1346171095Ssam * Verify that EEPROM in the xena can be programmed using I2C_CONTROL
1347171095Ssam * register.
1348171095Ssam * Return value:
1349171095Ssam * 0 on success.
1350171095Ssam */
1351171095Ssamxge_hal_status_e
1352171095Ssamxge_hal_eeprom_test(xge_hal_device_h devh, u64 *data)
1353171095Ssam{
1354171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1355171095Ssam	int fail     = 0;
1356171095Ssam	u32 ret_data = 0;
1357171095Ssam
1358171095Ssam	/* Test Write Error at offset 0 */
1359171095Ssam	if (!xge_hal_write_eeprom(hldev, 0, 0, 3))
1360173139Srwatson	    fail = 1;
1361171095Ssam
1362171095Ssam	/* Test Write at offset 4f0 */
1363171095Ssam	if (xge_hal_write_eeprom(hldev, 0x4F0, 0x01234567, 3))
1364173139Srwatson	    fail = 1;
1365171095Ssam	if (xge_hal_read_eeprom(hldev, 0x4F0, &ret_data))
1366173139Srwatson	    fail = 1;
1367171095Ssam
1368171095Ssam	if (ret_data != 0x01234567)
1369173139Srwatson	    fail = 1;
1370171095Ssam
1371171095Ssam	/* Reset the EEPROM data go FFFF */
1372171095Ssam	(void) xge_hal_write_eeprom(hldev, 0x4F0, 0xFFFFFFFF, 3);
1373171095Ssam
1374171095Ssam	/* Test Write Request Error at offset 0x7c */
1375171095Ssam	if (!xge_hal_write_eeprom(hldev, 0x07C, 0, 3))
1376173139Srwatson	    fail = 1;
1377171095Ssam
1378171095Ssam	/* Test Write Request at offset 0x7fc */
1379171095Ssam	if (xge_hal_write_eeprom(hldev, 0x7FC, 0x01234567, 3))
1380173139Srwatson	    fail = 1;
1381171095Ssam	if (xge_hal_read_eeprom(hldev, 0x7FC, &ret_data))
1382173139Srwatson	    fail = 1;
1383171095Ssam
1384171095Ssam	if (ret_data != 0x01234567)
1385173139Srwatson	    fail = 1;
1386171095Ssam
1387171095Ssam	/* Reset the EEPROM data go FFFF */
1388171095Ssam	(void) xge_hal_write_eeprom(hldev, 0x7FC, 0xFFFFFFFF, 3);
1389171095Ssam
1390171095Ssam	/* Test Write Error at offset 0x80 */
1391171095Ssam	if (!xge_hal_write_eeprom(hldev, 0x080, 0, 3))
1392173139Srwatson	    fail = 1;
1393171095Ssam
1394171095Ssam	/* Test Write Error at offset 0xfc */
1395171095Ssam	if (!xge_hal_write_eeprom(hldev, 0x0FC, 0, 3))
1396173139Srwatson	    fail = 1;
1397171095Ssam
1398171095Ssam	/* Test Write Error at offset 0x100 */
1399171095Ssam	if (!xge_hal_write_eeprom(hldev, 0x100, 0, 3))
1400173139Srwatson	    fail = 1;
1401171095Ssam
1402171095Ssam	/* Test Write Error at offset 4ec */
1403171095Ssam	if (!xge_hal_write_eeprom(hldev, 0x4EC, 0, 3))
1404173139Srwatson	    fail = 1;
1405171095Ssam
1406171095Ssam	*data = fail;
1407171095Ssam	return XGE_HAL_OK;
1408171095Ssam}
1409171095Ssam
1410171095Ssam/*
1411171095Ssam * xge_hal_bist_test - invokes the MemBist test of the card .
1412171095Ssam * @devh: HAL device handle.
1413171095Ssam * xge_nic structure.
1414171095Ssam * @data:variable that returns the result of each of the test conducted by
1415171095Ssam * the driver.
1416171095Ssam *
1417171095Ssam * This invokes the MemBist test of the card. We give around
1418171095Ssam * 2 secs time for the Test to complete. If it's still not complete
1419171095Ssam * within this peiod, we consider that the test failed.
1420171095Ssam * Return value:
1421171095Ssam * 0 on success and -1 on failure.
1422171095Ssam */
1423171095Ssamxge_hal_status_e
1424171095Ssamxge_hal_bist_test(xge_hal_device_h devh, u64 *data)
1425171095Ssam{
1426171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1427171095Ssam	u8 bist = 0;
1428171095Ssam	int cnt = 0;
1429171095Ssam	xge_hal_status_e ret = XGE_HAL_FAIL;
1430171095Ssam
1431171095Ssam	xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist);
1432171095Ssam	bist |= 0x40;
1433171095Ssam	xge_os_pci_write8(hldev->pdev, hldev->cfgh, 0x0f, bist);
1434171095Ssam
1435171095Ssam	while (cnt < 20) {
1436173139Srwatson	    xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist);
1437173139Srwatson	    if (!(bist & 0x40)) {
1438173139Srwatson	        *data = (bist & 0x0f);
1439173139Srwatson	        ret = XGE_HAL_OK;
1440173139Srwatson	        break;
1441173139Srwatson	    }
1442173139Srwatson	    xge_os_mdelay(100);
1443173139Srwatson	    cnt++;
1444171095Ssam	}
1445171095Ssam
1446171095Ssam	return ret;
1447171095Ssam}
1448171095Ssam
1449171095Ssam/*
1450171095Ssam * xge_hal_link_test - verifies the link state of the nic
1451171095Ssam * @devh: HAL device handle.
1452171095Ssam * @data: variable that returns the result of each of the test conducted by
1453171095Ssam * the driver.
1454171095Ssam *
1455171095Ssam * Verify the link state of the NIC and updates the input
1456171095Ssam * argument 'data' appropriately.
1457171095Ssam * Return value:
1458171095Ssam * 0 on success.
1459171095Ssam */
1460171095Ssamxge_hal_status_e
1461171095Ssamxge_hal_link_test(xge_hal_device_h devh, u64 *data)
1462171095Ssam{
1463171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1464171095Ssam	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1465171095Ssam	u64 val64;
1466171095Ssam
1467171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1468173139Srwatson	        &bar0->adapter_status);
1469171095Ssam	if (val64 & XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)
1470173139Srwatson	    *data = 1;
1471171095Ssam
1472171095Ssam	return XGE_HAL_OK;
1473171095Ssam}
1474171095Ssam
1475171095Ssam
1476171095Ssam/**
1477171095Ssam * xge_hal_getpause_data -Pause frame frame generation and reception.
1478171095Ssam * @devh: HAL device handle.
1479171095Ssam * @tx : A field to return the pause generation capability of the NIC.
1480171095Ssam * @rx : A field to return the pause reception capability of the NIC.
1481171095Ssam *
1482171095Ssam * Returns the Pause frame generation and reception capability of the NIC.
1483171095Ssam * Return value:
1484171095Ssam *  void
1485171095Ssam */
1486171095Ssamvoid xge_hal_getpause_data(xge_hal_device_h devh, int *tx, int *rx)
1487171095Ssam{
1488171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1489171095Ssam	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1490171095Ssam	u64 val64;
1491171095Ssam
1492171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1493173139Srwatson	            &bar0->rmac_pause_cfg);
1494171095Ssam	if (val64 & XGE_HAL_RMAC_PAUSE_GEN_EN)
1495173139Srwatson	    *tx = 1;
1496171095Ssam	if (val64 & XGE_HAL_RMAC_PAUSE_RCV_EN)
1497173139Srwatson	    *rx = 1;
1498171095Ssam}
1499171095Ssam
1500171095Ssam/**
1501171095Ssam * xge_hal_setpause_data -  set/reset pause frame generation.
1502171095Ssam * @devh: HAL device handle.
1503171095Ssam * @tx: A field that indicates the pause generation capability to be
1504171095Ssam * set on the NIC.
1505171095Ssam * @rx: A field that indicates the pause reception capability to be
1506171095Ssam * set on the NIC.
1507171095Ssam *
1508171095Ssam * It can be used to set or reset Pause frame generation or reception
1509171095Ssam * support of the NIC.
1510171095Ssam * Return value:
1511171095Ssam * int, returns 0 on Success
1512171095Ssam */
1513171095Ssam
1514171095Ssamint xge_hal_setpause_data(xge_hal_device_h devh, int tx, int rx)
1515171095Ssam{
1516171095Ssam	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1517171095Ssam	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1518171095Ssam	u64 val64;
1519171095Ssam
1520171095Ssam	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1521173139Srwatson	                &bar0->rmac_pause_cfg);
1522171095Ssam	if (tx)
1523173139Srwatson	    val64 |= XGE_HAL_RMAC_PAUSE_GEN_EN;
1524171095Ssam	else
1525173139Srwatson	    val64 &= ~XGE_HAL_RMAC_PAUSE_GEN_EN;
1526171095Ssam	if (rx)
1527173139Srwatson	    val64 |= XGE_HAL_RMAC_PAUSE_RCV_EN;
1528171095Ssam	else
1529173139Srwatson	    val64 &= ~XGE_HAL_RMAC_PAUSE_RCV_EN;
1530171095Ssam	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1531173139Srwatson	             val64, &bar0->rmac_pause_cfg);
1532171095Ssam	return 0;
1533171095Ssam}
1534171095Ssam
1535171095Ssam/**
1536171095Ssam * xge_hal_read_xfp_current_temp -
1537171095Ssam * @hldev: HAL device handle.
1538171095Ssam *
1539171095Ssam * This routine only gets the temperature for XFP modules. Also, updating of the
1540171095Ssam * NVRAM can sometimes fail and so the reading we might get may not be uptodate.
1541171095Ssam */
1542171095Ssamu32 xge_hal_read_xfp_current_temp(xge_hal_device_h hldev)
1543171095Ssam{
1544173139Srwatson	u16 val_1, val_2, i = 0;
1545173139Srwatson	u32 actual;
1546171095Ssam
1547173139Srwatson	/* First update the NVRAM table of XFP. */
1548171095Ssam
1549173139Srwatson	(void) xge_hal_mdio_write(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8000, 0x3);
1550171095Ssam
1551171095Ssam
1552173139Srwatson	/* Now wait for the transfer to complete */
1553173139Srwatson	do
1554173139Srwatson	{
1555173139Srwatson	    xge_os_mdelay( 50 ); // wait 50 milliseonds
1556171095Ssam
1557173139Srwatson	    val_1 =  xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8000);
1558171095Ssam
1559173139Srwatson	    if ( i++ > 10 )
1560173139Srwatson	    {
1561173139Srwatson	        // waited 500 ms which should be plenty of time.
1562173139Srwatson	        break;
1563173139Srwatson	    }
1564173139Srwatson	}while (( val_1 & 0x000C ) != 0x0004);
1565171095Ssam
1566173139Srwatson	/* Now NVRAM table of XFP should be updated, so read the temp */
1567173139Srwatson	val_1 =  (u8) xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8067);
1568173139Srwatson	val_2 =  (u8) xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8068);
1569171095Ssam
1570173139Srwatson	actual = ((val_1 << 8) | val_2);
1571171095Ssam
1572173139Srwatson	if (actual >= 32768)
1573173139Srwatson	    actual = actual- 65536;
1574173139Srwatson	actual =  actual/256;
1575171095Ssam
1576173139Srwatson	return actual;
1577171095Ssam}
1578171095Ssam
1579171095Ssam/**
1580171095Ssam * __hal_chk_xpak_counter -  check the Xpak error count and log the msg.
1581171095Ssam * @hldev: pointer to xge_hal_device_t structure
1582171095Ssam * @type:  xpak stats error type
1583171095Ssam * @value: xpak stats value
1584171095Ssam *
1585171095Ssam * It is used to log the error message based on the xpak stats value
1586171095Ssam * Return value:
1587171095Ssam * None
1588171095Ssam */
1589171095Ssam
1590171095Ssamvoid __hal_chk_xpak_counter(xge_hal_device_t *hldev, int type, u32 value)
1591171095Ssam{
1592171095Ssam	/*
1593171095Ssam	 * If the value is high for three consecutive cylce,
1594171095Ssam	 * log a error message
1595171095Ssam	 */
1596171095Ssam	if(value == 3)
1597171095Ssam	{
1598173139Srwatson	    switch(type)
1599173139Srwatson	    {
1600173139Srwatson	    case 1:
1601173139Srwatson	        hldev->stats.sw_dev_err_stats.xpak_counter.
1602173139Srwatson	            excess_temp = 0;
1603171095Ssam
1604173139Srwatson	        /*
1605173139Srwatson	         * Notify the ULD on Excess Xpak temperature alarm msg
1606173139Srwatson	         */
1607173139Srwatson	        if (g_xge_hal_driver->uld_callbacks.xpak_alarm_log) {
1608173139Srwatson	            g_xge_hal_driver->uld_callbacks.xpak_alarm_log(
1609173139Srwatson	                hldev->upper_layer_info,
1610173139Srwatson	                XGE_HAL_XPAK_ALARM_EXCESS_TEMP);
1611173139Srwatson	        }
1612173139Srwatson	        break;
1613173139Srwatson	    case 2:
1614173139Srwatson	        hldev->stats.sw_dev_err_stats.xpak_counter.
1615173139Srwatson	            excess_bias_current = 0;
1616171095Ssam
1617173139Srwatson	        /*
1618173139Srwatson	         * Notify the ULD on Excess  xpak bias current alarm msg
1619173139Srwatson	         */
1620173139Srwatson	        if (g_xge_hal_driver->uld_callbacks.xpak_alarm_log) {
1621173139Srwatson	            g_xge_hal_driver->uld_callbacks.xpak_alarm_log(
1622173139Srwatson	                hldev->upper_layer_info,
1623173139Srwatson	                XGE_HAL_XPAK_ALARM_EXCESS_BIAS_CURRENT);
1624173139Srwatson	        }
1625173139Srwatson	        break;
1626173139Srwatson	    case 3:
1627173139Srwatson	        hldev->stats.sw_dev_err_stats.xpak_counter.
1628173139Srwatson	            excess_laser_output = 0;
1629171095Ssam
1630173139Srwatson	        /*
1631173139Srwatson	         * Notify the ULD on Excess Xpak Laser o/p power
1632173139Srwatson	         * alarm msg
1633173139Srwatson	         */
1634173139Srwatson	        if (g_xge_hal_driver->uld_callbacks.xpak_alarm_log) {
1635173139Srwatson	            g_xge_hal_driver->uld_callbacks.xpak_alarm_log(
1636173139Srwatson	                hldev->upper_layer_info,
1637173139Srwatson	                XGE_HAL_XPAK_ALARM_EXCESS_LASER_OUTPUT);
1638173139Srwatson	        }
1639173139Srwatson	        break;
1640173139Srwatson	    default:
1641173139Srwatson	        xge_debug_osdep(XGE_TRACE, "Incorrect XPAK Alarm "
1642173139Srwatson	        "type ");
1643173139Srwatson	    }
1644171095Ssam	}
1645171095Ssam
1646171095Ssam}
1647171095Ssam
1648171095Ssam/**
1649171095Ssam * __hal_updt_stats_xpak -  update the Xpak error count.
1650171095Ssam * @hldev: pointer to xge_hal_device_t structure
1651171095Ssam *
1652171095Ssam * It is used to update the xpak stats value
1653171095Ssam * Return value:
1654171095Ssam * None
1655171095Ssam */
1656171095Ssamvoid __hal_updt_stats_xpak(xge_hal_device_t *hldev)
1657171095Ssam{
1658171095Ssam	u16 val_1;
1659171095Ssam	u64 addr;
1660171095Ssam
1661171095Ssam	/* Check the communication with the MDIO slave */
1662171095Ssam	addr = 0x0000;
1663171095Ssam	val_1 = 0x0;
1664171095Ssam	val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
1665171095Ssam	if((val_1 == 0xFFFF) || (val_1 == 0x0000))
1666173139Srwatson	    {
1667173139Srwatson	            xge_debug_osdep(XGE_TRACE, "ERR: MDIO slave access failed - "
1668173139Srwatson	                      "Returned %x", val_1);
1669173139Srwatson	            return;
1670173139Srwatson	    }
1671171095Ssam
1672171095Ssam	/* Check for the expected value of 2040 at PMA address 0x0000 */
1673171095Ssam	if(val_1 != 0x2040)
1674173139Srwatson	    {
1675173139Srwatson	            xge_debug_osdep(XGE_TRACE, "Incorrect value at PMA address 0x0000 - ");
1676173139Srwatson	            xge_debug_osdep(XGE_TRACE, "Returned: %llx- Expected: 0x2040",
1677173139Srwatson	            (unsigned long long)(unsigned long)val_1);
1678173139Srwatson	            return;
1679173139Srwatson	    }
1680171095Ssam
1681171095Ssam	/* Loading the DOM register to MDIO register */
1682173139Srwatson	    addr = 0xA100;
1683173139Srwatson	    (void) xge_hal_mdio_write(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr, 0x0);
1684173139Srwatson	    val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
1685171095Ssam
1686171095Ssam	/*
1687171095Ssam	 * Reading the Alarm flags
1688171095Ssam	 */
1689173139Srwatson	    addr = 0xA070;
1690173139Srwatson	    val_1 = 0x0;
1691173139Srwatson	    val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
1692171095Ssam	if(CHECKBIT(val_1, 0x7))
1693171095Ssam	{
1694173139Srwatson	    hldev->stats.sw_dev_err_stats.stats_xpak.
1695173139Srwatson	        alarm_transceiver_temp_high++;
1696173139Srwatson	    hldev->stats.sw_dev_err_stats.xpak_counter.excess_temp++;
1697173139Srwatson	    __hal_chk_xpak_counter(hldev, 0x1,
1698173139Srwatson	        hldev->stats.sw_dev_err_stats.xpak_counter.excess_temp);
1699171095Ssam	} else {
1700173139Srwatson	    hldev->stats.sw_dev_err_stats.xpak_counter.excess_temp = 0;
1701171095Ssam	}
1702171095Ssam	if(CHECKBIT(val_1, 0x6))
1703173139Srwatson	    hldev->stats.sw_dev_err_stats.stats_xpak.
1704173139Srwatson	        alarm_transceiver_temp_low++;
1705171095Ssam
1706171095Ssam	if(CHECKBIT(val_1, 0x3))
1707171095Ssam	{
1708173139Srwatson	    hldev->stats.sw_dev_err_stats.stats_xpak.
1709173139Srwatson	        alarm_laser_bias_current_high++;
1710173139Srwatson	    hldev->stats.sw_dev_err_stats.xpak_counter.
1711173139Srwatson	        excess_bias_current++;
1712173139Srwatson	    __hal_chk_xpak_counter(hldev, 0x2,
1713173139Srwatson	        hldev->stats.sw_dev_err_stats.xpak_counter.
1714173139Srwatson	        excess_bias_current);
1715171095Ssam	} else {
1716173139Srwatson	    hldev->stats.sw_dev_err_stats.xpak_counter.
1717173139Srwatson	        excess_bias_current = 0;
1718171095Ssam	}
1719171095Ssam	if(CHECKBIT(val_1, 0x2))
1720173139Srwatson	    hldev->stats.sw_dev_err_stats.stats_xpak.
1721173139Srwatson	        alarm_laser_bias_current_low++;
1722171095Ssam
1723171095Ssam	if(CHECKBIT(val_1, 0x1))
1724171095Ssam	{
1725173139Srwatson	    hldev->stats.sw_dev_err_stats.stats_xpak.
1726173139Srwatson	        alarm_laser_output_power_high++;
1727173139Srwatson	    hldev->stats.sw_dev_err_stats.xpak_counter.
1728173139Srwatson	        excess_laser_output++;
1729173139Srwatson	    __hal_chk_xpak_counter(hldev, 0x3,
1730173139Srwatson	        hldev->stats.sw_dev_err_stats.xpak_counter.
1731173139Srwatson	            excess_laser_output);
1732171095Ssam	} else {
1733173139Srwatson	    hldev->stats.sw_dev_err_stats.xpak_counter.
1734173139Srwatson	            excess_laser_output = 0;
1735171095Ssam	}
1736171095Ssam	if(CHECKBIT(val_1, 0x0))
1737173139Srwatson	    hldev->stats.sw_dev_err_stats.stats_xpak.
1738173139Srwatson	            alarm_laser_output_power_low++;
1739171095Ssam
1740171095Ssam	/*
1741171095Ssam	 * Reading the warning flags
1742171095Ssam	 */
1743173139Srwatson	    addr = 0xA074;
1744173139Srwatson	    val_1 = 0x0;
1745173139Srwatson	    val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
1746171095Ssam	if(CHECKBIT(val_1, 0x7))
1747173139Srwatson	    hldev->stats.sw_dev_err_stats.stats_xpak.
1748173139Srwatson	        warn_transceiver_temp_high++;
1749171095Ssam	if(CHECKBIT(val_1, 0x6))
1750173139Srwatson	    hldev->stats.sw_dev_err_stats.stats_xpak.
1751173139Srwatson	        warn_transceiver_temp_low++;
1752171095Ssam	if(CHECKBIT(val_1, 0x3))
1753173139Srwatson	    hldev->stats.sw_dev_err_stats.stats_xpak.
1754173139Srwatson	        warn_laser_bias_current_high++;
1755171095Ssam	if(CHECKBIT(val_1, 0x2))
1756173139Srwatson	    hldev->stats.sw_dev_err_stats.stats_xpak.
1757173139Srwatson	        warn_laser_bias_current_low++;
1758171095Ssam	if(CHECKBIT(val_1, 0x1))
1759173139Srwatson	    hldev->stats.sw_dev_err_stats.stats_xpak.
1760173139Srwatson	        warn_laser_output_power_high++;
1761171095Ssam	if(CHECKBIT(val_1, 0x0))
1762173139Srwatson	    hldev->stats.sw_dev_err_stats.stats_xpak.
1763173139Srwatson	        warn_laser_output_power_low++;
1764171095Ssam}
1765