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