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