xref: /illumos-gate/usr/src/uts/common/io/xge/hal/xgehal/xgehal-mgmt.c (revision e00bdde3c6d406f40f53f3025defadc22f7ec31a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  *
21  * Copyright (c) 2002-2006 Neterion, Inc.
22  */
23 
24 #include "xgehal-mgmt.h"
25 #include "xgehal-driver.h"
26 #include "xgehal-device.h"
27 
28 /**
29  * xge_hal_mgmt_about - Retrieve about info.
30  * @devh: HAL device handle.
31  * @about_info: Filled in by HAL. See xge_hal_mgmt_about_info_t{}.
32  * @size: Size of the @about_info buffer. HAL will return error if the
33  *        size is smaller than sizeof(xge_hal_mgmt_about_info_t).
34  *
35  * Retrieve information such as PCI device and vendor IDs, board
36  * revision number, HAL version number, etc.
37  *
38  * Returns: XGE_HAL_OK - success;
39  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
40  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
41  * XGE_HAL_FAIL - Failed to retrieve the information.
42  *
43  * See also: xge_hal_mgmt_about_info_t{}.
44  */
45 xge_hal_status_e
46 xge_hal_mgmt_about(xge_hal_device_h devh, xge_hal_mgmt_about_info_t *about_info,
47 		int size)
48 {
49 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
50 
51 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
52 		return XGE_HAL_ERR_INVALID_DEVICE;
53 	}
54 
55 	if (size != sizeof(xge_hal_mgmt_about_info_t)) {
56 		return XGE_HAL_ERR_VERSION_CONFLICT;
57 	}
58 
59 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
60 		xge_offsetof(xge_hal_pci_config_le_t, vendor_id),
61 		&about_info->vendor);
62 
63 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
64 		xge_offsetof(xge_hal_pci_config_le_t, device_id),
65 		&about_info->device);
66 
67 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
68 		xge_offsetof(xge_hal_pci_config_le_t, subsystem_vendor_id),
69 		&about_info->subsys_vendor);
70 
71 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
72 		xge_offsetof(xge_hal_pci_config_le_t, subsystem_id),
73 		&about_info->subsys_device);
74 
75 	xge_os_pci_read8(hldev->pdev, hldev->cfgh,
76 		xge_offsetof(xge_hal_pci_config_le_t, revision),
77 		&about_info->board_rev);
78 
79 	xge_os_strlcpy(about_info->vendor_name, XGE_DRIVER_VENDOR,
80 	    sizeof(about_info->vendor_name));
81 
82 	xge_os_strlcpy(about_info->chip_name, XGE_CHIP_FAMILY,
83 	    sizeof(about_info->chip_name));
84 
85 	xge_os_strlcpy(about_info->media, XGE_SUPPORTED_MEDIA_0,
86 	    sizeof(about_info->media));
87 
88 	xge_os_strlcpy(about_info->hal_major, XGE_HAL_VERSION_MAJOR,
89 	    sizeof(about_info->hal_major));
90 
91 	xge_os_strlcpy(about_info->hal_minor, XGE_HAL_VERSION_MINOR,
92 	    sizeof(about_info->hal_minor));
93 
94 	xge_os_strlcpy(about_info->hal_fix,   XGE_HAL_VERSION_FIX,
95 	    sizeof(about_info->hal_fix));
96 
97 	xge_os_strlcpy(about_info->hal_build, XGE_HAL_VERSION_BUILD,
98 	    sizeof(about_info->hal_build));
99 
100 	xge_os_strlcpy(about_info->ll_major, XGELL_VERSION_MAJOR,
101 	    sizeof(about_info->ll_major));
102 
103 	xge_os_strlcpy(about_info->ll_minor, XGELL_VERSION_MINOR,
104 	    sizeof(about_info->ll_minor));
105 
106 	xge_os_strlcpy(about_info->ll_fix,   XGELL_VERSION_FIX,
107 	    sizeof(about_info->ll_fix));
108 
109 	xge_os_strlcpy(about_info->ll_build, XGELL_VERSION_BUILD,
110 	    sizeof(about_info->ll_build));
111 
112 	about_info->transponder_temperature =
113 		xge_hal_read_xfp_current_temp(devh);
114 
115 	return XGE_HAL_OK;
116 }
117 
118 /**
119  * xge_hal_mgmt_reg_read - Read Xframe register.
120  * @devh: HAL device handle.
121  * @bar_id: 0 - for BAR0, 1- for BAR1.
122  * @offset: Register offset in the Base Address Register (BAR) space.
123  * @value: Register value. Returned by HAL.
124  * Read Xframe register.
125  *
126  * Returns: XGE_HAL_OK - success.
127  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
128  * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
129  * valid.
130  * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
131  *
132  * See also: xge_hal_aux_bar0_read(), xge_hal_aux_bar1_read().
133  */
134 xge_hal_status_e
135 xge_hal_mgmt_reg_read(xge_hal_device_h devh, int bar_id, unsigned int offset,
136 		u64 *value)
137 {
138 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
139 
140 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
141 		return XGE_HAL_ERR_INVALID_DEVICE;
142 	}
143 
144 	if (bar_id == 0) {
145 		if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
146 			return XGE_HAL_ERR_INVALID_OFFSET;
147 		}
148 		*value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
149 					     (void *)(hldev->bar0 + offset));
150 	} else if (bar_id == 1 &&
151 		   (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA ||
152 		    xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC))  {
153 		int i;
154 		for (i=0; i<XGE_HAL_MAX_FIFO_NUM_HERC; i++) {
155 			if (offset == i*0x2000 || offset == i*0x2000+0x18) {
156 				break;
157 			}
158 		}
159 		if (i == XGE_HAL_MAX_FIFO_NUM_HERC) {
160 			return XGE_HAL_ERR_INVALID_OFFSET;
161 		}
162 		*value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh1,
163 					     (void *)(hldev->bar1 + offset));
164 	} else if (bar_id == 1) {
165 		/* FIXME: check TITAN BAR1 offsets */
166 		return XGE_HAL_ERR_INVALID_DEVICE;
167 	} else {
168 		return XGE_HAL_ERR_INVALID_BAR_ID;
169 	}
170 
171 	return XGE_HAL_OK;
172 }
173 
174 /**
175  * xge_hal_mgmt_reg_write - Write Xframe register.
176  * @devh: HAL device handle.
177  * @bar_id: 0 - for BAR0, 1- for BAR1.
178  * @offset: Register offset in the Base Address Register (BAR) space.
179  * @value: Register value.
180  *
181  * Write Xframe register.
182  *
183  * Returns: XGE_HAL_OK - success.
184  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
185  * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
186  * valid.
187  * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
188  *
189  * See also: xge_hal_aux_bar0_write().
190  */
191 xge_hal_status_e
192 xge_hal_mgmt_reg_write(xge_hal_device_h devh, int bar_id, unsigned int offset,
193 		u64 value)
194 {
195 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
196 
197 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
198 		return XGE_HAL_ERR_INVALID_DEVICE;
199 	}
200 
201 	if (bar_id == 0) {
202 		if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
203 			return XGE_HAL_ERR_INVALID_OFFSET;
204 		}
205 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, value,
206 				     (void *)(hldev->bar0 + offset));
207 	} else if (bar_id == 1 &&
208 		   (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA ||
209 		    xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC))  {
210 		int i;
211 		for (i=0; i<XGE_HAL_MAX_FIFO_NUM_HERC; i++) {
212 			if (offset == i*0x2000 || offset == i*0x2000+0x18) {
213 				break;
214 			}
215 		}
216 		if (i == XGE_HAL_MAX_FIFO_NUM_HERC) {
217 			return XGE_HAL_ERR_INVALID_OFFSET;
218 		}
219 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh1, value,
220 				     (void *)(hldev->bar1 + offset));
221 	} else if (bar_id == 1) {
222 		/* FIXME: check TITAN BAR1 offsets */
223 		return XGE_HAL_ERR_INVALID_DEVICE;
224 	} else {
225 		return XGE_HAL_ERR_INVALID_BAR_ID;
226 	}
227 
228 	return XGE_HAL_OK;
229 }
230 
231 /**
232  * xge_hal_mgmt_hw_stats - Get Xframe hardware statistics.
233  * @devh: HAL device handle.
234  * @hw_stats: Hardware statistics. Returned by HAL.
235  *            See xge_hal_stats_hw_info_t{}.
236  * @size: Size of the @hw_stats buffer. HAL will return an error
237  * if the size is smaller than sizeof(xge_hal_stats_hw_info_t).
238  * Get Xframe hardware statistics.
239  *
240  * Returns: XGE_HAL_OK - success.
241  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
242  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
243  *
244  * See also: xge_hal_mgmt_sw_stats().
245  */
246 xge_hal_status_e
247 xge_hal_mgmt_hw_stats(xge_hal_device_h devh, xge_hal_mgmt_hw_stats_t *hw_stats,
248 		int size)
249 {
250 	xge_hal_status_e status;
251 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
252 	xge_hal_stats_hw_info_t	*hw_info;
253 
254 	xge_assert(xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN);
255 
256 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
257 		return XGE_HAL_ERR_INVALID_DEVICE;
258 	}
259 
260 	if (size != sizeof(xge_hal_stats_hw_info_t)) {
261 		return XGE_HAL_ERR_VERSION_CONFLICT;
262 	}
263 
264 	if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
265 		return status;
266 	}
267 
268 	xge_os_memcpy(hw_stats, hw_info, sizeof(xge_hal_stats_hw_info_t));
269 
270 	return XGE_HAL_OK;
271 }
272 
273 /**
274  * xge_hal_mgmt_hw_stats_off - TBD.
275  * @devh: HAL device handle.
276  * @off: TBD
277  * @size: TBD
278  * @out: TBD
279  *
280  * Returns: XGE_HAL_OK - success.
281  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
282  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
283  *
284  * See also: xge_hal_mgmt_sw_stats().
285  */
286 xge_hal_status_e
287 xge_hal_mgmt_hw_stats_off(xge_hal_device_h devh, int off, int size, char *out)
288 {
289 	xge_hal_status_e status;
290 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
291 	xge_hal_stats_hw_info_t	*hw_info;
292 
293 	xge_assert(xge_hal_device_check_id(hldev) != XGE_HAL_CARD_TITAN);
294 
295 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
296 		return XGE_HAL_ERR_INVALID_DEVICE;
297 	}
298 
299 	if (off > sizeof(xge_hal_stats_hw_info_t)-4 ||
300 	    size > 8) {
301 		return XGE_HAL_ERR_INVALID_OFFSET;
302 	}
303 
304 	if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
305 		return status;
306 	}
307 
308 	xge_os_memcpy(out, (char*)hw_info + off, size);
309 
310 	return XGE_HAL_OK;
311 }
312 
313 /**
314  * xge_hal_mgmt_pcim_stats - Get Titan hardware statistics.
315  * @devh: HAL device handle.
316  * @pcim_stats: PCIM statistics. Returned by HAL.
317  *            See xge_hal_stats_hw_info_t{}.
318  * @size: Size of the @hw_stats buffer. HAL will return an error
319  * if the size is smaller than sizeof(xge_hal_stats_hw_info_t).
320  * Get Xframe hardware statistics.
321  *
322  * Returns: XGE_HAL_OK - success.
323  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
324  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
325  *
326  * See also: xge_hal_mgmt_sw_stats().
327  */
328 xge_hal_status_e
329 xge_hal_mgmt_pcim_stats(xge_hal_device_h devh,
330 		xge_hal_mgmt_pcim_stats_t *pcim_stats, int size)
331 {
332 	xge_hal_status_e status;
333 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
334 	xge_hal_stats_pcim_info_t	*pcim_info;
335 
336 	xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN);
337 
338 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
339 		return XGE_HAL_ERR_INVALID_DEVICE;
340 	}
341 
342 	if (size != sizeof(xge_hal_stats_pcim_info_t)) {
343 		return XGE_HAL_ERR_VERSION_CONFLICT;
344 	}
345 
346 	if ((status = xge_hal_stats_pcim (devh, &pcim_info)) != XGE_HAL_OK) {
347 		return status;
348 	}
349 
350 	xge_os_memcpy(pcim_stats, pcim_info,
351 		sizeof(xge_hal_stats_pcim_info_t));
352 
353 	return XGE_HAL_OK;
354 }
355 
356 /**
357  * xge_hal_mgmt_pcim_stats_off - TBD.
358  * @devh: HAL device handle.
359  * @off: TBD
360  * @size: TBD
361  * @out: TBD
362  *
363  * Returns: XGE_HAL_OK - success.
364  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
365  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
366  *
367  * See also: xge_hal_mgmt_sw_stats().
368  */
369 xge_hal_status_e
370 xge_hal_mgmt_pcim_stats_off(xge_hal_device_h devh, int off, int size,
371 			    char *out)
372 {
373 	xge_hal_status_e status;
374 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
375 	xge_hal_stats_pcim_info_t	*pcim_info;
376 
377 	xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_TITAN);
378 
379 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
380 		return XGE_HAL_ERR_INVALID_DEVICE;
381 	}
382 
383 	if (off > sizeof(xge_hal_stats_pcim_info_t)-8 ||
384 	    size > 8) {
385 		return XGE_HAL_ERR_INVALID_OFFSET;
386 	}
387 
388 	if ((status = xge_hal_stats_pcim (devh, &pcim_info)) != XGE_HAL_OK) {
389 		return status;
390 	}
391 
392 	xge_os_memcpy(out, (char*)pcim_info + off, size);
393 
394 	return XGE_HAL_OK;
395 }
396 
397 /**
398  * xge_hal_mgmt_sw_stats - Get per-device software statistics.
399  * @devh: HAL device handle.
400  * @sw_stats: Hardware statistics. Returned by HAL.
401  *            See xge_hal_stats_sw_err_t{}.
402  * @size: Size of the @sw_stats buffer. HAL will return an error
403  * if the size is smaller than sizeof(xge_hal_stats_sw_err_t).
404  * Get device software statistics, including ECC and Parity error
405  * counters, etc.
406  *
407  * Returns: XGE_HAL_OK - success.
408  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
409  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
410  *
411  * See also: xge_hal_stats_sw_err_t{}, xge_hal_mgmt_hw_stats().
412  */
413 xge_hal_status_e
414 xge_hal_mgmt_sw_stats(xge_hal_device_h devh, xge_hal_mgmt_sw_stats_t *sw_stats,
415 		int size)
416 {
417 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
418 
419 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
420 		return XGE_HAL_ERR_INVALID_DEVICE;
421 	}
422 
423 	if (size != sizeof(xge_hal_stats_sw_err_t)) {
424 		return XGE_HAL_ERR_VERSION_CONFLICT;
425 	}
426 
427 	if (!hldev->stats.is_initialized ||
428 	    !hldev->stats.is_enabled) {
429 		return XGE_HAL_INF_STATS_IS_NOT_READY;
430 	}
431 
432 	/* Updating xpak stats value */
433 	__hal_updt_stats_xpak(hldev);
434 
435 	xge_os_memcpy(sw_stats, &hldev->stats.sw_dev_err_stats,
436 	            sizeof(xge_hal_stats_sw_err_t));
437 
438 	return XGE_HAL_OK;
439 }
440 
441 /**
442  * xge_hal_mgmt_device_stats - Get HAL device statistics.
443  * @devh: HAL device handle.
444  * @device_stats: HAL device "soft" statistics. Maintained by HAL itself.
445  *            (as opposed to xge_hal_mgmt_hw_stats() - those are
446  *            maintained by the Xframe hardware).
447  *            Returned by HAL.
448  *            See xge_hal_stats_device_info_t{}.
449  * @size: Size of the @device_stats buffer. HAL will return an error
450  * if the size is smaller than sizeof(xge_hal_stats_device_info_t).
451  *
452  * Get HAL (layer) statistic counters.
453  * Returns: XGE_HAL_OK - success.
454  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
455  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
456  * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
457  * currently available.
458  *
459  */
460 xge_hal_status_e
461 xge_hal_mgmt_device_stats(xge_hal_device_h devh,
462 		xge_hal_mgmt_device_stats_t *device_stats, int size)
463 {
464 	xge_hal_status_e status;
465 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
466 	xge_hal_stats_device_info_t *device_info;
467 
468 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
469 		return XGE_HAL_ERR_INVALID_DEVICE;
470 	}
471 
472 	if (size != sizeof(xge_hal_stats_device_info_t)) {
473 		return XGE_HAL_ERR_VERSION_CONFLICT;
474 	}
475 
476 	if ((status = xge_hal_stats_device (devh, &device_info)) !=
477 	XGE_HAL_OK) {
478 		return status;
479 	}
480 
481 	xge_os_memcpy(device_stats, device_info,
482 		    sizeof(xge_hal_stats_device_info_t));
483 
484 	return XGE_HAL_OK;
485 }
486 
487 /*
488  * __hal_update_ring_bump - Update the ring bump counter for the
489  * particular channel.
490  * @hldev: HAL device handle.
491  * @queue: the queue who's data is to be collected.
492  * @chinfo: pointer to the statistics structure of the given channel.
493  * Usage: See xge_hal_aux_stats_hal_read{}
494  */
495 
496 static void
497 __hal_update_ring_bump(xge_hal_device_t *hldev, int queue,
498 	xge_hal_stats_channel_info_t *chinfo)
499 {
500 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
501 	u64 rbc = 0;
502 	int reg = (queue / 4);
503 	void * addr;
504 
505 	addr = (reg == 1)? (&bar0->ring_bump_counter2) :
506 		(&bar0->ring_bump_counter1);
507 	rbc = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, addr);
508 	chinfo->ring_bump_cnt = XGE_HAL_RING_BUMP_CNT(queue, rbc);
509 }
510 
511 /**
512  * xge_hal_mgmt_channel_stats - Get HAL channel statistics.
513  * @channelh: HAL channel handle.
514  * @channel_stats: HAL channel statistics. Maintained by HAL itself
515  *            (as opposed to xge_hal_mgmt_hw_stats() - those are
516  *            maintained by the Xframe hardware).
517  *            Returned by HAL.
518  *            See xge_hal_stats_channel_info_t{}.
519  * @size: Size of the @channel_stats buffer. HAL will return an error
520  * if the size is smaller than sizeof(xge_hal_mgmt_channel_stats_t).
521  *
522  * Get HAL per-channel statistic counters.
523  *
524  * Returns: XGE_HAL_OK - success.
525  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
526  * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
527  * currently available.
528  *
529  */
530 xge_hal_status_e
531 xge_hal_mgmt_channel_stats(xge_hal_channel_h channelh,
532 		xge_hal_mgmt_channel_stats_t *channel_stats, int size)
533 {
534 	xge_hal_status_e status;
535 	xge_hal_stats_channel_info_t *channel_info;
536 	xge_hal_channel_t *channel = (xge_hal_channel_t* ) channelh;
537 
538 	if (size != sizeof(xge_hal_stats_channel_info_t)) {
539 		return XGE_HAL_ERR_VERSION_CONFLICT;
540 	}
541 
542 	if ((status = xge_hal_stats_channel (channelh, &channel_info)) !=
543 								XGE_HAL_OK) {
544 		return status;
545 	}
546 
547 	if (xge_hal_device_check_id(channel->devh) == XGE_HAL_CARD_HERC) {
548         __hal_update_ring_bump( (xge_hal_device_t *) channel->devh, channel->post_qid, channel_info);
549 	}
550 
551 	xge_os_memcpy(channel_stats, channel_info,
552 		    sizeof(xge_hal_stats_channel_info_t));
553 
554 	return XGE_HAL_OK;
555 }
556 
557 /**
558  * xge_hal_mgmt_pcireg_read - Read PCI configuration at a specified
559  * offset.
560  * @devh: HAL device handle.
561  * @offset: Offset in the 256 byte PCI configuration space.
562  * @value_bits: 8, 16, or 32 (bits) to read.
563  * @value: Value returned by HAL.
564  *
565  * Read PCI configuration, given device and offset in the PCI space.
566  *
567  * Returns: XGE_HAL_OK - success.
568  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
569  * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
570  * valid.
571  * XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE - Invalid bits size. Valid
572  * values(8/16/32).
573  *
574  */
575 xge_hal_status_e
576 xge_hal_mgmt_pcireg_read(xge_hal_device_h devh, unsigned int offset,
577 		int value_bits, u32 *value)
578 {
579 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
580 
581 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
582 		return XGE_HAL_ERR_INVALID_DEVICE;
583 	}
584 
585 	if (offset > sizeof(xge_hal_pci_config_t)-value_bits/8) {
586 		return XGE_HAL_ERR_INVALID_OFFSET;
587 	}
588 
589 	if (value_bits == 8) {
590 		xge_os_pci_read8(hldev->pdev, hldev->cfgh, offset, (u8*)value);
591 	} else if (value_bits == 16) {
592 		xge_os_pci_read16(hldev->pdev, hldev->cfgh, offset,
593 		(u16*)value);
594 	} else if (value_bits == 32) {
595 		xge_os_pci_read32(hldev->pdev, hldev->cfgh, offset, value);
596 	} else {
597 		return XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE;
598 	}
599 
600 	return XGE_HAL_OK;
601 }
602 
603 /**
604  * xge_hal_mgmt_device_config - Retrieve device configuration.
605  * @devh: HAL device handle.
606  * @dev_config: Device configuration, see xge_hal_device_config_t{}.
607  * @size: Size of the @dev_config buffer. HAL will return an error
608  * if the size is smaller than sizeof(xge_hal_mgmt_device_config_t).
609  *
610  * Get device configuration. Permits to retrieve at run-time configuration
611  * values that were used to initialize and configure the device.
612  *
613  * Returns: XGE_HAL_OK - success.
614  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
615  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
616  *
617  * See also: xge_hal_device_config_t{}, xge_hal_mgmt_driver_config().
618  */
619 xge_hal_status_e
620 xge_hal_mgmt_device_config(xge_hal_device_h devh,
621 		xge_hal_mgmt_device_config_t	*dev_config, int size)
622 {
623 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
624 
625 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
626 		return XGE_HAL_ERR_INVALID_DEVICE;
627 	}
628 
629 	if (size != sizeof(xge_hal_mgmt_device_config_t)) {
630 		return XGE_HAL_ERR_VERSION_CONFLICT;
631 	}
632 
633 	xge_os_memcpy(dev_config, &hldev->config,
634 	sizeof(xge_hal_device_config_t));
635 
636 	return XGE_HAL_OK;
637 }
638 
639 /**
640  * xge_hal_mgmt_driver_config - Retrieve driver configuration.
641  * @drv_config: Device configuration, see xge_hal_driver_config_t{}.
642  * @size: Size of the @dev_config buffer. HAL will return an error
643  * if the size is smaller than sizeof(xge_hal_mgmt_driver_config_t).
644  *
645  * Get driver configuration. Permits to retrieve at run-time configuration
646  * values that were used to configure the device at load-time.
647  *
648  * Returns: XGE_HAL_OK - success.
649  * XGE_HAL_ERR_DRIVER_NOT_INITIALIZED - HAL is not initialized.
650  * XGE_HAL_ERR_VERSION_CONFLICT - Version is not maching.
651  *
652  * See also: xge_hal_driver_config_t{}, xge_hal_mgmt_device_config().
653  */
654 xge_hal_status_e
655 xge_hal_mgmt_driver_config(xge_hal_mgmt_driver_config_t *drv_config, int size)
656 {
657 
658 	if (g_xge_hal_driver == NULL) {
659 		return XGE_HAL_ERR_DRIVER_NOT_INITIALIZED;
660 	}
661 
662 	if (size != sizeof(xge_hal_mgmt_driver_config_t)) {
663 		return XGE_HAL_ERR_VERSION_CONFLICT;
664 	}
665 
666 	xge_os_memcpy(drv_config, &g_xge_hal_driver->config,
667 		    sizeof(xge_hal_mgmt_driver_config_t));
668 
669 	return XGE_HAL_OK;
670 }
671 
672 /**
673  * xge_hal_mgmt_pci_config - Retrieve PCI configuration.
674  * @devh: HAL device handle.
675  * @pci_config: 256 byte long buffer for PCI configuration space.
676  * @size: Size of the @ buffer. HAL will return an error
677  * if the size is smaller than sizeof(xge_hal_mgmt_pci_config_t).
678  *
679  * Get PCI configuration. Permits to retrieve at run-time configuration
680  * values that were used to configure the device at load-time.
681  *
682  * Returns: XGE_HAL_OK - success.
683  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
684  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
685  *
686  */
687 xge_hal_status_e
688 xge_hal_mgmt_pci_config(xge_hal_device_h devh,
689 		xge_hal_mgmt_pci_config_t *pci_config, int size)
690 {
691 	int i;
692 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
693 
694 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
695 		return XGE_HAL_ERR_INVALID_DEVICE;
696 	}
697 
698 	if (size != sizeof(xge_hal_mgmt_pci_config_t)) {
699 		return XGE_HAL_ERR_VERSION_CONFLICT;
700 	}
701 
702 	/* refresh PCI config space */
703 	for (i = 0; i < 0x68/4+1; i++) {
704 		xge_os_pci_read32(hldev->pdev, hldev->cfgh, i*4,
705 		                (u32*)&hldev->pci_config_space + i);
706 	}
707 
708 	xge_os_memcpy(pci_config, &hldev->pci_config_space,
709 		    sizeof(xge_hal_mgmt_pci_config_t));
710 
711 	return XGE_HAL_OK;
712 }
713 
714 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
715 /**
716  * xge_hal_mgmt_trace_read - Read trace buffer contents.
717  * @buffer: Buffer to store the trace buffer contents.
718  * @buf_size: Size of the buffer.
719  * @offset: Offset in the internal trace buffer to read data.
720  * @read_length: Size of the valid data in the buffer.
721  *
722  * Read  HAL trace buffer contents starting from the offset
723  * upto the size of the buffer or till EOF is reached.
724  *
725  * Returns: XGE_HAL_OK - success.
726  * XGE_HAL_EOF_TRACE_BUF - No more data in the trace buffer.
727  *
728  */
729 xge_hal_status_e
730 xge_hal_mgmt_trace_read (char		*buffer,
731 			unsigned	buf_size,
732 			unsigned	*offset,
733 			unsigned	*read_length)
734 {
735 	int data_offset;
736 	int start_offset;
737 
738 	if ((g_xge_os_tracebuf == NULL) ||
739 		(g_xge_os_tracebuf->offset == g_xge_os_tracebuf->size - 2)) {
740 		return XGE_HAL_EOF_TRACE_BUF;
741 	}
742 
743 	data_offset = g_xge_os_tracebuf->offset + 1;
744 
745 	if  (*offset >= (unsigned)xge_os_strlen(g_xge_os_tracebuf->data +
746 	data_offset)) {
747 
748 		return XGE_HAL_EOF_TRACE_BUF;
749 	}
750 
751 	xge_os_memzero(buffer, buf_size);
752 
753 	start_offset  =  data_offset + *offset;
754 	*read_length = xge_os_strlen(g_xge_os_tracebuf->data +
755 	start_offset);
756 
757 	if (*read_length  >=  buf_size) {
758 		*read_length = buf_size - 1;
759 	}
760 
761 	xge_os_memcpy(buffer, g_xge_os_tracebuf->data + start_offset,
762 	*read_length);
763 
764 	*offset += *read_length;
765 	(*read_length) ++;
766 
767 	return XGE_HAL_OK;
768 }
769 
770 #endif
771 
772 /**
773  * xge_hal_restore_link_led - Restore link LED to its original state.
774  * @devh: HAL device handle.
775  */
776 void
777 xge_hal_restore_link_led(xge_hal_device_h devh)
778 {
779 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
780 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
781 	u64 val64;
782 
783 	/*
784 	 * If the current link state is UP, switch on LED else make it
785 	 * off.
786 	 */
787 
788 	/*
789 	 * For Xena 3 and lower revision cards, adapter control needs to be
790 	 * used for making LED ON/OFF.
791 	 */
792 	if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
793 	   (xge_hal_device_rev(hldev) <= 3)) {
794 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
795 					      &bar0->adapter_control);
796 		if (hldev->link_state == XGE_HAL_LINK_UP) {
797 			val64 |= XGE_HAL_ADAPTER_LED_ON;
798 		} else {
799 			val64 &= ~XGE_HAL_ADAPTER_LED_ON;
800 		}
801 
802 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
803 					&bar0->adapter_control);
804 		return;
805 	}
806 
807 	/*
808 	 * Use beacon control register to control the LED.
809 	 * LED link output corresponds to bit 8 of the beacon control
810 	 * register. Note that, in the case of Xena, beacon control register
811 	 * represents the gpio control register. In the case of Herc, LED
812 	 * handling is done by beacon control register as opposed to gpio
813 	 * control register in Xena. Beacon control is used only to toggle
814      * and the value written into it does not depend on the link state.
815      * It is upto the ULD to toggle the LED even number of times which
816      * brings the LED to it's original state.
817 	 */
818 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
819 				      &bar0->beacon_control);
820     val64 |= 0x0000800000000000ULL;
821     xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
822     		       val64, &bar0->beacon_control);
823 }
824 
825 /**
826  * xge_hal_flick_link_led - Flick (blink) link LED.
827  * @devh: HAL device handle.
828  *
829  * Depending on the card revision flicker the link LED by using the
830  * beacon control or the adapter_control register.
831  */
832 void
833 xge_hal_flick_link_led(xge_hal_device_h devh)
834 {
835 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
836 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
837 	u64 val64 = 0;
838 
839 	/*
840 	 * For Xena 3 and lower revision cards, adapter control needs to be
841 	 * used for making LED ON/OFF.
842 	 */
843 	if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
844 	   (xge_hal_device_rev(hldev) <= 3)) {
845 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
846 					      &bar0->adapter_control);
847 		val64 ^= XGE_HAL_ADAPTER_LED_ON;
848 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
849 					&bar0->adapter_control);
850 		return;
851 	}
852 
853 	/*
854 	 * Use beacon control register to control the Link LED.
855 	 * Note that, in the case of Xena, beacon control register represents
856 	 * the gpio control register. In the case of Herc, LED handling is
857 	 * done by beacon control register as opposed to gpio control register
858 	 * in Xena.
859 	 */
860 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
861 				      &bar0->beacon_control);
862 	val64 ^= XGE_HAL_GPIO_CTRL_GPIO_0;
863 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
864 			       &bar0->beacon_control);
865 }
866 
867 /**
868  * xge_hal_read_eeprom - Read 4 bytes of data from user given offset.
869  * @devh: HAL device handle.
870  * @off: offset at which the data must be written
871  * @data: output parameter where the data is stored.
872  *
873  * Read 4 bytes of data from the user given offset and return the
874  * read data.
875  * Note: will allow to read only part of the EEPROM visible through the
876  * I2C bus.
877  * Returns: -1 on failure, 0 on success.
878  */
879 xge_hal_status_e
880 xge_hal_read_eeprom(xge_hal_device_h devh, int off, u32* data)
881 {
882 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
883 	xge_hal_status_e ret = XGE_HAL_FAIL;
884 	u32 exit_cnt = 0;
885 	u64 val64;
886 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
887 
888 	val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) |
889 		XGE_HAL_I2C_CONTROL_ADDR(off) |
890 		XGE_HAL_I2C_CONTROL_BYTE_CNT(0x3) |
891 		XGE_HAL_I2C_CONTROL_READ | XGE_HAL_I2C_CONTROL_CNTL_START;
892 
893 	__hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
894 
895 	while (exit_cnt < 5) {
896 		val64 = __hal_serial_mem_read64(hldev, &bar0->i2c_control);
897 		if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) {
898 			*data = XGE_HAL_I2C_CONTROL_GET_DATA(val64);
899 			ret = XGE_HAL_OK;
900 			break;
901 		}
902 		exit_cnt++;
903 	}
904 
905 	return ret;
906 }
907 
908 /*
909  * xge_hal_write_eeprom - actually writes the relevant part of the data
910  value.
911  * @devh: HAL device handle.
912  * @off: offset at which the data must be written
913  * @data : The data that is to be written
914  * @cnt : Number of bytes of the data that are actually to be written into
915  * the Eeprom. (max of 3)
916  *
917  * Actually writes the relevant part of the data value into the Eeprom
918  * through the I2C bus.
919  * Return value:
920  * 0 on success, -1 on failure.
921  */
922 
923 xge_hal_status_e
924 xge_hal_write_eeprom(xge_hal_device_h devh, int off, u32 data, int cnt)
925 {
926 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
927 	xge_hal_status_e ret = XGE_HAL_FAIL;
928 	u32 exit_cnt = 0;
929 	u64 val64;
930 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
931 
932 	val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) |
933 		XGE_HAL_I2C_CONTROL_ADDR(off) |
934 		XGE_HAL_I2C_CONTROL_BYTE_CNT(cnt) |
935 		XGE_HAL_I2C_CONTROL_SET_DATA(data) |
936 		XGE_HAL_I2C_CONTROL_CNTL_START;
937 	__hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
938 
939 	while (exit_cnt < 5) {
940 		val64 = __hal_serial_mem_read64(hldev, &bar0->i2c_control);
941 		if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) {
942 			if (!(val64 & XGE_HAL_I2C_CONTROL_NACK))
943 				ret = XGE_HAL_OK;
944 			break;
945 		}
946 		exit_cnt++;
947 	}
948 
949 	return ret;
950 }
951 
952 /*
953  * xge_hal_register_test - reads and writes into all clock domains.
954  * @hldev : private member of the device structure.
955  * xge_nic structure.
956  * @data : variable that returns the result of each of the test conducted b
957  * by the driver.
958  *
959  * Read and write into all clock domains. The NIC has 3 clock domains,
960  * see that registers in all the three regions are accessible.
961  * Return value:
962  * 0 on success.
963  */
964 xge_hal_status_e
965 xge_hal_register_test(xge_hal_device_h devh, u64 *data)
966 {
967 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
968 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
969 	u64 val64 = 0;
970 	int fail = 0;
971 
972 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
973 			&bar0->pif_rd_swapper_fb);
974 	if (val64 != 0x123456789abcdefULL) {
975 		fail = 1;
976 		xge_debug_osdep(XGE_TRACE, "Read Test level 1 fails");
977 	}
978 
979 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
980 			&bar0->rmac_pause_cfg);
981 	if (val64 != 0xc000ffff00000000ULL) {
982 		fail = 1;
983 		xge_debug_osdep(XGE_TRACE, "Read Test level 2 fails");
984 	}
985 
986 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
987 			&bar0->rx_queue_cfg);
988 	if (val64 != 0x0808080808080808ULL) {
989 		fail = 1;
990 		xge_debug_osdep(XGE_TRACE, "Read Test level 3 fails");
991 	}
992 
993 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
994 			&bar0->xgxs_efifo_cfg);
995 	if (val64 != 0x000000001923141EULL) {
996 		fail = 1;
997 		xge_debug_osdep(XGE_TRACE, "Read Test level 4 fails");
998 	}
999 
1000 	val64 = 0x5A5A5A5A5A5A5A5AULL;
1001 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1002 			&bar0->xmsi_data);
1003 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1004 			&bar0->xmsi_data);
1005 	if (val64 != 0x5A5A5A5A5A5A5A5AULL) {
1006 		fail = 1;
1007 		xge_debug_osdep(XGE_ERR, "Write Test level 1 fails");
1008 	}
1009 
1010 	val64 = 0xA5A5A5A5A5A5A5A5ULL;
1011 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1012 			&bar0->xmsi_data);
1013 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1014 			&bar0->xmsi_data);
1015 	if (val64 != 0xA5A5A5A5A5A5A5A5ULL) {
1016 		fail = 1;
1017 		xge_debug_osdep(XGE_ERR, "Write Test level 2 fails");
1018 	}
1019 
1020 	*data = fail;
1021 	return XGE_HAL_OK;
1022 }
1023 
1024 /*
1025  * xge_hal_rldram_test - offline test for access to the RldRam chip on
1026  the NIC
1027  * @devh: HAL device handle.
1028  * @data: variable that returns the result of each of the test
1029  * conducted by the driver.
1030  *
1031  * This is one of the offline test that tests the read and write
1032  * access to the RldRam chip on the NIC.
1033  * Return value:
1034  * 0 on success.
1035  */
1036 xge_hal_status_e
1037 xge_hal_rldram_test(xge_hal_device_h devh, u64 *data)
1038 {
1039 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1040 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1041 	u64 val64;
1042 	int cnt, iteration = 0, test_pass = 0;
1043 
1044 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1045 			&bar0->adapter_control);
1046 	val64 &= ~XGE_HAL_ADAPTER_ECC_EN;
1047 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1048 			&bar0->adapter_control);
1049 
1050 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1051 			&bar0->mc_rldram_test_ctrl);
1052 	val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE;
1053 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1054 			&bar0->mc_rldram_test_ctrl);
1055 
1056 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1057 			&bar0->mc_rldram_mrs);
1058 	val64 |= XGE_HAL_MC_RLDRAM_QUEUE_SIZE_ENABLE;
1059 	__hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
1060 
1061 	val64 |= XGE_HAL_MC_RLDRAM_MRS_ENABLE;
1062 	__hal_serial_mem_write64(hldev, val64, &bar0->i2c_control);
1063 
1064 	while (iteration < 2) {
1065 		val64 = 0x55555555aaaa0000ULL;
1066 		if (iteration == 1) {
1067 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
1068 		}
1069 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1070 			&bar0->mc_rldram_test_d0);
1071 
1072 		val64 = 0xaaaa5a5555550000ULL;
1073 		if (iteration == 1) {
1074 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
1075 		}
1076 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1077 			&bar0->mc_rldram_test_d1);
1078 
1079 		val64 = 0x55aaaaaaaa5a0000ULL;
1080 		if (iteration == 1) {
1081 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
1082 		}
1083 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1084 			&bar0->mc_rldram_test_d2);
1085 
1086 		val64 = (u64) (0x0000003fffff0000ULL);
1087 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1088 			&bar0->mc_rldram_test_add);
1089 
1090 
1091 		val64 = XGE_HAL_MC_RLDRAM_TEST_MODE;
1092 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1093 			&bar0->mc_rldram_test_ctrl);
1094 
1095 		val64 |=
1096 		    XGE_HAL_MC_RLDRAM_TEST_MODE | XGE_HAL_MC_RLDRAM_TEST_WRITE |
1097 		    XGE_HAL_MC_RLDRAM_TEST_GO;
1098 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1099 			&bar0->mc_rldram_test_ctrl);
1100 
1101 		for (cnt = 0; cnt < 5; cnt++) {
1102 			val64 = xge_os_pio_mem_read64(hldev->pdev,
1103 				hldev->regh0, &bar0->mc_rldram_test_ctrl);
1104 			if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE)
1105 				break;
1106 			xge_os_mdelay(200);
1107 		}
1108 
1109 		if (cnt == 5)
1110 			break;
1111 
1112 		val64 = XGE_HAL_MC_RLDRAM_TEST_MODE;
1113 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1114 			&bar0->mc_rldram_test_ctrl);
1115 
1116 		val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE |
1117 		XGE_HAL_MC_RLDRAM_TEST_GO;
1118 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1119 			&bar0->mc_rldram_test_ctrl);
1120 
1121 		for (cnt = 0; cnt < 5; cnt++) {
1122 			val64 = xge_os_pio_mem_read64(hldev->pdev,
1123 				hldev->regh0, &bar0->mc_rldram_test_ctrl);
1124 			if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE)
1125 				break;
1126 			xge_os_mdelay(500);
1127 		}
1128 
1129 		if (cnt == 5)
1130 			break;
1131 
1132 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1133 			&bar0->mc_rldram_test_ctrl);
1134 		if (val64 & XGE_HAL_MC_RLDRAM_TEST_PASS)
1135 			test_pass = 1;
1136 
1137 		iteration++;
1138 	}
1139 
1140 	if (!test_pass)
1141 		*data = 1;
1142 	else
1143 		*data = 0;
1144 
1145 	return XGE_HAL_OK;
1146 }
1147 
1148 /*
1149  * xge_hal_pma_loopback - Enable or disable PMA loopback
1150  * @devh: HAL device handle.
1151  * @enable:Boolean set to 1 to enable and 0 to disable.
1152  *
1153  * Enable or disable PMA loopback.
1154  * Return value:
1155  * 0 on success.
1156  */
1157 xge_hal_status_e
1158 xge_hal_pma_loopback( xge_hal_device_h devh, int enable )
1159 {
1160 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1161 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1162 	u64 val64;
1163 	u16 data;
1164 
1165 	/*
1166 	 * This code if for MAC loopbak
1167 	 * Should be enabled through another parameter
1168 	 */
1169 #if 0
1170 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1171 	&bar0->mac_cfg);
1172     if ( enable )
1173     {
1174         val64 |= ( XGE_HAL_MAC_CFG_TMAC_LOOPBACK | XGE_HAL_MAC_CFG_RMAC_PROM_ENABLE );
1175     }
1176 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
1177 		    (u32)(val64 >> 32), (char*)&bar0->mac_cfg);
1178 	xge_os_mdelay(1);
1179 #endif
1180 
1181 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
1182 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
1183 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1184 		XGE_HAL_MDIO_CONTROL_MMD_CTRL(0)       |
1185 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
1186 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1187 
1188 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1189 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1190 
1191 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
1192 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
1193 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1194 		XGE_HAL_MDIO_CONTROL_MMD_CTRL(0)       |
1195 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_READ);
1196 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1197 
1198 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1199 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1200 
1201 	val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1202 
1203 	data = (u16)XGE_HAL_MDIO_CONTROL_MMD_DATA_GET(val64);
1204 
1205 #define _HAL_LOOPBK_PMA         1
1206 
1207 	if( enable )
1208 		data |= 1;
1209 	else
1210 		data &= 0xfe;
1211 
1212 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
1213 		 XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
1214 		 XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1215 		 XGE_HAL_MDIO_CONTROL_MMD_CTRL(0)       |
1216 		 XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
1217 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1218 
1219 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1220 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1221 
1222 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
1223 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
1224 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1225 		XGE_HAL_MDIO_CONTROL_MMD_DATA(data)    |
1226 		XGE_HAL_MDIO_CONTROL_MMD_CTRL(0x0)     |
1227 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_WRITE);
1228 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1229 
1230 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1231 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1232 
1233 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(0)  |
1234 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(1)   |
1235 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1236 		XGE_HAL_MDIO_CONTROL_MMD_CTRL(0x0)     |
1237 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_READ);
1238 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1239 
1240 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1241 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1242 
1243     return XGE_HAL_OK;
1244 }
1245 
1246 u16
1247 xge_hal_mdio_read( xge_hal_device_h devh, u32 mmd_type, u64 addr )
1248 {
1249 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1250 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1251 	u64 val64 = 0x0;
1252 	u16 rval16 = 0x0;
1253 	u8  i = 0;
1254 
1255 	/* address transaction */
1256 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr)  |
1257 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type)   |
1258 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1259 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
1260 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1261 
1262 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1263 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1264 	do
1265 	{
1266 		val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1267 		if (i++ > 10)
1268 		{
1269 			break;
1270 		}
1271 	}while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) != XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
1272 
1273 	/* Data transaction */
1274 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr)  |
1275 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type)   |
1276 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1277 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_READ);
1278 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1279 
1280 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1281 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1282 
1283 	i = 0;
1284 
1285 	do
1286 	{
1287 		val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1288 		if (i++ > 10)
1289 		{
1290 			break;
1291 		}
1292 	}while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) != XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
1293 
1294 	rval16 = (u16)XGE_HAL_MDIO_CONTROL_MMD_DATA_GET(val64);
1295 
1296 	return rval16;
1297 }
1298 
1299 xge_hal_status_e
1300 xge_hal_mdio_write( xge_hal_device_h devh, u32 mmd_type, u64 addr, u32 value )
1301 {
1302 	u64 val64 = 0x0;
1303 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1304 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1305 	u8  i = 0;
1306 	/* address transaction */
1307 
1308 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr)  |
1309 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type)   |
1310 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)   |
1311 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_ADDRESS);
1312 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1313 
1314 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1315 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1316 
1317 	do
1318 	{
1319 		val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1320 		if (i++ > 10)
1321 		{
1322 			break;
1323 		}
1324 	} while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) !=
1325 		XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
1326 
1327 	/* Data transaction */
1328 
1329 	val64 = 0x0;
1330 
1331 	val64 = XGE_HAL_MDIO_CONTROL_MMD_INDX_ADDR(addr)    |
1332 		XGE_HAL_MDIO_CONTROL_MMD_DEV_ADDR(mmd_type) |
1333 		XGE_HAL_MDIO_CONTROL_MMD_PRT_ADDR(0)        |
1334 		XGE_HAL_MDIO_CONTROL_MMD_DATA(value)        |
1335 		XGE_HAL_MDIO_CONTROL_MMD_OP(XGE_HAL_MDIO_OP_WRITE);
1336 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1337 
1338 	val64 |= XGE_HAL_MDIO_CONTROL_MMD_CTRL(XGE_HAL_MDIO_CTRL_START);
1339 	__hal_serial_mem_write64(hldev, val64, &bar0->mdio_control);
1340 
1341 	i = 0;
1342 
1343 	do
1344 	{
1345 		val64 = __hal_serial_mem_read64(hldev, &bar0->mdio_control);
1346 		if (i++ > 10)
1347 		{
1348 			break;
1349 		}
1350 	}while((val64 & XGE_HAL_MDIO_CONTROL_MMD_CTRL(0xF)) != XGE_HAL_MDIO_CONTROL_MMD_CTRL(1));
1351 
1352 	return XGE_HAL_OK;
1353 }
1354 
1355 /*
1356  * xge_hal_eeprom_test - to verify that EEprom in the xena can be
1357  programmed.
1358  * @devh: HAL device handle.
1359  * @data:variable that returns the result of each of the test conducted by
1360  * the driver.
1361  *
1362  * Verify that EEPROM in the xena can be programmed using I2C_CONTROL
1363  * register.
1364  * Return value:
1365  * 0 on success.
1366  */
1367 xge_hal_status_e
1368 xge_hal_eeprom_test(xge_hal_device_h devh, u64 *data)
1369 {
1370 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1371 	int fail     = 0;
1372 	u32 ret_data = 0;
1373 
1374 	/* Test Write Error at offset 0 */
1375 	if (!xge_hal_write_eeprom(hldev, 0, 0, 3))
1376 		fail = 1;
1377 
1378 	/* Test Write at offset 4f0 */
1379 	if (xge_hal_write_eeprom(hldev, 0x4F0, 0x01234567, 3))
1380 		fail = 1;
1381 	if (xge_hal_read_eeprom(hldev, 0x4F0, &ret_data))
1382 		fail = 1;
1383 
1384 	if (ret_data != 0x01234567)
1385 		fail = 1;
1386 
1387 	/* Reset the EEPROM data go FFFF */
1388 	(void) xge_hal_write_eeprom(hldev, 0x4F0, 0xFFFFFFFF, 3);
1389 
1390 	/* Test Write Request Error at offset 0x7c */
1391 	if (!xge_hal_write_eeprom(hldev, 0x07C, 0, 3))
1392 		fail = 1;
1393 
1394 	/* Test Write Request at offset 0x7fc */
1395 	if (xge_hal_write_eeprom(hldev, 0x7FC, 0x01234567, 3))
1396 		fail = 1;
1397 	if (xge_hal_read_eeprom(hldev, 0x7FC, &ret_data))
1398 		fail = 1;
1399 
1400 	if (ret_data != 0x01234567)
1401 		fail = 1;
1402 
1403 	/* Reset the EEPROM data go FFFF */
1404 	(void) xge_hal_write_eeprom(hldev, 0x7FC, 0xFFFFFFFF, 3);
1405 
1406 	/* Test Write Error at offset 0x80 */
1407 	if (!xge_hal_write_eeprom(hldev, 0x080, 0, 3))
1408 		fail = 1;
1409 
1410 	/* Test Write Error at offset 0xfc */
1411 	if (!xge_hal_write_eeprom(hldev, 0x0FC, 0, 3))
1412 		fail = 1;
1413 
1414 	/* Test Write Error at offset 0x100 */
1415 	if (!xge_hal_write_eeprom(hldev, 0x100, 0, 3))
1416 		fail = 1;
1417 
1418 	/* Test Write Error at offset 4ec */
1419 	if (!xge_hal_write_eeprom(hldev, 0x4EC, 0, 3))
1420 		fail = 1;
1421 
1422 	*data = fail;
1423 	return XGE_HAL_OK;
1424 }
1425 
1426 /*
1427  * xge_hal_bist_test - invokes the MemBist test of the card .
1428  * @devh: HAL device handle.
1429  * xge_nic structure.
1430  * @data:variable that returns the result of each of the test conducted by
1431  * the driver.
1432  *
1433  * This invokes the MemBist test of the card. We give around
1434  * 2 secs time for the Test to complete. If it's still not complete
1435  * within this peiod, we consider that the test failed.
1436  * Return value:
1437  * 0 on success and -1 on failure.
1438  */
1439 xge_hal_status_e
1440 xge_hal_bist_test(xge_hal_device_h devh, u64 *data)
1441 {
1442 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1443 	u8 bist = 0;
1444 	int cnt = 0;
1445 	xge_hal_status_e ret = XGE_HAL_FAIL;
1446 
1447 	xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist);
1448 	bist |= 0x40;
1449 	xge_os_pci_write8(hldev->pdev, hldev->cfgh, 0x0f, bist);
1450 
1451 	while (cnt < 20) {
1452 		xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist);
1453 		if (!(bist & 0x40)) {
1454 			*data = (bist & 0x0f);
1455 			ret = XGE_HAL_OK;
1456 			break;
1457 		}
1458 		xge_os_mdelay(100);
1459 		cnt++;
1460 	}
1461 
1462 	return ret;
1463 }
1464 
1465 /*
1466  * xge_hal_link_test - verifies the link state of the nic
1467  * @devh: HAL device handle.
1468  * @data: variable that returns the result of each of the test conducted by
1469  * the driver.
1470  *
1471  * Verify the link state of the NIC and updates the input
1472  * argument 'data' appropriately.
1473  * Return value:
1474  * 0 on success.
1475  */
1476 xge_hal_status_e
1477 xge_hal_link_test(xge_hal_device_h devh, u64 *data)
1478 {
1479 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1480 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1481 	u64 val64;
1482 
1483 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1484 			&bar0->adapter_status);
1485 	if (val64 & XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)
1486 		*data = 1;
1487 
1488 	return XGE_HAL_OK;
1489 }
1490 
1491 
1492 /**
1493  * xge_hal_getpause_data -Pause frame frame generation and reception.
1494  * @devh: HAL device handle.
1495  * @tx : A field to return the pause generation capability of the NIC.
1496  * @rx : A field to return the pause reception capability of the NIC.
1497  *
1498  * Returns the Pause frame generation and reception capability of the NIC.
1499  * Return value:
1500  *  void
1501  */
1502 void xge_hal_getpause_data(xge_hal_device_h devh, int *tx, int *rx)
1503 {
1504 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1505 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1506 	u64 val64;
1507 
1508 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1509 				&bar0->rmac_pause_cfg);
1510 	if (val64 & XGE_HAL_RMAC_PAUSE_GEN_EN)
1511 		*tx = 1;
1512 	if (val64 & XGE_HAL_RMAC_PAUSE_RCV_EN)
1513 		*rx = 1;
1514 }
1515 
1516 /**
1517  * xge_hal_setpause_data -  set/reset pause frame generation.
1518  * @devh: HAL device handle.
1519  * @tx: A field that indicates the pause generation capability to be
1520  * set on the NIC.
1521  * @rx: A field that indicates the pause reception capability to be
1522  * set on the NIC.
1523  *
1524  * It can be used to set or reset Pause frame generation or reception
1525  * support of the NIC.
1526  * Return value:
1527  * int, returns 0 on Success
1528  */
1529 
1530 int xge_hal_setpause_data(xge_hal_device_h devh, int tx, int rx)
1531 {
1532 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1533 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1534 	u64 val64;
1535 
1536 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1537 				    &bar0->rmac_pause_cfg);
1538 	if (tx)
1539 		val64 |= XGE_HAL_RMAC_PAUSE_GEN_EN;
1540 	else
1541 		val64 &= ~XGE_HAL_RMAC_PAUSE_GEN_EN;
1542 	if (rx)
1543 		val64 |= XGE_HAL_RMAC_PAUSE_RCV_EN;
1544 	else
1545 		val64 &= ~XGE_HAL_RMAC_PAUSE_RCV_EN;
1546 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1547 			     val64, &bar0->rmac_pause_cfg);
1548 	return 0;
1549 }
1550 
1551 /**
1552  * xge_hal_read_xfp_current_temp -
1553  * @hldev: HAL device handle.
1554  *
1555  * This routine only gets the temperature for XFP modules. Also, updating of the
1556  * NVRAM can sometimes fail and so the reading we might get may not be uptodate.
1557  */
1558 u32 xge_hal_read_xfp_current_temp(xge_hal_device_h hldev)
1559 {
1560     u16 val_1, val_2, i = 0;
1561     u32 actual;
1562 
1563     /* First update the NVRAM table of XFP. */
1564 
1565     (void) xge_hal_mdio_write(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8000, 0x3);
1566 
1567 
1568     /* Now wait for the transfer to complete */
1569     do
1570     {
1571         xge_os_mdelay( 50 ); // wait 50 milliseonds
1572 
1573         val_1 =  xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8000);
1574 
1575         if ( i++ > 10 )
1576         {
1577             // waited 500 ms which should be plenty of time.
1578             break;
1579         }
1580     }while (( val_1 & 0x000C ) != 0x0004);
1581 
1582     /* Now NVRAM table of XFP should be updated, so read the temp */
1583     val_1 =  (u8) xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8067);
1584     val_2 =  (u8) xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, 0x8068);
1585 
1586     actual = ((val_1 << 8) | val_2);
1587 
1588     if (actual >= 32768)
1589         actual = actual- 65536;
1590     actual =  actual/256;
1591 
1592     return actual;
1593 }
1594 
1595 /**
1596  * __hal_chk_xpak_counter -  check the Xpak error count and log the msg.
1597  * @hldev: pointer to xge_hal_device_t structure
1598  * @type:  xpak stats error type
1599  * @value: xpak stats value
1600  *
1601  * It is used to log the error message based on the xpak stats value
1602  * Return value:
1603  * None
1604  */
1605 
1606 void __hal_chk_xpak_counter(xge_hal_device_t *hldev, int type, u32 value)
1607 {
1608 	/*
1609 	 * If the value is high for three consecutive cylce,
1610 	 * log a error message
1611 	 */
1612 	if(value == 3)
1613 	{
1614 		switch(type)
1615 		{
1616 		case 1:
1617 			hldev->stats.sw_dev_err_stats.xpak_counter.
1618 				excess_temp = 0;
1619 
1620 			/*
1621 			 * Notify the ULD on Excess Xpak temperature alarm msg
1622 			 */
1623 			if (g_xge_hal_driver->uld_callbacks.xpak_alarm_log) {
1624 				g_xge_hal_driver->uld_callbacks.xpak_alarm_log(
1625 					hldev->upper_layer_info,
1626 					XGE_HAL_XPAK_ALARM_EXCESS_TEMP);
1627 			}
1628 			break;
1629 		case 2:
1630 			hldev->stats.sw_dev_err_stats.xpak_counter.
1631 				excess_bias_current = 0;
1632 
1633 			/*
1634 			 * Notify the ULD on Excess  xpak bias current alarm msg
1635 			 */
1636 			if (g_xge_hal_driver->uld_callbacks.xpak_alarm_log) {
1637 				g_xge_hal_driver->uld_callbacks.xpak_alarm_log(
1638 					hldev->upper_layer_info,
1639 					XGE_HAL_XPAK_ALARM_EXCESS_BIAS_CURRENT);
1640 			}
1641 			break;
1642 		case 3:
1643 			hldev->stats.sw_dev_err_stats.xpak_counter.
1644 				excess_laser_output = 0;
1645 
1646 			/*
1647 			 * Notify the ULD on Excess Xpak Laser o/p power
1648 			 * alarm msg
1649 			 */
1650 			if (g_xge_hal_driver->uld_callbacks.xpak_alarm_log) {
1651 				g_xge_hal_driver->uld_callbacks.xpak_alarm_log(
1652 					hldev->upper_layer_info,
1653 					XGE_HAL_XPAK_ALARM_EXCESS_LASER_OUTPUT);
1654 			}
1655 			break;
1656 		default:
1657 			xge_debug_osdep(XGE_TRACE, "Incorrect XPAK Alarm "
1658 			"type ");
1659 		}
1660 	}
1661 
1662 }
1663 
1664 /**
1665  * __hal_updt_stats_xpak -  update the Xpak error count.
1666  * @hldev: pointer to xge_hal_device_t structure
1667  *
1668  * It is used to update the xpak stats value
1669  * Return value:
1670  * None
1671  */
1672 void __hal_updt_stats_xpak(xge_hal_device_t *hldev)
1673 {
1674 	u16 val_1;
1675 	u64 addr;
1676 
1677 	/* Check the communication with the MDIO slave */
1678 	addr = 0x0000;
1679 	val_1 = 0x0;
1680 	val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
1681 	if((val_1 == 0xFFFF) || (val_1 == 0x0000))
1682         {
1683                 xge_debug_osdep(XGE_TRACE, "ERR: MDIO slave access failed - "
1684                           "Returned %x", val_1);
1685                 return;
1686         }
1687 
1688 	/* Check for the expected value of 2040 at PMA address 0x0000 */
1689 	if(val_1 != 0x2040)
1690         {
1691                 xge_debug_osdep(XGE_TRACE, "Incorrect value at PMA address 0x0000 - ");
1692                 xge_debug_osdep(XGE_TRACE, "Returned: %llx- Expected: 0x2040",
1693 				(unsigned long long)(unsigned long)val_1);
1694                 return;
1695         }
1696 
1697 	/* Loading the DOM register to MDIO register */
1698         addr = 0xA100;
1699         (void) xge_hal_mdio_write(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr, 0x0);
1700         val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
1701 
1702 	/*
1703 	 * Reading the Alarm flags
1704 	 */
1705         addr = 0xA070;
1706         val_1 = 0x0;
1707         val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
1708 	if(CHECKBIT(val_1, 0x7))
1709 	{
1710 		hldev->stats.sw_dev_err_stats.stats_xpak.
1711 			alarm_transceiver_temp_high++;
1712 		hldev->stats.sw_dev_err_stats.xpak_counter.excess_temp++;
1713 		__hal_chk_xpak_counter(hldev, 0x1,
1714 			hldev->stats.sw_dev_err_stats.xpak_counter.excess_temp);
1715 	} else {
1716 		hldev->stats.sw_dev_err_stats.xpak_counter.excess_temp = 0;
1717 	}
1718 	if(CHECKBIT(val_1, 0x6))
1719 		hldev->stats.sw_dev_err_stats.stats_xpak.
1720 			alarm_transceiver_temp_low++;
1721 
1722 	if(CHECKBIT(val_1, 0x3))
1723 	{
1724 		hldev->stats.sw_dev_err_stats.stats_xpak.
1725 			alarm_laser_bias_current_high++;
1726 		hldev->stats.sw_dev_err_stats.xpak_counter.
1727 			excess_bias_current++;
1728 		__hal_chk_xpak_counter(hldev, 0x2,
1729 			hldev->stats.sw_dev_err_stats.xpak_counter.
1730 			excess_bias_current);
1731 	} else {
1732 		hldev->stats.sw_dev_err_stats.xpak_counter.
1733 			excess_bias_current = 0;
1734 	}
1735 	if(CHECKBIT(val_1, 0x2))
1736 		hldev->stats.sw_dev_err_stats.stats_xpak.
1737 			alarm_laser_bias_current_low++;
1738 
1739 	if(CHECKBIT(val_1, 0x1))
1740 	{
1741 		hldev->stats.sw_dev_err_stats.stats_xpak.
1742 			alarm_laser_output_power_high++;
1743 		hldev->stats.sw_dev_err_stats.xpak_counter.
1744 			excess_laser_output++;
1745 		__hal_chk_xpak_counter(hldev, 0x3,
1746 			hldev->stats.sw_dev_err_stats.xpak_counter.
1747 				excess_laser_output);
1748 	} else {
1749 		hldev->stats.sw_dev_err_stats.xpak_counter.
1750 				excess_laser_output = 0;
1751 	}
1752 	if(CHECKBIT(val_1, 0x0))
1753 		hldev->stats.sw_dev_err_stats.stats_xpak.
1754 				alarm_laser_output_power_low++;
1755 
1756 	/*
1757 	 * Reading the warning flags
1758 	 */
1759         addr = 0xA074;
1760         val_1 = 0x0;
1761         val_1 = xge_hal_mdio_read(hldev, XGE_HAL_MDIO_MMD_PMA_DEV_ADDR, addr);
1762 	if(CHECKBIT(val_1, 0x7))
1763 		hldev->stats.sw_dev_err_stats.stats_xpak.
1764 			warn_transceiver_temp_high++;
1765 	if(CHECKBIT(val_1, 0x6))
1766 		hldev->stats.sw_dev_err_stats.stats_xpak.
1767 			warn_transceiver_temp_low++;
1768 	if(CHECKBIT(val_1, 0x3))
1769 		hldev->stats.sw_dev_err_stats.stats_xpak.
1770 			warn_laser_bias_current_high++;
1771 	if(CHECKBIT(val_1, 0x2))
1772 		hldev->stats.sw_dev_err_stats.stats_xpak.
1773 			warn_laser_bias_current_low++;
1774 	if(CHECKBIT(val_1, 0x1))
1775 		hldev->stats.sw_dev_err_stats.stats_xpak.
1776 			warn_laser_output_power_high++;
1777 	if(CHECKBIT(val_1, 0x0))
1778 		hldev->stats.sw_dev_err_stats.stats_xpak.
1779 			warn_laser_output_power_low++;
1780 }
1781