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 */
45xge_hal_status_e
46xge_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 */
134xge_hal_status_e
135xge_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 */
191xge_hal_status_e
192xge_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 */
246xge_hal_status_e
247xge_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 */
286xge_hal_status_e
287xge_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 */
328xge_hal_status_e
329xge_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 */
369xge_hal_status_e
370xge_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 */
413xge_hal_status_e
414xge_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 */
460xge_hal_status_e
461xge_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
496static 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 */
530xge_hal_status_e
531xge_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 */
575xge_hal_status_e
576xge_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 */
619xge_hal_status_e
620xge_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 */
654xge_hal_status_e
655xge_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 */
687xge_hal_status_e
688xge_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 */
729xge_hal_status_e
730xge_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 */
776void
777xge_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 */
832void
833xge_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 */
879xge_hal_status_e
880xge_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
923xge_hal_status_e
924xge_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 */
964xge_hal_status_e
965xge_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 */
1036xge_hal_status_e
1037xge_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 */
1157xge_hal_status_e
1158xge_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
1246u16
1247xge_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
1299xge_hal_status_e
1300xge_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 */
1367xge_hal_status_e
1368xge_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 */
1439xge_hal_status_e
1440xge_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 */
1476xge_hal_status_e
1477xge_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 */
1502void 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
1530int 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 */
1558u32 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
1606void __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 */
1672void __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