xref: /illumos-gate/usr/src/uts/common/io/xge/hal/xgehal/xgehal-mgmt.c (revision 7f7322febbcfe774b7270abc3b191c094bfcc517)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  *  Copyright (c) 2002-2005 Neterion, Inc.
24  *  All right Reserved.
25  *
26  *  FileName :    xgehal-mgmt.c
27  *
28  *  Description:  Xframe-family management facility implementation
29  *
30  *  Created:      1 September 2004
31  */
32 
33 #include "xgehal-mgmt.h"
34 #include "xgehal-driver.h"
35 #include "xgehal-device.h"
36 
37 /**
38  * xge_hal_mgmt_about - Retrieve about info.
39  * @devh: HAL device handle.
40  * @about_info: Filled in by HAL. See xge_hal_mgmt_about_info_t{}.
41  * @size: Size of the @about_info buffer. HAL will return error if the
42  *        size is smaller than sizeof(xge_hal_mgmt_about_info_t).
43  *
44  * Retrieve information such as PCI device and vendor IDs, board
45  * revision number, HAL version number, etc.
46  *
47  * Returns: XGE_HAL_OK - success;
48  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
49  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
50  * XGE_HAL_FAIL - Failed to retrieve the information.
51  *
52  * See also: xge_hal_mgmt_about_info_t{}.
53  */
54 xge_hal_status_e
55 xge_hal_mgmt_about(xge_hal_device_h devh, xge_hal_mgmt_about_info_t *about_info,
56 		int size)
57 {
58 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
59 
60 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
61 		return XGE_HAL_ERR_INVALID_DEVICE;
62 	}
63 
64 	if (size != sizeof(xge_hal_mgmt_about_info_t)) {
65 		return XGE_HAL_ERR_VERSION_CONFLICT;
66 	}
67 
68 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
69 		xge_offsetof(xge_hal_pci_config_le_t, vendor_id),
70 		&about_info->vendor);
71 
72 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
73 		xge_offsetof(xge_hal_pci_config_le_t, device_id),
74 		&about_info->device);
75 
76 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
77 		xge_offsetof(xge_hal_pci_config_le_t, subsystem_vendor_id),
78 		&about_info->subsys_vendor);
79 
80 	xge_os_pci_read16(hldev->pdev, hldev->cfgh,
81 		xge_offsetof(xge_hal_pci_config_le_t, subsystem_id),
82 		&about_info->subsys_device);
83 
84 	xge_os_pci_read8(hldev->pdev, hldev->cfgh,
85 		xge_offsetof(xge_hal_pci_config_le_t, revision),
86 		&about_info->board_rev);
87 
88 	xge_os_strcpy(about_info->vendor_name, XGE_DRIVER_VENDOR);
89 	xge_os_strcpy(about_info->chip_name, XGE_CHIP_FAMILY);
90 	xge_os_strcpy(about_info->media, XGE_SUPPORTED_MEDIA_0);
91 
92 	xge_os_strcpy(about_info->hal_major, XGE_HAL_VERSION_MAJOR);
93 	xge_os_strcpy(about_info->hal_minor, XGE_HAL_VERSION_MINOR);
94 	xge_os_strcpy(about_info->hal_fix,   XGE_HAL_VERSION_FIX);
95 	xge_os_strcpy(about_info->hal_build, XGE_HAL_VERSION_BUILD);
96 
97 	xge_os_strcpy(about_info->ll_major, XGELL_VERSION_MAJOR);
98 	xge_os_strcpy(about_info->ll_minor, XGELL_VERSION_MINOR);
99 	xge_os_strcpy(about_info->ll_fix,   XGELL_VERSION_FIX);
100 	xge_os_strcpy(about_info->ll_build, XGELL_VERSION_BUILD);
101 
102 	return XGE_HAL_OK;
103 }
104 
105 /**
106  * xge_hal_mgmt_reg_read - Read Xframe register.
107  * @devh: HAL device handle.
108  * @bar_id: 0 - for BAR0, 1- for BAR1.
109  * @offset: Register offset in the Base Address Register (BAR) space.
110  * @value: Register value. Returned by HAL.
111  * Read Xframe register.
112  *
113  * Returns: XGE_HAL_OK - success.
114  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
115  * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
116  * valid.
117  * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
118  *
119  * See also: xge_hal_aux_bar0_read(), xge_hal_aux_bar1_read().
120  */
121 xge_hal_status_e
122 xge_hal_mgmt_reg_read(xge_hal_device_h devh, int bar_id, unsigned int offset,
123 		u64 *value)
124 {
125 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
126 
127 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
128 		return XGE_HAL_ERR_INVALID_DEVICE;
129 	}
130 
131 	if (bar_id == 0) {
132 		if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
133 			return XGE_HAL_ERR_INVALID_OFFSET;
134 		}
135 		*value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
136 					     (void *)(hldev->bar0 + offset));
137 	} else if (bar_id == 1) {
138 		int i;
139 		for (i=0; i<XGE_HAL_MAX_FIFO_NUM; i++) {
140 			if (offset == i*0x2000 || offset == i*0x2000+0x18) {
141 				break;
142 			}
143 		}
144 		if (i == XGE_HAL_MAX_FIFO_NUM) {
145 			return XGE_HAL_ERR_INVALID_OFFSET;
146 		}
147 		*value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh1,
148 					     (void *)(hldev->bar1 + offset));
149 	} else {
150 		return XGE_HAL_ERR_INVALID_BAR_ID;
151 	}
152 
153 	return XGE_HAL_OK;
154 }
155 
156 /**
157  * xge_hal_mgmt_reg_write - Write Xframe register.
158  * @devh: HAL device handle.
159  * @bar_id: 0 - for BAR0, 1- for BAR1.
160  * @offset: Register offset in the Base Address Register (BAR) space.
161  * @value: Register value.
162  *
163  * Write Xframe register.
164  *
165  * Returns: XGE_HAL_OK - success.
166  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
167  * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
168  * valid.
169  * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid.
170  *
171  * See also: xge_hal_aux_bar0_write().
172  */
173 xge_hal_status_e
174 xge_hal_mgmt_reg_write(xge_hal_device_h devh, int bar_id, unsigned int offset,
175 		u64 value)
176 {
177 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
178 
179 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
180 		return XGE_HAL_ERR_INVALID_DEVICE;
181 	}
182 
183 	if (bar_id == 0) {
184 		if (offset > sizeof(xge_hal_pci_bar0_t)-8) {
185 			return XGE_HAL_ERR_INVALID_OFFSET;
186 		}
187 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, value,
188 				     (void *)(hldev->bar0 + offset));
189 	} else if (bar_id == 1) {
190 		int i;
191 		for (i=0; i<XGE_HAL_MAX_FIFO_NUM; i++) {
192 			if (offset == i*0x2000 || offset == i*0x2000+0x18) {
193 				break;
194 			}
195 		}
196 		if (i == XGE_HAL_MAX_FIFO_NUM) {
197 			return XGE_HAL_ERR_INVALID_OFFSET;
198 		}
199 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh1, value,
200 				     (void *)(hldev->bar1 + offset));
201 	} else {
202 		return XGE_HAL_ERR_INVALID_BAR_ID;
203 	}
204 
205 	return XGE_HAL_OK;
206 }
207 
208 /**
209  * xge_hal_mgmt_hw_stats - Get Xframe hardware statistics.
210  * @devh: HAL device handle.
211  * @hw_stats: Hardware statistics. Returned by HAL.
212  *            See xge_hal_stats_hw_info_t{}.
213  * @size: Size of the @hw_stats buffer. HAL will return an error
214  * if the size is smaller than sizeof(xge_hal_stats_hw_info_t).
215  * Get Xframe hardware statistics.
216  *
217  * Returns: XGE_HAL_OK - success.
218  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
219  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
220  *
221  * See also: xge_hal_mgmt_sw_stats().
222  */
223 xge_hal_status_e
224 xge_hal_mgmt_hw_stats(xge_hal_device_h devh, xge_hal_mgmt_hw_stats_t *hw_stats,
225 		int size)
226 {
227 	xge_hal_status_e status;
228 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
229 	xge_hal_stats_hw_info_t	*hw_info;
230 
231 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
232 		return XGE_HAL_ERR_INVALID_DEVICE;
233 	}
234 
235 	if (size != sizeof(xge_hal_stats_hw_info_t)) {
236 		return XGE_HAL_ERR_VERSION_CONFLICT;
237 	}
238 
239 	if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
240 		return status;
241 	}
242 
243 	xge_os_memcpy(hw_stats, hw_info, sizeof(xge_hal_stats_hw_info_t));
244 
245 	return XGE_HAL_OK;
246 }
247 
248 /**
249  * FIXME: document
250  */
251 xge_hal_status_e
252 xge_hal_mgmt_hw_stats_off(xge_hal_device_h devh, int off, int size, char *out)
253 {
254 	xge_hal_status_e status;
255 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
256 	xge_hal_stats_hw_info_t	*hw_info;
257 
258 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
259 		return XGE_HAL_ERR_INVALID_DEVICE;
260 	}
261 
262 	if (off > sizeof(xge_hal_stats_hw_info_t)-4 ||
263 	    size > 8) {
264 		return XGE_HAL_ERR_INVALID_OFFSET;
265 	}
266 
267 	if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) {
268 		return status;
269 	}
270 
271 	xge_os_memcpy(out, (char*)hw_info + off, size);
272 
273 	return XGE_HAL_OK;
274 }
275 
276 /**
277  * xge_hal_mgmt_sw_stats - Get per-device software statistics.
278  * @devh: HAL device handle.
279  * @sw_stats: Hardware statistics. Returned by HAL.
280  *            See xge_hal_stats_sw_err_t{}.
281  * @size: Size of the @sw_stats buffer. HAL will return an error
282  * if the size is smaller than sizeof(xge_hal_stats_sw_err_t).
283  * Get device software statistics, including ECC and Parity error
284  * counters, etc.
285  *
286  * Returns: XGE_HAL_OK - success.
287  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
288  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
289  *
290  * See also: xge_hal_stats_sw_err_t{}, xge_hal_mgmt_hw_stats().
291  */
292 xge_hal_status_e
293 xge_hal_mgmt_sw_stats(xge_hal_device_h devh, xge_hal_mgmt_sw_stats_t *sw_stats,
294 		int size)
295 {
296 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
297 
298 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
299 		return XGE_HAL_ERR_INVALID_DEVICE;
300 	}
301 
302 	if (size != sizeof(xge_hal_stats_sw_err_t)) {
303 		return XGE_HAL_ERR_VERSION_CONFLICT;
304 	}
305 
306 	if (!hldev->stats.is_initialized ||
307 	    !hldev->stats.is_enabled) {
308 		return XGE_HAL_INF_STATS_IS_NOT_READY;
309 	}
310 
311 	xge_os_memcpy(sw_stats, &hldev->stats.sw_dev_err_stats,
312 	            sizeof(xge_hal_stats_sw_err_t));
313 
314 	return XGE_HAL_OK;
315 }
316 
317 /**
318  * xge_hal_mgmt_device_stats - Get HAL device statistics.
319  * @devh: HAL device handle.
320  * @device_stats: HAL device "soft" statistics. Maintained by HAL itself.
321  *            (as opposed to xge_hal_mgmt_hw_stats() - those are
322  *            maintained by the Xframe hardware).
323  *            Returned by HAL.
324  *            See xge_hal_stats_device_info_t{}.
325  * @size: Size of the @device_stats buffer. HAL will return an error
326  * if the size is smaller than sizeof(xge_hal_stats_device_info_t).
327  *
328  * Get HAL (layer) statistic counters.
329  * Returns: XGE_HAL_OK - success.
330  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
331  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
332  * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
333  * currently available.
334  *
335  */
336 xge_hal_status_e
337 xge_hal_mgmt_device_stats(xge_hal_device_h devh,
338 		xge_hal_mgmt_device_stats_t *device_stats, int size)
339 {
340 	xge_hal_status_e status;
341 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
342 	xge_hal_stats_device_info_t *device_info;
343 
344 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
345 		return XGE_HAL_ERR_INVALID_DEVICE;
346 	}
347 
348 	if (size != sizeof(xge_hal_stats_device_info_t)) {
349 		return XGE_HAL_ERR_VERSION_CONFLICT;
350 	}
351 
352 	if ((status = xge_hal_stats_device (devh, &device_info)) !=
353 	XGE_HAL_OK) {
354 		return status;
355 	}
356 
357 	xge_os_memcpy(device_stats, device_info,
358 		    sizeof(xge_hal_stats_device_info_t));
359 
360 	return XGE_HAL_OK;
361 }
362 
363 /*
364  * __hal_update_ring_bump - Update the ring bump counter for the
365  * particular channel.
366  * @hldev: HAL device handle.
367  * @queue: the queue who's data is to be collected.
368  * @chinfo: pointer to the statistics structure of the given channel.
369  * Usage: See xge_hal_aux_stats_hal_read{}
370  */
371 
372 static void
373 __hal_update_ring_bump(xge_hal_device_t *hldev, int queue,
374 	xge_hal_stats_channel_info_t *chinfo)
375 {
376 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
377 	u64 rbc = 0;
378 	int reg = (queue / 4);
379 	void * addr;
380 
381 	addr = (reg == 1)? (&bar0->ring_bump_counter2) :
382 		(&bar0->ring_bump_counter1);
383 	rbc = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, addr);
384 	chinfo->ring_bump_cnt = XGE_HAL_RING_BUMP_CNT(queue, rbc);
385 }
386 
387 /**
388  * xge_hal_mgmt_channel_stats - Get HAL channel statistics.
389  * @channelh: HAL channel handle.
390  * @channel_stats: HAL channel statistics. Maintained by HAL itself
391  *            (as opposed to xge_hal_mgmt_hw_stats() - those are
392  *            maintained by the Xframe hardware).
393  *            Returned by HAL.
394  *            See xge_hal_stats_channel_info_t{}.
395  * @size: Size of the @channel_stats buffer. HAL will return an error
396  * if the size is smaller than sizeof(xge_hal_mgmt_channel_stats_t).
397  *
398  * Get HAL per-channel statistic counters.
399  *
400  * Returns: XGE_HAL_OK - success.
401  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
402  * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not
403  * currently available.
404  *
405  */
406 xge_hal_status_e
407 xge_hal_mgmt_channel_stats(xge_hal_channel_h channelh,
408 		xge_hal_mgmt_channel_stats_t *channel_stats, int size)
409 {
410 	xge_hal_status_e status;
411 	xge_hal_stats_channel_info_t *channel_info;
412 	xge_hal_channel_t *channel = channelh;
413 
414 	if (size != sizeof(xge_hal_stats_channel_info_t)) {
415 		return XGE_HAL_ERR_VERSION_CONFLICT;
416 	}
417 
418 	if ((status = xge_hal_stats_channel (channelh, &channel_info)) !=
419 								XGE_HAL_OK) {
420 		return status;
421 	}
422 
423 	if (xge_hal_device_check_id(channel->devh) == XGE_HAL_CARD_HERC) {
424 		__hal_update_ring_bump(channel->devh, channel->post_qid,
425 			channel_info);
426 	}
427 
428 	xge_os_memcpy(channel_stats, channel_info,
429 		    sizeof(xge_hal_stats_channel_info_t));
430 
431 	return XGE_HAL_OK;
432 }
433 
434 /**
435  * xge_hal_mgmt_pcireg_read - Read PCI configuration at a specified
436  * offset.
437  * @devh: HAL device handle.
438  * @offset: Offset in the 256 byte PCI configuration space.
439  * @value_bits: 8, 16, or 32 (bits) to read.
440  * @value: Value returned by HAL.
441  *
442  * Read PCI configuration, given device and offset in the PCI space.
443  *
444  * Returns: XGE_HAL_OK - success.
445  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
446  * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
447  * valid.
448  * XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE - Invalid bits size. Valid
449  * values(8/16/32).
450  *
451  */
452 xge_hal_status_e
453 xge_hal_mgmt_pcireg_read(xge_hal_device_h devh, unsigned int offset,
454 		int value_bits, u32 *value)
455 {
456 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
457 
458 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
459 		return XGE_HAL_ERR_INVALID_DEVICE;
460 	}
461 
462 	if (offset > sizeof(xge_hal_pci_config_t)-value_bits/8) {
463 		return XGE_HAL_ERR_INVALID_OFFSET;
464 	}
465 
466 	if (value_bits == 8) {
467 		xge_os_pci_read8(hldev->pdev, hldev->cfgh, offset, (u8*)value);
468 	} else if (value_bits == 16) {
469 		xge_os_pci_read16(hldev->pdev, hldev->cfgh, offset,
470 		(u16*)value);
471 	} else if (value_bits == 32) {
472 		xge_os_pci_read32(hldev->pdev, hldev->cfgh, offset, value);
473 	} else {
474 		return XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE;
475 	}
476 
477 	return XGE_HAL_OK;
478 }
479 
480 /**
481  * xge_hal_mgmt_device_config - Retrieve device configuration.
482  * @devh: HAL device handle.
483  * @dev_config: Device configuration, see xge_hal_device_config_t{}.
484  * @size: Size of the @dev_config buffer. HAL will return an error
485  * if the size is smaller than sizeof(xge_hal_mgmt_device_config_t).
486  *
487  * Get device configuration. Permits to retrieve at run-time configuration
488  * values that were used to initialize and configure the device.
489  *
490  * Returns: XGE_HAL_OK - success.
491  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
492  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
493  *
494  * See also: xge_hal_device_config_t{}, xge_hal_mgmt_driver_config().
495  */
496 xge_hal_status_e
497 xge_hal_mgmt_device_config(xge_hal_device_h devh,
498 		xge_hal_mgmt_device_config_t	*dev_config, int size)
499 {
500 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
501 
502 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
503 		return XGE_HAL_ERR_INVALID_DEVICE;
504 	}
505 
506 	if (size != sizeof(xge_hal_mgmt_device_config_t)) {
507 		return XGE_HAL_ERR_VERSION_CONFLICT;
508 	}
509 
510 	xge_os_memcpy(dev_config, &hldev->config,
511 	sizeof(xge_hal_device_config_t));
512 
513 	return XGE_HAL_OK;
514 }
515 
516 /**
517  * xge_hal_mgmt_driver_config - Retrieve driver configuration.
518  * @drv_config: Device configuration, see xge_hal_driver_config_t{}.
519  * @size: Size of the @dev_config buffer. HAL will return an error
520  * if the size is smaller than sizeof(xge_hal_mgmt_driver_config_t).
521  *
522  * Get driver configuration. Permits to retrieve at run-time configuration
523  * values that were used to configure the device at load-time.
524  *
525  * Returns: XGE_HAL_OK - success.
526  * XGE_HAL_ERR_DRIVER_NOT_INITIALIZED - HAL is not initialized.
527  * XGE_HAL_ERR_VERSION_CONFLICT - Version is not maching.
528  *
529  * See also: xge_hal_driver_config_t{}, xge_hal_mgmt_device_config().
530  */
531 xge_hal_status_e
532 xge_hal_mgmt_driver_config(xge_hal_mgmt_driver_config_t *drv_config, int size)
533 {
534 
535 	if (g_xge_hal_driver == NULL) {
536 		return XGE_HAL_ERR_DRIVER_NOT_INITIALIZED;
537 	}
538 
539 	if (size != sizeof(xge_hal_mgmt_driver_config_t)) {
540 		return XGE_HAL_ERR_VERSION_CONFLICT;
541 	}
542 
543 	xge_os_memcpy(drv_config, &g_xge_hal_driver->config,
544 		    sizeof(xge_hal_mgmt_driver_config_t));
545 
546 	return XGE_HAL_OK;
547 }
548 
549 /**
550  * xge_hal_mgmt_pci_config - Retrieve PCI configuration.
551  * @devh: HAL device handle.
552  * @pci_config: 256 byte long buffer for PCI configuration space.
553  * @size: Size of the @ buffer. HAL will return an error
554  * if the size is smaller than sizeof(xge_hal_mgmt_pci_config_t).
555  *
556  * Get PCI configuration. Permits to retrieve at run-time configuration
557  * values that were used to configure the device at load-time.
558  *
559  * Returns: XGE_HAL_OK - success.
560  * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
561  * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
562  *
563  */
564 xge_hal_status_e
565 xge_hal_mgmt_pci_config(xge_hal_device_h devh,
566 		xge_hal_mgmt_pci_config_t *pci_config, int size)
567 {
568 	int i;
569 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
570 
571 	if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) {
572 		return XGE_HAL_ERR_INVALID_DEVICE;
573 	}
574 
575 	if (size != sizeof(xge_hal_mgmt_pci_config_t)) {
576 		return XGE_HAL_ERR_VERSION_CONFLICT;
577 	}
578 
579 	/* refresh PCI config space */
580 	for (i = 0; i < 0x68/4+1; i++) {
581 		xge_os_pci_read32(hldev->pdev, hldev->cfgh, i*4,
582 		                (u32*)&hldev->pci_config_space + i);
583 	}
584 
585 	xge_os_memcpy(pci_config, &hldev->pci_config_space,
586 		    sizeof(xge_hal_mgmt_pci_config_t));
587 
588 	return XGE_HAL_OK;
589 }
590 
591 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
592 /**
593  * xge_hal_mgmt_trace_read - Read trace buffer contents.
594  * @buffer: Buffer to store the trace buffer contents.
595  * @buf_size: Size of the buffer.
596  * @offset: Offset in the internal trace buffer to read data.
597  * @read_length: Size of the valid data in the buffer.
598  *
599  * Read  HAL trace buffer contents starting from the offset
600  * upto the size of the buffer or till EOF is reached.
601  *
602  * Returns: XGE_HAL_OK - success.
603  * XGE_HAL_EOF_TRACE_BUF - No more data in the trace buffer.
604  *
605  */
606 xge_hal_status_e
607 xge_hal_mgmt_trace_read (char		*buffer,
608 			unsigned	buf_size,
609 			unsigned	*offset,
610 			unsigned	*read_length)
611 {
612 	int data_offset;
613 	int start_offset;
614 
615 	if ((g_xge_os_tracebuf == NULL) ||
616 		(g_xge_os_tracebuf->offset == g_xge_os_tracebuf->size - 2)) {
617 		return XGE_HAL_EOF_TRACE_BUF;
618 	}
619 
620 	data_offset = g_xge_os_tracebuf->offset + 1;
621 
622 	if  (*offset >= (unsigned)xge_os_strlen(g_xge_os_tracebuf->data +
623 	data_offset)) {
624 
625 		return XGE_HAL_EOF_TRACE_BUF;
626 	}
627 
628 	xge_os_memzero(buffer, buf_size);
629 
630 	start_offset  =  data_offset + *offset;
631 	*read_length = xge_os_strlen(g_xge_os_tracebuf->data +
632 	start_offset);
633 
634 	if (*read_length  >=  buf_size) {
635 		*read_length = buf_size - 1;
636 	}
637 
638 	xge_os_memcpy(buffer, g_xge_os_tracebuf->data + start_offset,
639 	*read_length);
640 
641 	*offset += *read_length;
642 	(*read_length) ++;
643 
644 	return XGE_HAL_OK;
645 }
646 
647 #endif
648 
649 /**
650  * xge_hal_restore_link_led - Restore link LED to its original state.
651  * @devh: HAL device handle.
652  */
653 void
654 xge_hal_restore_link_led(xge_hal_device_h devh)
655 {
656 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
657 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
658 	u64 val64;
659 
660 	/*
661 	 * If the current link state is UP, switch on LED else make it
662 	 * off.
663 	 */
664 
665 	/*
666 	 * For Xena 3 and lower revision cards, adapter control needs to be
667 	 * used for making LED ON/OFF.
668 	 */
669 	if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
670 	   (xge_hal_device_rev(hldev) <= 3)) {
671 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
672 					      &bar0->adapter_control);
673 		if (hldev->link_state == XGE_HAL_LINK_UP) {
674 			val64 |= XGE_HAL_ADAPTER_LED_ON;
675 		} else {
676 			val64 &= ~XGE_HAL_ADAPTER_LED_ON;
677 		}
678 
679 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
680 					&bar0->adapter_control);
681 		return;
682 	}
683 
684 	/*
685 	 * Use beacon control register to control the LED.
686 	 * LED link output corresponds to bit 8 of the beacon control
687 	 * register. Note that, in the case of Xena, beacon control register
688 	 * represents the gpio control register. In the case of Herc, LED
689 	 * handling is done by beacon control register as opposed to gpio
690 	 * control register in Xena.
691 	 */
692 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
693 				      &bar0->beacon_control);
694 	if (hldev->link_state == XGE_HAL_LINK_UP) {
695 		val64 |= 0x0080800000000000ULL;
696 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
697 				       val64, &bar0->beacon_control);
698 	} else {
699 		val64 |= 0x0000800000000000ULL;
700 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
701 				       val64, &bar0->beacon_control);
702 	}
703 }
704 
705 /**
706  * xge_hal_flick_link_led - Flick (blink) link LED.
707  * @devh: HAL device handle.
708  *
709  * Depending on the card revision flicker the link LED by using the
710  * beacon control or the adapter_control register.
711  */
712 void
713 xge_hal_flick_link_led(xge_hal_device_h devh)
714 {
715 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
716 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
717 	u64 val64 = 0;
718 
719 	/*
720 	 * For Xena 3 and lower revision cards, adapter control needs to be
721 	 * used for making LED ON/OFF.
722 	 */
723 	if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) &&
724 	   (xge_hal_device_rev(hldev) <= 3)) {
725 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
726 					      &bar0->adapter_control);
727 		val64 ^= XGE_HAL_ADAPTER_LED_ON;
728 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
729 					&bar0->adapter_control);
730 		return;
731 	}
732 
733 	/*
734 	 * Use beacon control register to control the Link LED.
735 	 * Note that, in the case of Xena, beacon control register represents
736 	 * the gpio control register. In the case of Herc, LED handling is
737 	 * done by beacon control register as opposed to gpio control register
738 	 * in Xena.
739 	 */
740 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
741 				      &bar0->beacon_control);
742 	val64 ^= XGE_HAL_GPIO_CTRL_GPIO_0;
743 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
744 			       &bar0->beacon_control);
745 }
746 
747 /**
748  * xge_hal_read_eeprom - Read 4 bytes of data from user given offset.
749  * @devh: HAL device handle.
750  * @off: offset at which the data must be written
751  * @data: output parameter where the data is stored.
752  *
753  * Read 4 bytes of data from the user given offset and return the
754  * read data.
755  * Note: will allow to read only part of the EEPROM visible through the
756  * I2C bus.
757  * Returns: -1 on failure, 0 on success.
758  */
759 xge_hal_status_e
760 xge_hal_read_eeprom(xge_hal_device_h devh, xge_hal_status_e off, u32* data)
761 {
762 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
763 	int ret = XGE_HAL_FAIL;
764 	u32 exit_cnt = 0;
765 	u64 val64;
766 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
767 
768 
769 	val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) |
770 		XGE_HAL_I2C_CONTROL_ADDR(off) |
771 		XGE_HAL_I2C_CONTROL_BYTE_CNT(0x3) |
772 		XGE_HAL_I2C_CONTROL_READ | XGE_HAL_I2C_CONTROL_CNTL_START;
773 
774 	__hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
775 			(u32)val64, &bar0->i2c_control);
776 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
777 			(u32) (val64 >> 32), &bar0->i2c_control);
778 
779 	while (exit_cnt < 5) {
780 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
781 					&bar0->i2c_control);
782 		if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) {
783 			*data = XGE_HAL_I2C_CONTROL_GET_DATA(val64);
784 			ret = XGE_HAL_OK;
785 			break;
786 		}
787 		xge_os_mdelay(50);
788 		exit_cnt++;
789 	}
790 
791 	return ret;
792 }
793 
794 /*
795  * xge_hal_write_eeprom - actually writes the relevant part of the data
796  value.
797  * @devh: HAL device handle.
798  * @off: offset at which the data must be written
799  * @data : The data that is to be written
800  * @cnt : Number of bytes of the data that are actually to be written into
801  * the Eeprom. (max of 3)
802  *
803  * Actually writes the relevant part of the data value into the Eeprom
804  * through the I2C bus.
805  * Return value:
806  * 0 on success, -1 on failure.
807  */
808 
809 xge_hal_status_e
810 xge_hal_write_eeprom(xge_hal_device_h devh, int off, u32 data, int cnt)
811 {
812 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
813 	int exit_cnt = 0, ret = XGE_HAL_FAIL;
814 	u64 val64;
815 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
816 
817 	val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) |
818 		XGE_HAL_I2C_CONTROL_ADDR(off) |
819 		XGE_HAL_I2C_CONTROL_BYTE_CNT(cnt) |
820 		XGE_HAL_I2C_CONTROL_SET_DATA(data) |
821 		XGE_HAL_I2C_CONTROL_CNTL_START;
822 	__hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
823 			(u32)val64, &bar0->i2c_control);
824 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
825 			(u32) (val64 >> 32), &bar0->i2c_control);
826 
827 	while (exit_cnt < 5) {
828 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
829 					&bar0->i2c_control);
830 		if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) {
831 			if (!(val64 & XGE_HAL_I2C_CONTROL_NACK))
832 				ret = XGE_HAL_OK;
833 			break;
834 		}
835 		xge_os_mdelay(50);
836 		exit_cnt++;
837 	}
838 
839 	return ret;
840 }
841 
842 /*
843  * xge_hal_register_test - reads and writes into all clock domains.
844  * @hldev : private member of the device structure.
845  * xge_nic structure.
846  * @data : variable that returns the result of each of the test conducted b
847  * by the driver.
848  *
849  * Read and write into all clock domains. The NIC has 3 clock domains,
850  * see that registers in all the three regions are accessible.
851  * Return value:
852  * 0 on success.
853  */
854 xge_hal_status_e
855 xge_hal_register_test(xge_hal_device_h devh, u64 *data)
856 {
857 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
858 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
859 	u64 val64 = 0;
860 	int fail = 0;
861 
862 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
863 			&bar0->pif_rd_swapper_fb);
864 	if (val64 != 0x123456789abcdefULL) {
865 		fail = 1;
866 		xge_debug_osdep(XGE_TRACE, "Read Test level 1 fails\n");
867 	}
868 
869 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
870 			&bar0->rmac_pause_cfg);
871 	if (val64 != 0xc000ffff00000000ULL) {
872 		fail = 1;
873 		xge_debug_osdep(XGE_TRACE, "Read Test level 2 fails\n");
874 	}
875 
876 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
877 			&bar0->rx_queue_cfg);
878 	if (val64 != 0x0808080808080808ULL) {
879 		fail = 1;
880 		xge_debug_osdep(XGE_TRACE, "Read Test level 3 fails\n");
881 	}
882 
883 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
884 			&bar0->xgxs_efifo_cfg);
885 	if (val64 != 0x000000001923141EULL) {
886 		fail = 1;
887 		xge_debug_osdep(XGE_TRACE, "Read Test level 4 fails\n");
888 	}
889 
890 	val64 = 0x5A5A5A5A5A5A5A5AULL;
891 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
892 			&bar0->xmsi_data);
893 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
894 			&bar0->xmsi_data);
895 	if (val64 != 0x5A5A5A5A5A5A5A5AULL) {
896 		fail = 1;
897 		xge_debug_osdep(XGE_ERR, "Write Test level 1 fails\n");
898 	}
899 
900 	val64 = 0xA5A5A5A5A5A5A5A5ULL;
901 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
902 			&bar0->xmsi_data);
903 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
904 			&bar0->xmsi_data);
905 	if (val64 != 0xA5A5A5A5A5A5A5A5ULL) {
906 		fail = 1;
907 		xge_debug_osdep(XGE_ERR, "Write Test level 2 fails\n");
908 	}
909 
910 	*data = fail;
911 	return XGE_HAL_OK;
912 }
913 
914 /*
915  * xge_hal_rldram_test - offline test for access to the RldRam chip on
916  the NIC
917  * @devh: HAL device handle.
918  * @data: variable that returns the result of each of the test
919  * conducted by the driver.
920  *
921  * This is one of the offline test that tests the read and write
922  * access to the RldRam chip on the NIC.
923  * Return value:
924  * 0 on success.
925  */
926 xge_hal_status_e
927 xge_hal_rldram_test(xge_hal_device_h devh, uint64_t * data)
928 {
929 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
930 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
931 	u64 val64;
932 	int cnt, iteration = 0, test_pass = 0;
933 
934 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
935 			&bar0->adapter_control);
936 	val64 &= ~XGE_HAL_ADAPTER_ECC_EN;
937 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
938 			&bar0->adapter_control);
939 
940 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
941 			&bar0->mc_rldram_test_ctrl);
942 	val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE;
943 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
944 			&bar0->mc_rldram_test_ctrl);
945 
946 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
947 			&bar0->mc_rldram_mrs);
948 	val64 |= XGE_HAL_MC_RLDRAM_QUEUE_SIZE_ENABLE;
949 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
950 			(u32) (val64 >> 32), &bar0->i2c_control);
951 	__hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
952 			(u32)val64, &bar0->mc_rldram_mrs);
953 
954 	val64 |= XGE_HAL_MC_RLDRAM_MRS_ENABLE;
955 	__hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
956 			(u32) (val64 >> 32), &bar0->i2c_control);
957 	__hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
958 			(u32)val64, &bar0->mc_rldram_mrs);
959 
960 	while (iteration < 2) {
961 		val64 = 0x55555555aaaa0000ULL;
962 		if (iteration == 1) {
963 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
964 		}
965 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
966 			&bar0->mc_rldram_test_d0);
967 
968 		val64 = 0xaaaa5a5555550000ULL;
969 		if (iteration == 1) {
970 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
971 		}
972 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
973 			&bar0->mc_rldram_test_d1);
974 
975 		val64 = 0x55aaaaaaaa5a0000ULL;
976 		if (iteration == 1) {
977 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
978 		}
979 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
980 			&bar0->mc_rldram_test_d2);
981 
982 		val64 = (u64) (0x0000003fffff0000ULL);
983 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
984 			&bar0->mc_rldram_test_add);
985 
986 
987 		val64 = XGE_HAL_MC_RLDRAM_TEST_MODE;
988 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
989 			&bar0->mc_rldram_test_ctrl);
990 
991 		val64 |=
992 		    XGE_HAL_MC_RLDRAM_TEST_MODE | XGE_HAL_MC_RLDRAM_TEST_WRITE |
993 		    XGE_HAL_MC_RLDRAM_TEST_GO;
994 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
995 			&bar0->mc_rldram_test_ctrl);
996 
997 		for (cnt = 0; cnt < 5; cnt++) {
998 			val64 = xge_os_pio_mem_read64(hldev->pdev,
999 				hldev->regh0, &bar0->mc_rldram_test_ctrl);
1000 			if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE)
1001 				break;
1002 			xge_os_mdelay(200);
1003 		}
1004 
1005 		if (cnt == 5)
1006 			break;
1007 
1008 		val64 = XGE_HAL_MC_RLDRAM_TEST_MODE;
1009 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1010 			&bar0->mc_rldram_test_ctrl);
1011 
1012 		val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE |
1013 		XGE_HAL_MC_RLDRAM_TEST_GO;
1014 		xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
1015 			&bar0->mc_rldram_test_ctrl);
1016 
1017 		for (cnt = 0; cnt < 5; cnt++) {
1018 			val64 = xge_os_pio_mem_read64(hldev->pdev,
1019 				hldev->regh0, &bar0->mc_rldram_test_ctrl);
1020 			if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE)
1021 				break;
1022 			xge_os_mdelay(500);
1023 		}
1024 
1025 		if (cnt == 5)
1026 			break;
1027 
1028 		val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1029 			&bar0->mc_rldram_test_ctrl);
1030 		if (val64 & XGE_HAL_MC_RLDRAM_TEST_PASS)
1031 			test_pass = 1;
1032 
1033 		iteration++;
1034 	}
1035 
1036 	if (!test_pass)
1037 		*data = 1;
1038 	else
1039 		*data = 0;
1040 
1041 	return XGE_HAL_OK;
1042 }
1043 
1044 /*
1045  * xge_hal_eeprom_test - to verify that EEprom in the xena can be
1046  programmed.
1047  * @devh: HAL device handle.
1048  * @data:variable that returns the result of each of the test conducted by
1049  * the driver.
1050  *
1051  * Verify that EEPROM in the xena can be programmed using I2C_CONTROL
1052  * register.
1053  * Return value:
1054  * 0 on success.
1055  */
1056 xge_hal_status_e
1057 xge_hal_eeprom_test(xge_hal_device_h devh, u64 *data)
1058 {
1059 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1060 	int fail = 0;
1061 	u32 ret_data;
1062 
1063 	/* Test Write Error at offset 0 */
1064 	if (!xge_hal_write_eeprom(hldev, 0, 0, 3))
1065 		fail = 1;
1066 
1067 	/* Test Write at offset 4f0 */
1068 	if (xge_hal_write_eeprom(hldev, 0x4F0, 0x01234567, 3))
1069 		fail = 1;
1070 	if (xge_hal_read_eeprom(hldev, 0x4F0, &ret_data))
1071 		fail = 1;
1072 
1073 	if (ret_data != 0x01234567)
1074 		fail = 1;
1075 
1076 	/* Reset the EEPROM data go FFFF */
1077 	(void) xge_hal_write_eeprom(hldev, 0x4F0, 0xFFFFFFFF, 3);
1078 
1079 	/* Test Write Request Error at offset 0x7c */
1080 	if (!xge_hal_write_eeprom(hldev, 0x07C, 0, 3))
1081 		fail = 1;
1082 
1083 	/* Test Write Request at offset 0x7fc */
1084 	if (xge_hal_write_eeprom(hldev, 0x7FC, 0x01234567, 3))
1085 		fail = 1;
1086 	if (xge_hal_read_eeprom(hldev, 0x7FC, &ret_data))
1087 		fail = 1;
1088 
1089 	if (ret_data != 0x01234567)
1090 		fail = 1;
1091 
1092 	/* Reset the EEPROM data go FFFF */
1093 	(void) xge_hal_write_eeprom(hldev, 0x7FC, 0xFFFFFFFF, 3);
1094 
1095 	/* Test Write Error at offset 0x80 */
1096 	if (!xge_hal_write_eeprom(hldev, 0x080, 0, 3))
1097 		fail = 1;
1098 
1099 	/* Test Write Error at offset 0xfc */
1100 	if (!xge_hal_write_eeprom(hldev, 0x0FC, 0, 3))
1101 		fail = 1;
1102 
1103 	/* Test Write Error at offset 0x100 */
1104 	if (!xge_hal_write_eeprom(hldev, 0x100, 0, 3))
1105 		fail = 1;
1106 
1107 	/* Test Write Error at offset 4ec */
1108 	if (!xge_hal_write_eeprom(hldev, 0x4EC, 0, 3))
1109 		fail = 1;
1110 
1111 	*data = fail;
1112 	return XGE_HAL_OK;
1113 }
1114 
1115 /*
1116  * xge_hal_bist_test - invokes the MemBist test of the card .
1117  * @devh: HAL device handle.
1118  * xge_nic structure.
1119  * @data:variable that returns the result of each of the test conducted by
1120  * the driver.
1121  *
1122  * This invokes the MemBist test of the card. We give around
1123  * 2 secs time for the Test to complete. If it's still not complete
1124  * within this peiod, we consider that the test failed.
1125  * Return value:
1126  * 0 on success and -1 on failure.
1127  */
1128 xge_hal_status_e
1129 xge_hal_bist_test(xge_hal_device_h devh, u64 *data)
1130 {
1131 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1132 	u8 bist = 0;
1133 	int cnt = 0, ret = XGE_HAL_FAIL;
1134 
1135 	xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist);
1136 	bist |= 0x40;
1137 	xge_os_pci_write8(hldev->pdev, hldev->cfgh, 0x0f, bist);
1138 
1139 	while (cnt < 20) {
1140 		xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist);
1141 		if (!(bist & 0x40)) {
1142 			*data = (bist & 0x0f);
1143 			ret = XGE_HAL_OK;
1144 			break;
1145 		}
1146 		xge_os_mdelay(100);
1147 		cnt++;
1148 	}
1149 
1150 	return ret;
1151 }
1152 
1153 /*
1154  * xge_hal_link_test - verifies the link state of the nic
1155  * @devh: HAL device handle.
1156  * @data: variable that returns the result of each of the test conducted by
1157  * the driver.
1158  *
1159  * Verify the link state of the NIC and updates the input
1160  * argument 'data' appropriately.
1161  * Return value:
1162  * 0 on success.
1163  */
1164 xge_hal_status_e
1165 xge_hal_link_test(xge_hal_device_h devh, u64 *data)
1166 {
1167 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1168 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1169 	u64 val64;
1170 
1171 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1172 			&bar0->adapter_status);
1173 	if (val64 & XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)
1174 		*data = 1;
1175 
1176 	return XGE_HAL_OK;
1177 }
1178 
1179 
1180 /**
1181  * xge_hal_getpause_data -Pause frame frame generation and reception.
1182  * @devh: HAL device handle.
1183  * @tx : A field to return the pause generation capability of the NIC.
1184  * @rx : A field to return the pause reception capability of the NIC.
1185  *
1186  * Returns the Pause frame generation and reception capability of the NIC.
1187  * Return value:
1188  *  void
1189  */
1190 void xge_hal_getpause_data(xge_hal_device_h devh, int *tx, int *rx)
1191 {
1192 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1193 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1194 	u64 val64;
1195 
1196 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1197 				&bar0->rmac_pause_cfg);
1198 	if (val64 & XGE_HAL_RMAC_PAUSE_GEN_EN)
1199 		*tx = 1;
1200 	if (val64 & XGE_HAL_RMAC_PAUSE_RCV_EN)
1201 		*rx = 1;
1202 }
1203 
1204 /**
1205  * xge_hal_setpause_data -  set/reset pause frame generation.
1206  * @devh: HAL device handle.
1207  * @tx: A field that indicates the pause generation capability to be
1208  * set on the NIC.
1209  * @rx: A field that indicates the pause reception capability to be
1210  * set on the NIC.
1211  *
1212  * It can be used to set or reset Pause frame generation or reception
1213  * support of the NIC.
1214  * Return value:
1215  * int, returns 0 on Success
1216  */
1217 
1218 int xge_hal_setpause_data(xge_hal_device_h devh, int tx, int rx)
1219 {
1220 	xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
1221 	xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
1222 	u64 val64;
1223 
1224 	val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
1225 				    &bar0->rmac_pause_cfg);
1226 	if (tx)
1227 		val64 |= XGE_HAL_RMAC_PAUSE_GEN_EN;
1228 	else
1229 		val64 &= ~XGE_HAL_RMAC_PAUSE_GEN_EN;
1230 	if (rx)
1231 		val64 |= XGE_HAL_RMAC_PAUSE_RCV_EN;
1232 	else
1233 		val64 &= ~XGE_HAL_RMAC_PAUSE_RCV_EN;
1234 	xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
1235 			     val64, &bar0->rmac_pause_cfg);
1236 	return 0;
1237 }
1238 
1239