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: stable/10/sys/dev/nxge/xgehal/xgehal-mgmt.c 173139 2007-10-29 14:19:32Z rwatson $
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
xge_hal_mgmt_about(xge_hal_device_h devh,xge_hal_mgmt_about_info_t * about_info,int size)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
xge_hal_mgmt_reg_read(xge_hal_device_h devh,int bar_id,unsigned int offset,u64 * value)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
xge_hal_mgmt_reg_write(xge_hal_device_h devh,int bar_id,unsigned int offset,u64 value)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
xge_hal_mgmt_hw_stats(xge_hal_device_h devh,xge_hal_mgmt_hw_stats_t * hw_stats,int size)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
xge_hal_mgmt_hw_stats_off(xge_hal_device_h devh,int off,int size,char * out)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
xge_hal_mgmt_pcim_stats(xge_hal_device_h devh,xge_hal_mgmt_pcim_stats_t * pcim_stats,int size)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
xge_hal_mgmt_pcim_stats_off(xge_hal_device_h devh,int off,int size,char * out)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
xge_hal_mgmt_sw_stats(xge_hal_device_h devh,xge_hal_mgmt_sw_stats_t * sw_stats,int size)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
xge_hal_mgmt_device_stats(xge_hal_device_h devh,xge_hal_mgmt_device_stats_t * device_stats,int size)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
__hal_update_ring_bump(xge_hal_device_t * hldev,int queue,xge_hal_stats_channel_info_t * chinfo)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
xge_hal_mgmt_channel_stats(xge_hal_channel_h channelh,xge_hal_mgmt_channel_stats_t * channel_stats,int size)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
xge_hal_mgmt_pcireg_read(xge_hal_device_h devh,unsigned int offset,int value_bits,u32 * value)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
xge_hal_mgmt_device_config(xge_hal_device_h devh,xge_hal_mgmt_device_config_t * dev_config,int size)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
xge_hal_mgmt_driver_config(xge_hal_mgmt_driver_config_t * drv_config,int size)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
xge_hal_mgmt_pci_config(xge_hal_device_h devh,xge_hal_mgmt_pci_config_t * pci_config,int size)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
xge_hal_mgmt_trace_read(char * buffer,unsigned buf_size,unsigned * offset,unsigned * read_length)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
xge_hal_restore_link_led(xge_hal_device_h devh)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
xge_hal_flick_link_led(xge_hal_device_h devh)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
xge_hal_read_eeprom(xge_hal_device_h devh,int off,u32 * data)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
xge_hal_write_eeprom(xge_hal_device_h devh,int off,u32 data,int cnt)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
xge_hal_register_test(xge_hal_device_h devh,u64 * data)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
xge_hal_rldram_test(xge_hal_device_h devh,u64 * data)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
xge_hal_pma_loopback(xge_hal_device_h devh,int enable)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
xge_hal_mdio_read(xge_hal_device_h devh,u32 mmd_type,u64 addr)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
xge_hal_mdio_write(xge_hal_device_h devh,u32 mmd_type,u64 addr,u32 value)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
xge_hal_eeprom_test(xge_hal_device_h devh,u64 * data)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
xge_hal_bist_test(xge_hal_device_h devh,u64 * data)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
xge_hal_link_test(xge_hal_device_h devh,u64 * data)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  */
xge_hal_getpause_data(xge_hal_device_h devh,int * tx,int * rx)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 
xge_hal_setpause_data(xge_hal_device_h devh,int tx,int rx)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  */
xge_hal_read_xfp_current_temp(xge_hal_device_h hldev)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 
__hal_chk_xpak_counter(xge_hal_device_t * hldev,int type,u32 value)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  */
__hal_updt_stats_xpak(xge_hal_device_t * hldev)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 }
1765