1/*-
2 * Copyright(c) 2002-2011 Exar Corp.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification are permitted provided the following conditions are met:
7 *
8 *    1. Redistributions of source code must retain the above copyright notice,
9 *       this list of conditions and the following disclaimer.
10 *
11 *    2. Redistributions in binary form must reproduce the above copyright
12 *       notice, this list of conditions and the following disclaimer in the
13 *       documentation and/or other materials provided with the distribution.
14 *
15 *    3. Neither the name of the Exar Corporation nor the names of its
16 *       contributors may be used to endorse or promote products derived from
17 *       this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31/*$FreeBSD$*/
32
33#include <dev/vxge/vxgehal/vxgehal.h>
34
35/*
36 * vxge_hal_mgmt_about - Retrieve about info.
37 * @devh: HAL device handle.
38 * @about_info: Filled in by HAL. See vxge_hal_mgmt_about_info_t {}.
39 * @size: Pointer to buffer containing the Size of the @buffer_info.
40 * HAL will return an error if the size is smaller than
41 * sizeof(vxge_hal_mgmt_about_info_t) and returns required size in this field
42 *
43 * Retrieve information such as PCI device and vendor IDs, board
44 * revision number, HAL version number, etc.
45 *
46 * Returns: VXGE_HAL_OK - success;
47 * VXGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
48 * VXGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
49 * VXGE_HAL_ERR_OUT_OF_SPACE - If the buffer is not sufficient
50 * VXGE_HAL_FAIL - Failed to retrieve the information.
51 *
52 * See also: vxge_hal_mgmt_about_info_t {}.
53 */
54vxge_hal_status_e
55vxge_hal_mgmt_about(vxge_hal_device_h devh,
56    vxge_hal_mgmt_about_info_t *about_info,
57    u32 *size)
58{
59	__hal_device_t *hldev = (__hal_device_t *) devh;
60
61	vxge_assert((hldev != NULL) && (about_info != NULL) && (size != NULL));
62
63	vxge_hal_trace_log_device("==> %s:%s:%d",
64	    __FILE__, __func__, __LINE__);
65
66	vxge_hal_trace_log_device(
67	    "hldev = 0x"VXGE_OS_STXFMT", about_info = 0x"VXGE_OS_STXFMT", "
68	    "size = 0x"VXGE_OS_STXFMT,
69	    (ptr_t) hldev, (ptr_t) about_info, (ptr_t) size);
70
71	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
72		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
73		    __FILE__, __func__, __LINE__,
74		    VXGE_HAL_ERR_INVALID_DEVICE);
75		return (VXGE_HAL_ERR_INVALID_DEVICE);
76	}
77
78	if (*size < sizeof(vxge_hal_mgmt_about_info_t)) {
79		*size = sizeof(vxge_hal_mgmt_about_info_t);
80		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
81		    __FILE__, __func__, __LINE__,
82		    VXGE_HAL_ERR_OUT_OF_SPACE);
83		return (VXGE_HAL_ERR_OUT_OF_SPACE);
84	}
85
86	about_info->vendor = hldev->pci_config_space_bios.vendor_id;
87	about_info->device = hldev->pci_config_space_bios.device_id;
88	about_info->subsys_vendor =
89	    hldev->pci_config_space_bios.subsystem_vendor_id;
90	about_info->subsys_device = hldev->pci_config_space_bios.subsystem_id;
91	about_info->board_rev = hldev->pci_config_space_bios.revision;
92
93	vxge_os_strlcpy(about_info->vendor_name, VXGE_DRIVER_VENDOR,
94	    sizeof(about_info->vendor_name));
95	vxge_os_strlcpy(about_info->chip_name, VXGE_CHIP_FAMILY,
96	    sizeof(about_info->chip_name));
97	vxge_os_strlcpy(about_info->media, VXGE_SUPPORTED_MEDIA_0,
98	    sizeof(about_info->media));
99
100	(void) vxge_os_snprintf(about_info->hal_major,
101	    sizeof(about_info->hal_major), "%d", VXGE_HAL_VERSION_MAJOR);
102	(void) vxge_os_snprintf(about_info->hal_minor,
103	    sizeof(about_info->hal_minor), "%d", VXGE_HAL_VERSION_MINOR);
104	(void) vxge_os_snprintf(about_info->hal_fix,
105	    sizeof(about_info->hal_fix), "%d", VXGE_HAL_VERSION_FIX);
106	(void) vxge_os_snprintf(about_info->hal_build,
107	    sizeof(about_info->hal_build), "%d", VXGE_HAL_VERSION_BUILD);
108
109	(void) vxge_os_snprintf(about_info->ll_major,
110	    sizeof(about_info->ll_major), "%d", XGELL_VERSION_MAJOR);
111	(void) vxge_os_snprintf(about_info->ll_minor,
112	    sizeof(about_info->ll_minor), "%d", XGELL_VERSION_MINOR);
113	(void) vxge_os_snprintf(about_info->ll_fix,
114	    sizeof(about_info->ll_fix), "%d", XGELL_VERSION_FIX);
115	(void) vxge_os_snprintf(about_info->ll_build,
116	    sizeof(about_info->ll_build), "%d", XGELL_VERSION_BUILD);
117
118	*size = sizeof(vxge_hal_mgmt_about_info_t);
119
120	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
121	    __FILE__, __func__, __LINE__);
122
123	return (VXGE_HAL_OK);
124}
125
126/*
127 * vxge_hal_mgmt_pci_config - Retrieve PCI configuration.
128 * @devh: HAL device handle.
129 * @buffer: Buffer to return pci config.
130 * @size: Pointer to buffer containing the Size of the @buffer.
131 * HAL will return an error if the size is smaller than
132 * sizeof(vxge_hal_pci_config_t) and returns required size in this field
133 *
134 * Get PCI configuration. Permits to retrieve at run-time configuration
135 * values that were used to configure the device at load-time.
136 *
137 * Returns: VXGE_HAL_OK - success.
138 * VXGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
139 * VXGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
140 * VXGE_HAL_ERR_OUT_OF_SPACE - If the buffer is not sufficient
141 *
142 */
143vxge_hal_status_e
144vxge_hal_mgmt_pci_config(vxge_hal_device_h devh, u8 *buffer, u32 *size)
145{
146	int i;
147	vxge_hal_pci_config_t *pci_config = (vxge_hal_pci_config_t *) buffer;
148	__hal_device_t *hldev = (__hal_device_t *) devh;
149
150	vxge_assert((hldev != NULL) && (buffer != NULL) && (size != NULL));
151
152	vxge_hal_trace_log_device("==> %s:%s:%d",
153	    __FILE__, __func__, __LINE__);
154
155	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT", "
156	    "buffer = 0x"VXGE_OS_STXFMT", "
157	    "size = 0x"VXGE_OS_STXFMT,
158	    (ptr_t) hldev, (ptr_t) buffer, (ptr_t) size);
159
160	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
161		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
162		    __FILE__, __func__, __LINE__,
163		    VXGE_HAL_ERR_INVALID_DEVICE);
164		return (VXGE_HAL_ERR_INVALID_DEVICE);
165	}
166
167	if (*size < sizeof(vxge_hal_pci_config_t)) {
168		*size = sizeof(vxge_hal_pci_config_t);
169		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
170		    __FILE__, __func__, __LINE__,
171		    VXGE_HAL_ERR_OUT_OF_SPACE);
172		return (VXGE_HAL_ERR_OUT_OF_SPACE);
173	}
174
175	/* refresh PCI config space */
176	for (i = 0; i < VXGE_HAL_PCI_CONFIG_SPACE_SIZE / 4; i++) {
177		(void) __hal_vpath_pci_read(hldev,
178		    hldev->first_vp_id,
179		    i * 4,
180		    4,
181		    (u32 *) ((void *)&hldev->pci_config_space) + i);
182	}
183
184	vxge_os_memcpy(pci_config, &hldev->pci_config_space,
185	    sizeof(vxge_hal_pci_config_t));
186
187	*size = sizeof(vxge_hal_pci_config_t);
188
189	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
190	    __FILE__, __func__, __LINE__);
191
192	return (VXGE_HAL_OK);
193}
194
195/*
196 * vxge_hal_mgmt_msi_capabilities_get - Returns the msi capabilities
197 * @devh: HAL device handle.
198 * @msi_cap: MSI Capabilities
199 *
200 * Return the msi capabilities
201 */
202vxge_hal_status_e
203vxge_hal_mgmt_msi_capabilities_get(vxge_hal_device_h devh,
204    vxge_hal_mgmt_msi_cap_t *msi_cap)
205{
206	u16 msi_control_reg;
207	u32 addr32;
208	__hal_device_t *hldev = (__hal_device_t *) devh;
209
210	vxge_assert((hldev != NULL) && (msi_cap != NULL));
211
212	vxge_hal_trace_log_device("==> %s:%s:%d",
213	    __FILE__, __func__, __LINE__);
214
215	vxge_hal_trace_log_device(
216	    "hldev = 0x"VXGE_OS_STXFMT", msi_cap = 0x"VXGE_OS_STXFMT,
217	    (ptr_t) hldev, (ptr_t) msi_cap);
218
219	if (hldev->pci_caps.msi_cap_offset == 0) {
220		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
221		    __FILE__, __func__, __LINE__, VXGE_HAL_FAIL);
222		return (VXGE_HAL_FAIL);
223	}
224
225	vxge_os_memzero(msi_cap, sizeof(vxge_hal_mgmt_msi_cap_t));
226
227	(void) __hal_vpath_pci_read(hldev,
228	    hldev->first_vp_id,
229	    hldev->pci_caps.msi_cap_offset +
230	    vxge_offsetof(vxge_hal_msi_capability_le_t, msi_control),
231	    2,
232	    &msi_control_reg);
233
234	if (msi_control_reg & VXGE_HAL_PCI_MSI_FLAGS_ENABLE)
235		msi_cap->enable = 1;
236
237	if (msi_control_reg & VXGE_HAL_PCI_MSI_FLAGS_PVMASK)
238		msi_cap->is_pvm_capable = 1;
239
240	if (msi_control_reg & VXGE_HAL_PCI_MSI_FLAGS_64BIT)
241		msi_cap->is_64bit_addr_capable = 1;
242
243	msi_cap->vectors_allocated =
244	    (msi_control_reg & VXGE_HAL_PCI_MSI_FLAGS_QSIZE) >> 4;
245
246	msi_cap->max_vectors_capable =
247	    (msi_control_reg & VXGE_HAL_PCI_MSI_FLAGS_QMASK) >> 1;
248
249	if (msi_cap->is_64bit_addr_capable) {
250		if (msi_cap->is_pvm_capable) {
251			(void) __hal_vpath_pci_read(hldev,
252			    hldev->first_vp_id,
253			    hldev->pci_caps.msi_cap_offset +
254			    vxge_offsetof(vxge_hal_msi_capability_le_t,
255			    au.ma64_pvm.msi_addr_hi),
256			    4, &addr32);
257
258			msi_cap->address = ((u64) addr32) << 32;
259
260			(void) __hal_vpath_pci_read(hldev,
261			    hldev->first_vp_id,
262			    hldev->pci_caps.msi_cap_offset +
263			    vxge_offsetof(vxge_hal_msi_capability_le_t,
264			    au.ma64_pvm.msi_addr_lo),
265			    4, &addr32);
266
267			msi_cap->address |= (u64) addr32;
268
269			(void) __hal_vpath_pci_read(hldev,
270			    hldev->first_vp_id,
271			    hldev->pci_caps.msi_cap_offset +
272			    vxge_offsetof(vxge_hal_msi_capability_le_t,
273			    au.ma64_pvm.msi_data),
274			    2, &msi_cap->data);
275
276			(void) __hal_vpath_pci_read(hldev,
277			    hldev->first_vp_id,
278			    hldev->pci_caps.msi_cap_offset +
279			    vxge_offsetof(vxge_hal_msi_capability_le_t,
280			    au.ma64_pvm.msi_mask),
281			    4, &msi_cap->mask_bits);
282
283			(void) __hal_vpath_pci_read(hldev,
284			    hldev->first_vp_id,
285			    hldev->pci_caps.msi_cap_offset +
286			    vxge_offsetof(vxge_hal_msi_capability_le_t,
287			    au.ma64_pvm.msi_pending),
288			    4, &msi_cap->pending_bits);
289		} else {
290			(void) __hal_vpath_pci_read(hldev,
291			    hldev->first_vp_id,
292			    hldev->pci_caps.msi_cap_offset +
293			    vxge_offsetof(vxge_hal_msi_capability_le_t,
294			    au.ma64_no_pvm.msi_addr_hi),
295			    4, &addr32);
296
297			msi_cap->address = ((u64) addr32) << 32;
298
299			(void) __hal_vpath_pci_read(hldev,
300			    hldev->first_vp_id,
301			    hldev->pci_caps.msi_cap_offset +
302			    vxge_offsetof(vxge_hal_msi_capability_le_t,
303			    au.ma64_no_pvm.msi_addr_lo),
304			    4, &addr32);
305
306			msi_cap->address |= (u64) addr32;
307
308			(void) __hal_vpath_pci_read(hldev,
309			    hldev->first_vp_id,
310			    hldev->pci_caps.msi_cap_offset +
311			    vxge_offsetof(vxge_hal_msi_capability_le_t,
312			    au.ma64_no_pvm.msi_data),
313			    2, &msi_cap->data);
314
315		}
316	} else {
317		if (msi_cap->is_pvm_capable) {
318			(void) __hal_vpath_pci_read(hldev,
319			    hldev->first_vp_id,
320			    hldev->pci_caps.msi_cap_offset +
321			    vxge_offsetof(vxge_hal_msi_capability_le_t,
322			    au.ma32_pvm.msi_addr),
323			    4, &addr32);
324
325			msi_cap->address = (u64) addr32;
326
327			(void) __hal_vpath_pci_read(hldev,
328			    hldev->first_vp_id,
329			    hldev->pci_caps.msi_cap_offset +
330			    vxge_offsetof(vxge_hal_msi_capability_le_t,
331			    au.ma32_pvm.msi_data),
332			    2, &msi_cap->data);
333
334			(void) __hal_vpath_pci_read(hldev,
335			    hldev->first_vp_id,
336			    hldev->pci_caps.msi_cap_offset +
337			    vxge_offsetof(vxge_hal_msi_capability_le_t,
338			    au.ma32_pvm.msi_mask),
339			    4, &msi_cap->mask_bits);
340
341			(void) __hal_vpath_pci_read(hldev,
342			    hldev->first_vp_id,
343			    hldev->pci_caps.msi_cap_offset +
344			    vxge_offsetof(vxge_hal_msi_capability_le_t,
345			    au.ma32_pvm.msi_pending),
346			    4, &msi_cap->pending_bits);
347
348		} else {
349			(void) __hal_vpath_pci_read(hldev,
350			    hldev->first_vp_id,
351			    hldev->pci_caps.msi_cap_offset +
352			    vxge_offsetof(vxge_hal_msi_capability_le_t,
353			    au.ma32_no_pvm.msi_addr),
354			    4, &addr32);
355
356			msi_cap->address = (u64) addr32;
357
358			(void) __hal_vpath_pci_read(hldev,
359			    hldev->first_vp_id,
360			    hldev->pci_caps.msi_cap_offset +
361			    vxge_offsetof(vxge_hal_msi_capability_le_t,
362			    au.ma32_no_pvm.msi_data),
363			    2, &msi_cap->data);
364		}
365	}
366
367	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
368	    __FILE__, __func__, __LINE__);
369	return (VXGE_HAL_OK);
370}
371
372/*
373 * vxge_hal_mgmt_msi_capabilities_set - Sets the msi capabilities
374 * @devh: HAL device handle.
375 * @msi_cap: MSI Capabilities
376 *
377 * Sets the msi capabilities
378 */
379vxge_hal_status_e
380vxge_hal_mgmt_msi_capabilities_set(vxge_hal_device_h devh,
381    vxge_hal_mgmt_msi_cap_t *msi_cap)
382{
383	u16 msi_control_reg;
384	u32 addr32;
385	__hal_device_t *hldev = (__hal_device_t *) devh;
386
387	vxge_assert((hldev != NULL) && (msi_cap != NULL));
388
389	vxge_hal_trace_log_device("==> %s:%s:%d",
390	    __FILE__, __func__, __LINE__);
391
392	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT","
393	    "msi_cap = 0x"VXGE_OS_STXFMT, (ptr_t) hldev, (ptr_t) msi_cap);
394
395	if (hldev->pci_caps.msi_cap_offset == 0) {
396		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
397		    __FILE__, __func__, __LINE__, VXGE_HAL_FAIL);
398		return (VXGE_HAL_FAIL);
399	}
400
401	(void) __hal_vpath_pci_read(hldev,
402	    hldev->first_vp_id,
403	    hldev->pci_caps.msi_cap_offset +
404	    vxge_offsetof(vxge_hal_msi_capability_le_t, msi_control),
405	    2, &msi_control_reg);
406
407	if (msi_cap->enable)
408		msi_control_reg |= VXGE_HAL_PCI_MSI_FLAGS_ENABLE;
409	else
410		msi_control_reg &= ~VXGE_HAL_PCI_MSI_FLAGS_ENABLE;
411
412	if (msi_cap->vectors_allocated >
413	    (u32) ((msi_control_reg & VXGE_HAL_PCI_MSI_FLAGS_QMASK) >> 1)) {
414		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
415		    __FILE__, __func__, __LINE__, VXGE_HAL_FAIL);
416		return (VXGE_HAL_FAIL);
417	}
418
419	msi_control_reg &= ~VXGE_HAL_PCI_MSI_FLAGS_QSIZE;
420
421	msi_control_reg |= (msi_cap->vectors_allocated & 0x7) << 4;
422
423	if (msi_control_reg & VXGE_HAL_PCI_MSI_FLAGS_64BIT) {
424		if (msi_control_reg & VXGE_HAL_PCI_MSI_FLAGS_PVMASK) {
425
426			addr32 = (u32) (msi_cap->address >> 32);
427
428			vxge_os_pci_write32(hldev->header.pdev,
429			    hldev->header.cfgh,
430			    hldev->pci_caps.msi_cap_offset +
431			    vxge_offsetof(vxge_hal_msi_capability_le_t,
432			    au.ma64_pvm.msi_addr_hi), addr32);
433
434			addr32 = (u32) msi_cap->address;
435
436			vxge_os_pci_write32(hldev->header.pdev,
437			    hldev->header.cfgh,
438			    hldev->pci_caps.msi_cap_offset +
439			    vxge_offsetof(vxge_hal_msi_capability_le_t,
440			    au.ma64_pvm.msi_addr_lo), addr32);
441
442			vxge_os_pci_write16(hldev->header.pdev,
443			    hldev->header.cfgh,
444			    hldev->pci_caps.msi_cap_offset +
445			    vxge_offsetof(vxge_hal_msi_capability_le_t,
446			    au.ma64_pvm.msi_data), msi_cap->data);
447
448			vxge_os_pci_write32(hldev->header.pdev,
449			    hldev->header.cfgh,
450			    hldev->pci_caps.msi_cap_offset +
451			    vxge_offsetof(vxge_hal_msi_capability_le_t,
452			    au.ma64_pvm.msi_mask), msi_cap->mask_bits);
453
454			vxge_os_pci_write32(hldev->header.pdev,
455			    hldev->header.cfgh,
456			    hldev->pci_caps.msi_cap_offset +
457			    vxge_offsetof(vxge_hal_msi_capability_le_t,
458			    au.ma64_pvm.msi_pending), msi_cap->pending_bits);
459		} else {
460			addr32 = (u32) (msi_cap->address >> 32);
461
462			vxge_os_pci_write32(hldev->header.pdev,
463			    hldev->header.cfgh,
464			    hldev->pci_caps.msi_cap_offset +
465			    vxge_offsetof(vxge_hal_msi_capability_le_t,
466			    au.ma64_no_pvm.msi_addr_hi), addr32);
467
468			addr32 = (u32) msi_cap->address;
469
470			vxge_os_pci_write32(hldev->header.pdev,
471			    hldev->header.cfgh,
472			    hldev->pci_caps.msi_cap_offset +
473			    vxge_offsetof(vxge_hal_msi_capability_le_t,
474			    au.ma64_no_pvm.msi_addr_lo), addr32);
475
476			vxge_os_pci_write16(hldev->header.pdev,
477			    hldev->header.cfgh,
478			    hldev->pci_caps.msi_cap_offset +
479			    vxge_offsetof(vxge_hal_msi_capability_le_t,
480			    au.ma64_no_pvm.msi_data), msi_cap->data);
481
482		}
483	} else {
484		if (msi_control_reg & VXGE_HAL_PCI_MSI_FLAGS_PVMASK) {
485
486			addr32 = (u32) msi_cap->address;
487
488			vxge_os_pci_write32(hldev->header.pdev,
489			    hldev->header.cfgh,
490			    hldev->pci_caps.msi_cap_offset +
491			    vxge_offsetof(vxge_hal_msi_capability_le_t,
492			    au.ma32_pvm.msi_addr), addr32);
493
494			vxge_os_pci_write16(hldev->header.pdev,
495			    hldev->header.cfgh,
496			    hldev->pci_caps.msi_cap_offset +
497			    vxge_offsetof(vxge_hal_msi_capability_le_t,
498			    au.ma32_pvm.msi_data), msi_cap->data);
499
500			vxge_os_pci_write32(hldev->header.pdev,
501			    hldev->header.cfgh,
502			    hldev->pci_caps.msi_cap_offset +
503			    vxge_offsetof(vxge_hal_msi_capability_le_t,
504			    au.ma32_pvm.msi_mask), msi_cap->mask_bits);
505
506			vxge_os_pci_write32(hldev->header.pdev,
507			    hldev->header.cfgh,
508			    hldev->pci_caps.msi_cap_offset +
509			    vxge_offsetof(vxge_hal_msi_capability_le_t,
510			    au.ma32_pvm.msi_pending), msi_cap->pending_bits);
511
512		} else {
513			addr32 = (u32) msi_cap->address;
514
515			vxge_os_pci_write32(hldev->header.pdev,
516			    hldev->header.cfgh,
517			    hldev->pci_caps.msi_cap_offset +
518			    vxge_offsetof(vxge_hal_msi_capability_le_t,
519			    au.ma32_no_pvm.msi_addr), addr32);
520
521			vxge_os_pci_write16(hldev->header.pdev,
522			    hldev->header.cfgh,
523			    hldev->pci_caps.msi_cap_offset +
524			    vxge_offsetof(vxge_hal_msi_capability_le_t,
525			    au.ma32_no_pvm.msi_data), msi_cap->data);
526		}
527	}
528
529	vxge_os_pci_write16(hldev->header.pdev, hldev->header.cfgh,
530	    hldev->pci_caps.msi_cap_offset +
531	    vxge_offsetof(vxge_hal_msi_capability_le_t, msi_control),
532	    msi_control_reg);
533
534	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
535	    __FILE__, __func__, __LINE__);
536
537	return (VXGE_HAL_OK);
538}
539
540/*
541 * vxge_hal_mgmt_msix_capabilities_get - Returns the msix capabilities
542 * @devh: HAL device handle.
543 * @msix_cap: MSIX Capabilities
544 *
545 * Return the msix capabilities
546 */
547vxge_hal_status_e
548vxge_hal_mgmt_msix_capabilities_get(vxge_hal_device_h devh,
549    vxge_hal_mgmt_msix_cap_t *msix_cap)
550{
551	u16 msix_control_reg;
552	u32 msix_offset;
553	__hal_device_t *hldev = (__hal_device_t *) devh;
554
555	vxge_assert((hldev != NULL) && (msix_cap != NULL));
556
557	vxge_hal_trace_log_device("==> %s:%s:%d",
558	    __FILE__, __func__, __LINE__);
559
560	vxge_hal_trace_log_device(
561	    "hldev = 0x"VXGE_OS_STXFMT", msix_cap = 0x"VXGE_OS_STXFMT,
562	    (ptr_t) hldev, (ptr_t) msix_cap);
563
564	if (hldev->pci_caps.msix_cap_offset == 0) {
565		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
566		    __FILE__, __func__, __LINE__, VXGE_HAL_FAIL);
567		return (VXGE_HAL_FAIL);
568	}
569
570	vxge_os_memzero(msix_cap, sizeof(vxge_hal_mgmt_msix_cap_t));
571
572	(void) __hal_vpath_pci_read(hldev,
573	    hldev->first_vp_id,
574	    hldev->pci_caps.msix_cap_offset +
575	    vxge_offsetof(vxge_hal_msix_capability_le_t, msix_control),
576	    2, &msix_control_reg);
577
578	if (msix_control_reg & VXGE_HAL_PCI_MSIX_FLAGS_ENABLE)
579		msix_cap->enable = 1;
580
581	if (msix_control_reg & VXGE_HAL_PCI_MSIX_FLAGS_MASK)
582		msix_cap->mask_all_vect = 1;
583
584	msix_cap->table_size =
585	    (msix_control_reg & VXGE_HAL_PCI_MSIX_FLAGS_TSIZE) + 1;
586
587	(void) __hal_vpath_pci_read(hldev,
588	    hldev->first_vp_id,
589	    hldev->pci_caps.msix_cap_offset +
590	    vxge_offsetof(vxge_hal_msix_capability_le_t, table_offset),
591	    4, &msix_offset);
592
593	msix_cap->table_offset =
594	    (msix_offset & VXGE_HAL_PCI_MSIX_TABLE_OFFSET) >> 3;
595
596	msix_cap->table_bir = msix_offset & VXGE_HAL_PCI_MSIX_TABLE_BIR;
597
598	(void) __hal_vpath_pci_read(hldev,
599	    hldev->first_vp_id,
600	    hldev->pci_caps.msix_cap_offset +
601	    vxge_offsetof(vxge_hal_msix_capability_le_t, pba_offset),
602	    4, &msix_offset);
603
604	msix_cap->pba_offset =
605	    (msix_offset & VXGE_HAL_PCI_MSIX_PBA_OFFSET) >> 3;
606
607	msix_cap->pba_bir = msix_offset & VXGE_HAL_PCI_MSIX_PBA_BIR;
608
609	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
610	    __FILE__, __func__, __LINE__);
611	return (VXGE_HAL_OK);
612}
613
614/*
615 * vxge_hal_mgmt_pm_capabilities_get - Returns the pm capabilities
616 * @devh: HAL device handle.
617 * @pm_cap: pm Capabilities
618 *
619 * Return the pm capabilities
620 */
621vxge_hal_status_e
622vxge_hal_mgmt_pm_capabilities_get(vxge_hal_device_h devh,
623    vxge_hal_mgmt_pm_cap_t *pm_cap)
624{
625	u16 pm_cap_reg;
626	u16 pm_control_reg;
627	u8 pm_ppb_ext;
628	u8 pm_data_reg;
629	__hal_device_t *hldev = (__hal_device_t *) devh;
630
631	vxge_assert((hldev != NULL) && (pm_cap != NULL));
632
633	vxge_hal_trace_log_device("==> %s:%s:%d",
634	    __FILE__, __func__, __LINE__);
635
636	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT", "
637	    "pm_cap = 0x"VXGE_OS_STXFMT, (ptr_t) hldev, (ptr_t) pm_cap);
638
639	if (hldev->pci_caps.pm_cap_offset == 0) {
640		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
641		    __FILE__, __func__, __LINE__, VXGE_HAL_FAIL);
642		return (VXGE_HAL_FAIL);
643	}
644
645	vxge_os_memzero(pm_cap, sizeof(vxge_hal_mgmt_pm_cap_t));
646
647	(void) __hal_vpath_pci_read(hldev,
648	    hldev->first_vp_id,
649	    hldev->pci_caps.pm_cap_offset +
650	    vxge_offsetof(vxge_hal_pm_capability_le_t, capabilities_reg),
651	    2, &pm_cap_reg);
652
653	pm_cap->pm_cap_ver =
654	    (u32) (pm_cap_reg & VXGE_HAL_PCI_PM_CAP_VER_MASK);
655
656	if (pm_cap_reg & VXGE_HAL_PCI_PM_CAP_PME_CLOCK)
657		pm_cap->pm_cap_pme_clock = 1;
658
659	if (pm_cap_reg & VXGE_HAL_PCI_PM_CAP_AUX_POWER)
660		pm_cap->pm_cap_aux_power = 1;
661
662	if (pm_cap_reg & VXGE_HAL_PCI_PM_CAP_DSI)
663		pm_cap->pm_cap_dsi = 1;
664
665	if (pm_cap_reg & VXGE_HAL_PCI_PM_AUX_CURRENT)
666		pm_cap->pm_cap_aux_current = 1;
667
668	if (pm_cap_reg & VXGE_HAL_PCI_PM_CAP_D1)
669		pm_cap->pm_cap_cap_d0 = 1;
670
671	if (pm_cap_reg & VXGE_HAL_PCI_PM_CAP_D2)
672		pm_cap->pm_cap_cap_d1 = 1;
673
674	if (pm_cap_reg & VXGE_HAL_PCI_PM_CAP_PME_D0)
675		pm_cap->pm_cap_pme_d0 = 1;
676
677	if (pm_cap_reg & VXGE_HAL_PCI_PM_CAP_PME_D1)
678		pm_cap->pm_cap_pme_d1 = 1;
679
680	if (pm_cap_reg & VXGE_HAL_PCI_PM_CAP_PME_D2)
681		pm_cap->pm_cap_pme_d2 = 1;
682
683	if (pm_cap_reg & VXGE_HAL_PCI_PM_CAP_PME_D3_HOT)
684		pm_cap->pm_cap_pme_d3_hot = 1;
685
686	if (pm_cap_reg & VXGE_HAL_PCI_PM_CAP_PME_D3_COLD)
687		pm_cap->pm_cap_pme_d3_cold = 1;
688
689	(void) __hal_vpath_pci_read(hldev,
690	    hldev->first_vp_id,
691	    hldev->pci_caps.pm_cap_offset +
692	    vxge_offsetof(vxge_hal_pm_capability_le_t, pm_ctrl),
693	    2, &pm_control_reg);
694
695	pm_cap->pm_ctrl_state =
696	    pm_control_reg & VXGE_HAL_PCI_PM_CTRL_STATE_MASK;
697
698	if (pm_cap_reg & VXGE_HAL_PCI_PM_CTRL_NO_SOFT_RESET)
699		pm_cap->pm_ctrl_no_soft_reset = 1;
700
701	if (pm_cap_reg & VXGE_HAL_PCI_PM_CTRL_PME_ENABLE)
702		pm_cap->pm_ctrl_pme_enable = 1;
703
704	pm_cap->pm_ctrl_pme_data_sel =
705	    (u32) (pm_control_reg & VXGE_HAL_PCI_PM_CTRL_DATA_SEL_MASK) >> 10;
706
707	pm_cap->pm_ctrl_pme_data_scale =
708	    (u32) (pm_control_reg & VXGE_HAL_PCI_PM_CTRL_DATA_SCALE_MASK) >> 13;
709
710	if (pm_cap_reg & VXGE_HAL_PCI_PM_CTRL_PME_STATUS)
711		pm_cap->pm_ctrl_pme_status = 1;
712
713	(void) __hal_vpath_pci_read(hldev,
714	    hldev->first_vp_id,
715	    hldev->pci_caps.pm_cap_offset +
716	    vxge_offsetof(vxge_hal_pm_capability_le_t, pm_ctrl),
717	    1, &pm_ppb_ext);
718
719	if (pm_ppb_ext & VXGE_HAL_PCI_PM_PPB_B2_B3)
720		pm_cap->pm_ppb_ext_b2_b3 = 1;
721
722	if (pm_ppb_ext & VXGE_HAL_PCI_PM_BPCC_ENABLE)
723		pm_cap->pm_ppb_ext_ecc_en = 1;
724
725	(void) __hal_vpath_pci_read(hldev,
726	    hldev->first_vp_id,
727	    hldev->pci_caps.pm_cap_offset +
728	    vxge_offsetof(vxge_hal_pm_capability_le_t, pm_data_reg),
729	    1, &pm_data_reg);
730
731	pm_cap->pm_data_reg = (u32) pm_data_reg;
732
733	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
734	    __FILE__, __func__, __LINE__);
735	return (VXGE_HAL_OK);
736}
737
738/*
739 * vxge_hal_mgmt_sid_capabilities_get - Returns the sid capabilities
740 * @devh: HAL device handle.
741 * @sid_cap: Slot Id Capabilities
742 *
743 * Return the Slot Id capabilities
744 */
745vxge_hal_status_e
746vxge_hal_mgmt_sid_capabilities_get(vxge_hal_device_h devh,
747    vxge_hal_mgmt_sid_cap_t *sid_cap)
748{
749	u8 chasis_num_reg;
750	u8 slot_num_reg;
751	__hal_device_t *hldev = (__hal_device_t *) devh;
752
753	vxge_assert((hldev != NULL) && (sid_cap != NULL));
754
755	vxge_hal_trace_log_device("==> %s:%s:%d",
756	    __FILE__, __func__, __LINE__);
757
758	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT
759	    ", sid_cap = 0x"VXGE_OS_STXFMT, (ptr_t) hldev, (ptr_t) sid_cap);
760
761	if (hldev->pci_caps.sid_cap_offset == 0) {
762		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
763		    __FILE__, __func__, __LINE__, VXGE_HAL_FAIL);
764		return (VXGE_HAL_FAIL);
765	}
766
767	vxge_os_memzero(sid_cap, sizeof(vxge_hal_mgmt_sid_cap_t));
768
769	(void) __hal_vpath_pci_read(hldev,
770	    hldev->first_vp_id,
771	    hldev->pci_caps.sid_cap_offset +
772	    vxge_offsetof(vxge_hal_sid_capability_le_t, sid_esr),
773	    1, &slot_num_reg);
774
775	sid_cap->sid_number_of_slots =
776	    (u32) (slot_num_reg & VXGE_HAL_PCI_SID_ESR_NSLOTS);
777
778	if (slot_num_reg & VXGE_HAL_PCI_SID_ESR_FIC)
779		sid_cap->sid_number_of_slots = 1;
780
781	(void) __hal_vpath_pci_read(hldev,
782	    hldev->first_vp_id,
783	    hldev->pci_caps.sid_cap_offset +
784	    vxge_offsetof(vxge_hal_sid_capability_le_t, sid_chasis_nr),
785	    1, &chasis_num_reg);
786
787	sid_cap->sid_chasis_number = (u32) chasis_num_reg;
788
789	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
790	    __FILE__, __func__, __LINE__);
791
792	return (VXGE_HAL_OK);
793}
794
795/*
796 * vxge_hal_mgmt_pci_err_capabilities_get - Returns the pci error capabilities
797 * @devh: HAL device handle.
798 * @err_cap: PCI-E Extended Error Capabilities
799 *
800 * Return the PCI-E Extended Error capabilities
801 */
802vxge_hal_status_e
803vxge_hal_mgmt_pci_err_capabilities_get(vxge_hal_device_h devh,
804    vxge_hal_pci_err_cap_t *err_cap)
805{
806	__hal_device_t *hldev = (__hal_device_t *) devh;
807
808	vxge_assert((hldev != NULL) && (err_cap != NULL));
809
810	vxge_hal_trace_log_device("==> %s:%s:%d",
811	    __FILE__, __func__, __LINE__);
812
813	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT
814	    ",sid_cap = 0x"VXGE_OS_STXFMT, (ptr_t) hldev, (ptr_t) err_cap);
815
816	if (hldev->pci_e_ext_caps.err_cap_offset == 0) {
817		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
818		    __FILE__, __func__, __LINE__, VXGE_HAL_FAIL);
819		return (VXGE_HAL_FAIL);
820	}
821
822	vxge_os_memzero(err_cap, sizeof(vxge_hal_pci_err_cap_t));
823
824	(void) __hal_vpath_pci_read(hldev,
825	    hldev->first_vp_id,
826	    hldev->pci_e_ext_caps.err_cap_offset +
827	    vxge_offsetof(vxge_hal_err_capability_t, pci_err_header),
828	    4,
829	    &err_cap->pci_err_header);
830
831	(void) __hal_vpath_pci_read(hldev,
832	    hldev->first_vp_id,
833	    hldev->pci_e_ext_caps.err_cap_offset +
834	    vxge_offsetof(vxge_hal_err_capability_t, pci_err_uncor_status),
835	    4,
836	    &err_cap->pci_err_uncor_status);
837
838	(void) __hal_vpath_pci_read(hldev,
839	    hldev->first_vp_id,
840	    hldev->pci_e_ext_caps.err_cap_offset +
841	    vxge_offsetof(vxge_hal_err_capability_t, pci_err_uncor_mask),
842	    4,
843	    &err_cap->pci_err_uncor_mask);
844
845	(void) __hal_vpath_pci_read(hldev,
846	    hldev->first_vp_id,
847	    hldev->pci_e_ext_caps.err_cap_offset +
848	    vxge_offsetof(vxge_hal_err_capability_t, pci_err_uncor_server),
849	    4,
850	    &err_cap->pci_err_uncor_server);
851
852	(void) __hal_vpath_pci_read(hldev,
853	    hldev->first_vp_id,
854	    hldev->pci_e_ext_caps.err_cap_offset +
855	    vxge_offsetof(vxge_hal_err_capability_t, pci_err_cor_status),
856	    4,
857	    &err_cap->pci_err_cor_status);
858
859	(void) __hal_vpath_pci_read(hldev,
860	    hldev->first_vp_id,
861	    hldev->pci_e_ext_caps.err_cap_offset +
862	    vxge_offsetof(vxge_hal_err_capability_t, pci_err_cap),
863	    4,
864	    &err_cap->pci_err_cap);
865
866	(void) __hal_vpath_pci_read(hldev,
867	    hldev->first_vp_id,
868	    hldev->pci_e_ext_caps.err_cap_offset +
869	    vxge_offsetof(vxge_hal_err_capability_t, err_header_log),
870	    4,
871	    &err_cap->err_header_log);
872
873	(void) __hal_vpath_pci_read(hldev,
874	    hldev->first_vp_id,
875	    hldev->pci_e_ext_caps.err_cap_offset +
876	    vxge_offsetof(vxge_hal_err_capability_t, pci_err_root_command),
877	    4,
878	    &err_cap->pci_err_root_command);
879
880	(void) __hal_vpath_pci_read(hldev,
881	    hldev->first_vp_id,
882	    hldev->pci_e_ext_caps.err_cap_offset +
883	    vxge_offsetof(vxge_hal_err_capability_t, pci_err_root_status),
884	    4,
885	    &err_cap->pci_err_root_status);
886
887	(void) __hal_vpath_pci_read(hldev,
888	    hldev->first_vp_id,
889	    hldev->pci_e_ext_caps.err_cap_offset +
890	    vxge_offsetof(vxge_hal_err_capability_t, pci_err_root_cor_src),
891	    4,
892	    &err_cap->pci_err_root_cor_src);
893
894	(void) __hal_vpath_pci_read(hldev,
895	    hldev->first_vp_id,
896	    hldev->pci_e_ext_caps.err_cap_offset +
897	    vxge_offsetof(vxge_hal_err_capability_t, pci_err_root_src),
898	    4,
899	    &err_cap->pci_err_root_src);
900
901	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
902	    __FILE__, __func__, __LINE__);
903
904	return (VXGE_HAL_OK);
905}
906
907/*
908 * vxge_hal_mgmt_driver_config - Retrieve driver configuration.
909 * @drv_config: Device configuration, see vxge_hal_driver_config_t {}.
910 * @size: Pointer to buffer containing the Size of the @drv_config.
911 * HAL will return an error if the size is smaller than
912 * sizeof(vxge_hal_driver_config_t) and returns required size in this field
913 *
914 * Get driver configuration. Permits to retrieve at run-time configuration
915 * values that were used to configure the device at load-time.
916 *
917 * Returns: VXGE_HAL_OK - success.
918 * VXGE_HAL_ERR_DRIVER_NOT_INITIALIZED - HAL is not initialized.
919 * VXGE_HAL_ERR_VERSION_CONFLICT - Version is not maching.
920 * VXGE_HAL_ERR_OUT_OF_SPACE - If the buffer is not sufficient
921 *
922 * See also: vxge_hal_driver_config_t {}, vxge_hal_mgmt_device_config().
923 */
924vxge_hal_status_e
925vxge_hal_mgmt_driver_config(vxge_hal_driver_config_t *drv_config, u32 *size)
926{
927
928	vxge_assert((drv_config != NULL) && (size != NULL));
929
930	vxge_hal_trace_log_driver("==> %s:%s:%d",
931	    __FILE__, __func__, __LINE__);
932
933	vxge_hal_trace_log_driver(
934	    "drv_config = 0x"VXGE_OS_STXFMT", size = 0x"VXGE_OS_STXFMT,
935	    (ptr_t) drv_config, (ptr_t) size);
936
937	if (g_vxge_hal_driver == NULL) {
938		vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
939		    __FILE__, __func__, __LINE__,
940		    VXGE_HAL_ERR_DRIVER_NOT_INITIALIZED);
941		return (VXGE_HAL_ERR_DRIVER_NOT_INITIALIZED);
942	}
943
944	if (*size < sizeof(vxge_hal_driver_config_t)) {
945		*size = sizeof(vxge_hal_driver_config_t);
946		vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
947		    __FILE__, __func__, __LINE__,
948		    VXGE_HAL_ERR_OUT_OF_SPACE);
949		return (VXGE_HAL_ERR_OUT_OF_SPACE);
950	}
951
952	vxge_os_memcpy(drv_config, &g_vxge_hal_driver->config,
953	    sizeof(vxge_hal_driver_config_t));
954
955	*size = sizeof(vxge_hal_driver_config_t);
956
957	vxge_hal_trace_log_driver("<== %s:%s:%d Result = 0",
958	    __FILE__, __func__, __LINE__);
959
960	return (VXGE_HAL_OK);
961}
962
963
964/*
965 * vxge_hal_mgmt_device_config - Retrieve device configuration.
966 * @devh: HAL device handle.
967 * @dev_config: Device configuration, see vxge_hal_device_config_t {}.
968 * @size: Pointer to buffer containing the Size of the @dev_config.
969 * HAL will return an error if the size is smaller than
970 * sizeof(vxge_hal_device_config_t) and returns required size in this field
971 *
972 * Get device configuration. Permits to retrieve at run-time configuration
973 * values that were used to initialize and configure the device.
974 *
975 * Returns: VXGE_HAL_OK - success.
976 * VXGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
977 * VXGE_HAL_ERR_VERSION_CONFLICT - Version it not maching.
978 * VXGE_HAL_ERR_OUT_OF_SPACE - If the buffer is not sufficient
979 *
980 * See also: vxge_hal_device_config_t {}, vxge_hal_mgmt_driver_config().
981 */
982vxge_hal_status_e
983vxge_hal_mgmt_device_config(vxge_hal_device_h devh,
984    vxge_hal_device_config_t *dev_config, u32 *size)
985{
986	vxge_hal_device_t *hldev = (vxge_hal_device_t *) devh;
987
988	vxge_assert((devh != NULL) && (dev_config != NULL) && (size != NULL));
989
990	vxge_hal_trace_log_device("==> %s:%s:%d",
991	    __FILE__, __func__, __LINE__);
992
993	vxge_hal_trace_log_device(
994	    "devh = 0x"VXGE_OS_STXFMT", dev_config = 0x"VXGE_OS_STXFMT", "
995	    "size = 0x"VXGE_OS_STXFMT, (ptr_t) devh, (ptr_t) dev_config,
996	    (ptr_t) size);
997
998	if (hldev->magic != VXGE_HAL_DEVICE_MAGIC) {
999		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1000		    __FILE__, __func__, __LINE__,
1001		    VXGE_HAL_ERR_INVALID_DEVICE);
1002		return (VXGE_HAL_ERR_INVALID_DEVICE);
1003	}
1004
1005	if (*size < sizeof(vxge_hal_device_config_t)) {
1006		*size = sizeof(vxge_hal_device_config_t);
1007		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1008		    __FILE__, __func__, __LINE__,
1009		    VXGE_HAL_ERR_OUT_OF_SPACE);
1010		return (VXGE_HAL_ERR_OUT_OF_SPACE);
1011	}
1012
1013	vxge_os_memcpy(dev_config, &hldev->config,
1014	    sizeof(vxge_hal_device_config_t));
1015
1016	*size = sizeof(vxge_hal_device_config_t);
1017
1018	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
1019	    __FILE__, __func__, __LINE__);
1020
1021	return (VXGE_HAL_OK);
1022}
1023
1024/*
1025 * vxge_hal_mgmt_pcireg_read - Read PCI configuration at a specified
1026 * offset.
1027 * @devh: HAL device handle.
1028 * @offset: Offset in the 256 byte PCI configuration space.
1029 * @value_bits: 8, 16, or 32 (bits) to read.
1030 * @value: Value returned by HAL.
1031 *
1032 * Read PCI configuration, given device and offset in the PCI space.
1033 *
1034 * Returns: VXGE_HAL_OK - success.
1035 * VXGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
1036 * VXGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not
1037 * valid.
1038 * VXGE_HAL_ERR_INVALID_VALUE_BIT_SIZE - Invalid bits size. Valid
1039 * values(8/16/32).
1040 *
1041 */
1042vxge_hal_status_e
1043vxge_hal_mgmt_pcireg_read(vxge_hal_device_h devh, unsigned int offset,
1044    int value_bits, u32 *value)
1045{
1046	__hal_device_t *hldev = (__hal_device_t *) devh;
1047
1048	vxge_assert((devh != NULL) && (value != NULL));
1049
1050	vxge_hal_trace_log_device("==> %s:%s:%d",
1051	    __FILE__, __func__, __LINE__);
1052
1053	vxge_hal_trace_log_device(
1054	    "devh = 0x"VXGE_OS_STXFMT", offset = %d, value_bits = %d, "
1055	    "value = 0x"VXGE_OS_STXFMT, (ptr_t) devh, offset,
1056	    value_bits, (ptr_t) value);
1057
1058	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
1059		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1060		    __FILE__, __func__, __LINE__,
1061		    VXGE_HAL_ERR_INVALID_DEVICE);
1062		return (VXGE_HAL_ERR_INVALID_DEVICE);
1063	}
1064
1065	if (offset > sizeof(vxge_hal_pci_config_t) - value_bits / 8) {
1066		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1067		    __FILE__, __func__, __LINE__,
1068		    VXGE_HAL_ERR_INVALID_DEVICE);
1069		return (VXGE_HAL_ERR_INVALID_OFFSET);
1070	}
1071
1072	(void) __hal_vpath_pci_read(hldev,
1073	    hldev->first_vp_id,
1074	    offset,
1075	    value_bits / 8,
1076	    value);
1077
1078	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
1079	    __FILE__, __func__, __LINE__);
1080
1081	return (VXGE_HAL_OK);
1082}
1083
1084/*
1085 * vxge_hal_mgmt_reg_read - Read X3100 register.
1086 * @devh: HAL device handle.
1087 * @type: Register types as defined in enum vxge_hal_mgmt_reg_type_e {}
1088 * @Index: For pcicfgmgmt, srpcim, vpmgmt, vpath this gives the Index
1089 *		ignored for others
1090 * @offset: Register offset in the register space qualified by the type and
1091 *		index.
1092 * @value: Register value. Returned by HAL.
1093 * Read X3100 register.
1094 *
1095 * Returns: VXGE_HAL_OK - success.
1096 * VXGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
1097 * VXGE_HAL_ERR_INVALID_TYPE - Type is not valid.
1098 * VXGE_HAL_ERR_INVALID_INDEX - Index is not valid.
1099 * VXGE_HAL_ERR_INVALID_OFFSET - Register offset in the space is not valid.
1100 *
1101 */
1102vxge_hal_status_e
1103vxge_hal_mgmt_reg_read(vxge_hal_device_h devh,
1104    vxge_hal_mgmt_reg_type_e type,
1105    u32 vp_id,
1106    u32 offset,
1107    u64 *value)
1108{
1109	vxge_hal_status_e status = VXGE_HAL_OK;
1110	__hal_device_t *hldev = (__hal_device_t *) devh;
1111
1112	vxge_assert((devh != NULL) && (value != NULL));
1113
1114	vxge_hal_trace_log_device("==> %s:%s:%d",
1115	    __FILE__, __func__, __LINE__);
1116
1117	vxge_hal_trace_log_device(
1118	    "devh = 0x"VXGE_OS_STXFMT", type = %d, "
1119	    "vp_id = %d, offset = %d, value = 0x"VXGE_OS_STXFMT,
1120	    (ptr_t) devh, type, vp_id, offset, (ptr_t) value);
1121
1122	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
1123		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1124		    __FILE__, __func__, __LINE__,
1125		    VXGE_HAL_ERR_INVALID_DEVICE);
1126		return (VXGE_HAL_ERR_INVALID_DEVICE);
1127	}
1128
1129	switch (type) {
1130	case vxge_hal_mgmt_reg_type_legacy:
1131		if (offset > sizeof(vxge_hal_legacy_reg_t) - 8) {
1132			status = VXGE_HAL_ERR_INVALID_OFFSET;
1133			break;
1134		}
1135		*value = vxge_os_pio_mem_read64(hldev->header.pdev,
1136		    hldev->header.regh0,
1137		    (void *)(((ptr_t) hldev->legacy_reg) + offset));
1138		break;
1139	case vxge_hal_mgmt_reg_type_toc:
1140		if (offset > sizeof(vxge_hal_toc_reg_t) - 8) {
1141			status = VXGE_HAL_ERR_INVALID_OFFSET;
1142			break;
1143		}
1144		*value = vxge_os_pio_mem_read64(hldev->header.pdev,
1145		    hldev->header.regh0,
1146		    (void *)(((ptr_t) hldev->toc_reg) + offset));
1147		break;
1148	case vxge_hal_mgmt_reg_type_common:
1149		if (offset > sizeof(vxge_hal_common_reg_t) - 8) {
1150			status = VXGE_HAL_ERR_INVALID_OFFSET;
1151			break;
1152		}
1153		*value = vxge_os_pio_mem_read64(hldev->header.pdev,
1154		    hldev->header.regh0,
1155		    (void *)(((ptr_t) hldev->common_reg) + offset));
1156		break;
1157	case vxge_hal_mgmt_reg_type_memrepair:
1158		if (!(hldev->access_rights &
1159		    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)) {
1160			status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
1161			break;
1162		}
1163		if (offset > sizeof(vxge_hal_memrepair_reg_t) - 8) {
1164			status = VXGE_HAL_ERR_INVALID_OFFSET;
1165			break;
1166		}
1167		*value = vxge_os_pio_mem_read64(hldev->header.pdev,
1168		    hldev->header.regh0,
1169		    (void *)(((ptr_t) hldev->memrepair_reg) + offset));
1170		break;
1171	case vxge_hal_mgmt_reg_type_pcicfgmgmt:
1172		if (!(hldev->access_rights &
1173		    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)) {
1174			status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
1175			break;
1176		}
1177		if (vp_id > VXGE_HAL_TITAN_PCICFGMGMT_REG_SPACES - 1) {
1178			status = VXGE_HAL_ERR_INVALID_INDEX;
1179			break;
1180		}
1181		if (offset > sizeof(vxge_hal_pcicfgmgmt_reg_t) - 8) {
1182			status = VXGE_HAL_ERR_INVALID_OFFSET;
1183			break;
1184		}
1185		*value = vxge_os_pio_mem_read64(hldev->header.pdev,
1186		    hldev->header.regh0,
1187		    (void *)(((ptr_t) hldev->pcicfgmgmt_reg[vp_id]) + offset));
1188		break;
1189	case vxge_hal_mgmt_reg_type_mrpcim:
1190		if (!(hldev->access_rights &
1191		    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)) {
1192			status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
1193			break;
1194		}
1195		if (offset > sizeof(vxge_hal_mrpcim_reg_t) - 8) {
1196			status = VXGE_HAL_ERR_INVALID_OFFSET;
1197			break;
1198		}
1199		*value = vxge_os_pio_mem_read64(hldev->header.pdev,
1200		    hldev->header.regh0,
1201		    (void *)(((ptr_t) hldev->mrpcim_reg) + offset));
1202		break;
1203	case vxge_hal_mgmt_reg_type_srpcim:
1204		if (!(hldev->access_rights &
1205		    VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM)) {
1206			status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
1207			break;
1208		}
1209		if (vp_id > VXGE_HAL_TITAN_SRPCIM_REG_SPACES - 1) {
1210			status = VXGE_HAL_ERR_INVALID_INDEX;
1211			break;
1212		}
1213		if (offset > sizeof(vxge_hal_srpcim_reg_t) - 8) {
1214			status = VXGE_HAL_ERR_INVALID_OFFSET;
1215			break;
1216		}
1217		*value = vxge_os_pio_mem_read64(hldev->header.pdev,
1218		    hldev->header.regh0,
1219		    (void *)(((ptr_t) hldev->srpcim_reg[vp_id]) + offset));
1220		break;
1221	case vxge_hal_mgmt_reg_type_vpmgmt:
1222		if ((vp_id > VXGE_HAL_TITAN_VPMGMT_REG_SPACES - 1) ||
1223		    (!(hldev->vpath_assignments & mBIT(vp_id)))) {
1224			status = VXGE_HAL_ERR_INVALID_INDEX;
1225			break;
1226		}
1227		if (offset > sizeof(vxge_hal_vpmgmt_reg_t) - 8) {
1228			status = VXGE_HAL_ERR_INVALID_OFFSET;
1229			break;
1230		}
1231		*value = vxge_os_pio_mem_read64(hldev->header.pdev,
1232		    hldev->header.regh0,
1233		    (void *)(((ptr_t) hldev->vpmgmt_reg[vp_id]) + offset));
1234		break;
1235	case vxge_hal_mgmt_reg_type_vpath:
1236		if ((vp_id > VXGE_HAL_TITAN_VPATH_REG_SPACES - 1) ||
1237		    (!(hldev->vpath_assignments & mBIT(vp_id)))) {
1238			status = VXGE_HAL_ERR_INVALID_INDEX;
1239			break;
1240		}
1241		if (vp_id > VXGE_HAL_TITAN_VPATH_REG_SPACES - 1) {
1242			status = VXGE_HAL_ERR_INVALID_INDEX;
1243			break;
1244		}
1245		if (offset > sizeof(vxge_hal_vpath_reg_t) - 8) {
1246			status = VXGE_HAL_ERR_INVALID_OFFSET;
1247			break;
1248		}
1249		*value = vxge_os_pio_mem_read64(hldev->header.pdev,
1250		    hldev->header.regh0,
1251		    (void *)(((ptr_t) hldev->vpath_reg[vp_id]) + offset));
1252		break;
1253	default:
1254		status = VXGE_HAL_ERR_INVALID_TYPE;
1255		break;
1256	}
1257
1258	vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1259	    __FILE__, __func__, __LINE__, status);
1260	return (status);
1261}
1262
1263/*
1264 * vxge_hal_mgmt_reg_Write - Write X3100 register.
1265 * @devh: HAL device handle.
1266 * @type: Register types as defined in enum vxge_hal_mgmt_reg_type_e {}
1267 * @index: For pcicfgmgmt, srpcim, vpmgmt, vpath this gives the Index
1268 *		ignored for others
1269 * @offset: Register offset in the register space qualified by the type and
1270 *		index.
1271 * @value: Register value to be written.
1272 * Write X3100 register.
1273 *
1274 * Returns: VXGE_HAL_OK - success.
1275 * VXGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
1276 * VXGE_HAL_ERR_INVALID_TYPE - Type is not valid.
1277 * VXGE_HAL_ERR_INVALID_INDEX - Index is not valid.
1278 * VXGE_HAL_ERR_INVALID_OFFSET - Register offset in the space is not valid.
1279 *
1280 */
1281vxge_hal_status_e
1282vxge_hal_mgmt_reg_write(vxge_hal_device_h devh,
1283    vxge_hal_mgmt_reg_type_e type,
1284    u32 vp_id,
1285    u32 offset,
1286    u64 value)
1287{
1288	vxge_hal_status_e status = VXGE_HAL_OK;
1289	__hal_device_t *hldev = (__hal_device_t *) devh;
1290
1291	vxge_assert(devh != NULL);
1292
1293	vxge_hal_trace_log_device("==> %s:%s:%d",
1294	    __FILE__, __func__, __LINE__);
1295
1296	vxge_hal_trace_log_device(
1297		"devh = 0x"VXGE_OS_STXFMT", type = %d, "
1298	    "index = %d, offset = %d, value = 0x"VXGE_OS_STXFMT,
1299	    (ptr_t) devh, type, vp_id, offset, (ptr_t) value);
1300
1301	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
1302		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1303		    __FILE__, __func__, __LINE__,
1304		    VXGE_HAL_ERR_INVALID_DEVICE);
1305
1306		return (VXGE_HAL_ERR_INVALID_DEVICE);
1307	}
1308
1309	switch (type) {
1310	case vxge_hal_mgmt_reg_type_legacy:
1311		if (offset > sizeof(vxge_hal_legacy_reg_t) - 8) {
1312			status = VXGE_HAL_ERR_INVALID_OFFSET;
1313			break;
1314		}
1315		vxge_os_pio_mem_write64(hldev->header.pdev,
1316		    hldev->header.regh0,
1317		    value,
1318		    (void *)(((ptr_t) hldev->legacy_reg) + offset));
1319		break;
1320	case vxge_hal_mgmt_reg_type_toc:
1321		if (offset > sizeof(vxge_hal_toc_reg_t) - 8) {
1322			status = VXGE_HAL_ERR_INVALID_OFFSET;
1323			break;
1324		}
1325		vxge_os_pio_mem_write64(hldev->header.pdev,
1326		    hldev->header.regh0,
1327		    value,
1328		    (void *)(((ptr_t) hldev->toc_reg) + offset));
1329		break;
1330	case vxge_hal_mgmt_reg_type_common:
1331		if (offset > sizeof(vxge_hal_common_reg_t) - 8) {
1332			status = VXGE_HAL_ERR_INVALID_OFFSET;
1333			break;
1334		}
1335		vxge_os_pio_mem_write64(hldev->header.pdev,
1336		    hldev->header.regh0,
1337		    value,
1338		    (void *)(((ptr_t) hldev->common_reg) + offset));
1339		break;
1340	case vxge_hal_mgmt_reg_type_memrepair:
1341		if (!(hldev->access_rights &
1342		    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)) {
1343			status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
1344			break;
1345		}
1346		if (offset > sizeof(vxge_hal_memrepair_reg_t) - 8) {
1347			status = VXGE_HAL_ERR_INVALID_OFFSET;
1348			break;
1349		}
1350		vxge_os_pio_mem_write64(hldev->header.pdev,
1351		    hldev->header.regh0,
1352		    value,
1353		    (void *)(((ptr_t) hldev->memrepair_reg) + offset));
1354		break;
1355	case vxge_hal_mgmt_reg_type_pcicfgmgmt:
1356		if (!(hldev->access_rights &
1357		    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)) {
1358			status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
1359			break;
1360		}
1361		if (vp_id > VXGE_HAL_TITAN_PCICFGMGMT_REG_SPACES - 1) {
1362			status = VXGE_HAL_ERR_INVALID_INDEX;
1363			break;
1364		}
1365		if (offset > sizeof(vxge_hal_pcicfgmgmt_reg_t) - 8) {
1366			status = VXGE_HAL_ERR_INVALID_OFFSET;
1367			break;
1368		}
1369		vxge_os_pio_mem_write64(hldev->header.pdev,
1370		    hldev->header.regh0,
1371		    value,
1372		    (void *)(((ptr_t) hldev->pcicfgmgmt_reg[vp_id]) + offset));
1373		break;
1374	case vxge_hal_mgmt_reg_type_mrpcim:
1375		if (!(hldev->access_rights &
1376		    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)) {
1377			status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
1378			break;
1379		}
1380		if (offset > sizeof(vxge_hal_mrpcim_reg_t) - 8) {
1381			status = VXGE_HAL_ERR_INVALID_OFFSET;
1382			break;
1383		}
1384		vxge_os_pio_mem_write64(hldev->header.pdev,
1385		    hldev->header.regh0,
1386		    value,
1387		    (void *)(((ptr_t) hldev->mrpcim_reg) + offset));
1388		break;
1389	case vxge_hal_mgmt_reg_type_srpcim:
1390		if (!(hldev->access_rights &
1391		    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)) {
1392			status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
1393			break;
1394		}
1395		if (vp_id > VXGE_HAL_TITAN_SRPCIM_REG_SPACES - 1) {
1396			status = VXGE_HAL_ERR_INVALID_INDEX;
1397			break;
1398		}
1399		if (offset > sizeof(vxge_hal_srpcim_reg_t) - 8) {
1400			status = VXGE_HAL_ERR_INVALID_OFFSET;
1401			break;
1402		}
1403		vxge_os_pio_mem_write64(hldev->header.pdev,
1404		    hldev->header.regh0,
1405		    value,
1406		    (void *)(((ptr_t) hldev->srpcim_reg[vp_id]) + offset));
1407		break;
1408	case vxge_hal_mgmt_reg_type_vpmgmt:
1409		if ((vp_id > VXGE_HAL_TITAN_VPMGMT_REG_SPACES - 1) ||
1410		    (!(hldev->vpath_assignments & mBIT(vp_id)))) {
1411			status = VXGE_HAL_ERR_INVALID_INDEX;
1412			break;
1413		}
1414		if (offset > sizeof(vxge_hal_vpmgmt_reg_t) - 8) {
1415			status = VXGE_HAL_ERR_INVALID_OFFSET;
1416			break;
1417		}
1418		vxge_os_pio_mem_write64(hldev->header.pdev,
1419		    hldev->header.regh0,
1420		    value,
1421		    (void *)(((ptr_t) hldev->vpmgmt_reg[vp_id]) + offset));
1422		break;
1423	case vxge_hal_mgmt_reg_type_vpath:
1424		if ((vp_id > VXGE_HAL_TITAN_VPATH_REG_SPACES - 1) ||
1425		    (!(hldev->vpath_assignments & mBIT(vp_id)))) {
1426			status = VXGE_HAL_ERR_INVALID_INDEX;
1427			break;
1428		}
1429		if (offset > sizeof(vxge_hal_vpath_reg_t) - 8) {
1430			status = VXGE_HAL_ERR_INVALID_OFFSET;
1431			break;
1432		}
1433		vxge_os_pio_mem_write64(hldev->header.pdev,
1434		    hldev->header.regh0,
1435		    value,
1436		    (void *)(((ptr_t) hldev->vpath_reg[vp_id]) + offset));
1437		break;
1438	default:
1439		status = VXGE_HAL_ERR_INVALID_TYPE;
1440		break;
1441	}
1442
1443	vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1444	    __FILE__, __func__, __LINE__, status);
1445	return (status);
1446}
1447
1448/*
1449 * vxge_hal_mgmt_bar0_read - Read X3100 register located at the offset
1450 *                           from bar0.
1451 * @devh: HAL device handle.
1452 * @offset: Register offset from bar0
1453 * @value: Register value. Returned by HAL.
1454 * Read X3100 register.
1455 *
1456 * Returns: VXGE_HAL_OK - success.
1457 * VXGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
1458 * VXGE_HAL_ERR_INVALID_OFFSET - Register offset in the space is not valid.
1459 *
1460 */
1461vxge_hal_status_e
1462vxge_hal_mgmt_bar0_read(vxge_hal_device_h devh,
1463    u32 offset,
1464    u64 *value)
1465{
1466	vxge_hal_status_e status = VXGE_HAL_OK;
1467	__hal_device_t *hldev = (__hal_device_t *) devh;
1468
1469	vxge_assert(devh != NULL);
1470
1471	vxge_hal_trace_log_device("==> %s:%s:%d",
1472	    __FILE__, __func__, __LINE__);
1473
1474	vxge_hal_trace_log_device(
1475	    "devh = 0x"VXGE_OS_STXFMT", offset = %d, value = 0x"VXGE_OS_STXFMT,
1476	    (ptr_t) devh, offset, (ptr_t) value);
1477
1478	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
1479		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1480		    __FILE__, __func__, __LINE__,
1481		    VXGE_HAL_ERR_INVALID_DEVICE);
1482		return (VXGE_HAL_ERR_INVALID_DEVICE);
1483	}
1484
1485	if (((ptr_t) hldev->header.bar0 + offset) >
1486	    ((ptr_t) hldev->vpath_reg[VXGE_HAL_MAX_VIRTUAL_PATHS - 1] +
1487	    sizeof(vxge_hal_vpath_reg_t) - 8)) {
1488		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1489		    __FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_OFFSET);
1490		return (VXGE_HAL_ERR_INVALID_OFFSET);
1491	}
1492
1493	*value = vxge_os_pio_mem_read64(hldev->header.pdev,
1494	    hldev->header.regh0,
1495	    (void *)(((ptr_t) hldev->header.bar0) + offset));
1496
1497	vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1498	    __FILE__, __func__, __LINE__, status);
1499	return (status);
1500}
1501
1502/*
1503 * vxge_hal_mgmt_bar1_read - Read X3100 register located at the offset
1504 *                           from bar1.
1505 * @devh: HAL device handle.
1506 * @offset: Register offset from bar1
1507 * @value: Register value. Returned by HAL.
1508 * Read X3100 register.
1509 *
1510 * Returns: VXGE_HAL_OK - success.
1511 * VXGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
1512 *
1513 */
1514vxge_hal_status_e
1515vxge_hal_mgmt_bar1_read(vxge_hal_device_h devh,
1516    u32 offset,
1517    u64 *value)
1518{
1519	vxge_hal_status_e status = VXGE_HAL_OK;
1520	__hal_device_t *hldev = (__hal_device_t *) devh;
1521
1522	vxge_assert(devh != NULL);
1523
1524	vxge_hal_trace_log_device("==> %s:%s:%d",
1525	    __FILE__, __func__, __LINE__);
1526
1527	vxge_hal_trace_log_device(
1528	    "devh = 0x"VXGE_OS_STXFMT", offset = %d, value = 0x"VXGE_OS_STXFMT,
1529	    (ptr_t) devh, offset, (ptr_t) value);
1530
1531	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
1532		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1533		    __FILE__, __func__, __LINE__,
1534		    VXGE_HAL_ERR_INVALID_DEVICE);
1535		return (VXGE_HAL_ERR_INVALID_DEVICE);
1536	}
1537
1538	*value = vxge_os_pio_mem_read64(hldev->header.pdev,
1539	    hldev->header.regh0,
1540	    (void *)(((ptr_t) hldev->header.bar1) + offset));
1541
1542	vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1543	    __FILE__, __func__, __LINE__, status);
1544	return (status);
1545}
1546
1547/*
1548 * vxge_hal_mgmt_bar0_Write - Write X3100 register located at the offset
1549 *			    from bar0.
1550 * @devh: HAL device handle.
1551 * @offset: Register offset from bar0
1552 * @value: Register value to be written.
1553 * Write X3100 register.
1554 *
1555 * Returns: VXGE_HAL_OK - success.
1556 * VXGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
1557 * VXGE_HAL_ERR_INVALID_OFFSET - Register offset in the space is not valid.
1558 *
1559 */
1560vxge_hal_status_e
1561vxge_hal_mgmt_bar0_write(vxge_hal_device_h devh,
1562    u32 offset,
1563    u64 value)
1564{
1565	vxge_hal_status_e status = VXGE_HAL_OK;
1566	__hal_device_t *hldev = (__hal_device_t *) devh;
1567
1568	vxge_assert(devh != NULL);
1569
1570	vxge_hal_trace_log_device("==> %s:%s:%d",
1571	    __FILE__, __func__, __LINE__);
1572
1573	vxge_hal_trace_log_device(
1574	    "devh = 0x"VXGE_OS_STXFMT", offset = %d, value = 0x"VXGE_OS_STXFMT,
1575	    (ptr_t) devh, offset, (ptr_t) value);
1576
1577	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
1578		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1579		    __FILE__, __func__, __LINE__,
1580		    VXGE_HAL_ERR_INVALID_DEVICE);
1581		return (VXGE_HAL_ERR_INVALID_DEVICE);
1582	}
1583	if (((ptr_t) hldev->header.bar0 + offset) >
1584	    ((ptr_t) hldev->vpath_reg[VXGE_HAL_MAX_VIRTUAL_PATHS - 1] +
1585	    sizeof(vxge_hal_vpath_reg_t) - 8)) {
1586		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1587		    __FILE__, __func__, __LINE__,
1588		    VXGE_HAL_ERR_INVALID_OFFSET);
1589		return (VXGE_HAL_ERR_INVALID_OFFSET);
1590	}
1591
1592	vxge_os_pio_mem_write64(hldev->header.pdev,
1593	    hldev->header.regh0,
1594	    value,
1595	    (void *)(((ptr_t) hldev->header.bar0) + offset));
1596
1597	vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1598	    __FILE__, __func__, __LINE__, status);
1599	return (status);
1600}
1601
1602/*
1603 * vxge_hal_mgmt_register_config - Retrieve register configuration.
1604 * @devh: HAL device handle.
1605 * @type: Register types as defined in enum vxge_hal_mgmt_reg_type_e {}
1606 * @Index: For pcicfgmgmt, srpcim, vpmgmt, vpath this gives the Index
1607 *		ignored for others
1608 * @config: Device configuration, see vxge_hal_device_config_t {}.
1609 * @size: Pointer to buffer containing the Size of the @reg_config.
1610 * HAL will return an error if the size is smaller than
1611 * requested register space and returns required size in this field
1612 *
1613 * Get register configuration. Permits to retrieve register values.
1614 *
1615 * Returns: VXGE_HAL_OK - success.
1616 * VXGE_HAL_ERR_INVALID_DEVICE - Device is not valid.
1617 * VXGE_HAL_ERR_INVALID_TYPE - Type is not valid.
1618 * VXGE_HAL_ERR_INVALID_INDEX - Index is not valid.
1619 * VXGE_HAL_ERR_OUT_OF_SPACE - If the buffer is not sufficient
1620 *
1621 */
1622vxge_hal_status_e
1623vxge_hal_mgmt_register_config(vxge_hal_device_h devh,
1624    vxge_hal_mgmt_reg_type_e type, u32 vp_id, u8 *config, u32 *size)
1625{
1626	u32 offset;
1627	u64 *reg_config = (u64 *) ((void *)config);
1628	vxge_hal_status_e status = VXGE_HAL_OK;
1629	__hal_device_t *hldev = (__hal_device_t *) devh;
1630
1631	vxge_assert((devh != NULL) && (reg_config != NULL) && (size != NULL));
1632
1633	vxge_hal_trace_log_device("==> %s:%s:%d",
1634	    __FILE__, __func__, __LINE__);
1635
1636	vxge_hal_trace_log_device(
1637	    "devh = 0x"VXGE_OS_STXFMT", type = %d, index = %d, "
1638	    "reg_config = 0x"VXGE_OS_STXFMT", size = 0x"VXGE_OS_STXFMT,
1639	    (ptr_t) devh, type, vp_id, (ptr_t) reg_config, (ptr_t) size);
1640
1641	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
1642		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1643		    __FILE__, __func__, __LINE__,
1644		    VXGE_HAL_ERR_INVALID_DEVICE);
1645		return (VXGE_HAL_ERR_INVALID_DEVICE);
1646	}
1647
1648	switch (type) {
1649	case vxge_hal_mgmt_reg_type_legacy:
1650		if (*size < sizeof(vxge_hal_legacy_reg_t)) {
1651			status = VXGE_HAL_ERR_OUT_OF_SPACE;
1652			*size = sizeof(vxge_hal_legacy_reg_t);
1653			break;
1654		}
1655
1656		for (offset = 0; offset < sizeof(vxge_hal_legacy_reg_t);
1657		    offset += 8) {
1658			*reg_config++ = vxge_os_pio_mem_read64(
1659			    hldev->header.pdev,
1660			    hldev->header.regh0,
1661			    (void *)(((ptr_t) hldev->legacy_reg) + offset));
1662		}
1663		*size = sizeof(vxge_hal_legacy_reg_t);
1664		break;
1665
1666	case vxge_hal_mgmt_reg_type_toc:
1667		if (*size < sizeof(vxge_hal_toc_reg_t)) {
1668			status = VXGE_HAL_ERR_OUT_OF_SPACE;
1669			*size = sizeof(vxge_hal_toc_reg_t);
1670			break;
1671		}
1672
1673		for (offset = 0; offset < sizeof(vxge_hal_toc_reg_t);
1674		    offset += 8) {
1675			*reg_config++ = vxge_os_pio_mem_read64(
1676			    hldev->header.pdev,
1677			    hldev->header.regh0,
1678			    (void *)(((ptr_t) hldev->toc_reg) + offset));
1679		}
1680		*size = sizeof(vxge_hal_toc_reg_t);
1681		break;
1682
1683	case vxge_hal_mgmt_reg_type_common:
1684		if (*size < sizeof(vxge_hal_common_reg_t)) {
1685			status = VXGE_HAL_ERR_OUT_OF_SPACE;
1686			*size = sizeof(vxge_hal_common_reg_t);
1687			break;
1688		}
1689
1690		for (offset = 0; offset < sizeof(vxge_hal_common_reg_t);
1691		    offset += 8) {
1692			*reg_config++ = vxge_os_pio_mem_read64(
1693			    hldev->header.pdev,
1694			    hldev->header.regh0,
1695			    (void *)(((ptr_t) hldev->common_reg) + offset));
1696		}
1697		*size = sizeof(vxge_hal_common_reg_t);
1698		break;
1699
1700	case vxge_hal_mgmt_reg_type_memrepair:
1701		if (!(hldev->access_rights &
1702		    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)) {
1703			status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
1704			break;
1705		}
1706
1707		if (*size < sizeof(vxge_hal_memrepair_reg_t)) {
1708			status = VXGE_HAL_ERR_OUT_OF_SPACE;
1709			*size = sizeof(vxge_hal_memrepair_reg_t);
1710			break;
1711		}
1712
1713		for (offset = 0;
1714		    offset < sizeof(vxge_hal_memrepair_reg_t); offset += 8) {
1715			*reg_config++ = vxge_os_pio_mem_read64(
1716			    hldev->header.pdev,
1717			    hldev->header.regh0,
1718			    (void *)(((ptr_t) hldev->memrepair_reg) + offset));
1719		}
1720		*size = sizeof(vxge_hal_memrepair_reg_t);
1721		break;
1722
1723	case vxge_hal_mgmt_reg_type_pcicfgmgmt:
1724		if (!(hldev->access_rights &
1725		    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)) {
1726			status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
1727			break;
1728		}
1729
1730		if (vp_id > VXGE_HAL_TITAN_PCICFGMGMT_REG_SPACES - 1) {
1731			status = VXGE_HAL_ERR_INVALID_INDEX;
1732			break;
1733		}
1734
1735		if (*size < sizeof(vxge_hal_pcicfgmgmt_reg_t)) {
1736			status = VXGE_HAL_ERR_OUT_OF_SPACE;
1737			*size = sizeof(vxge_hal_pcicfgmgmt_reg_t);
1738			break;
1739		}
1740
1741		for (offset = 0; offset < sizeof(vxge_hal_pcicfgmgmt_reg_t);
1742		    offset += 8) {
1743			*reg_config++ = vxge_os_pio_mem_read64(
1744			    hldev->header.pdev,
1745			    hldev->header.regh0,
1746			    (void *)(((ptr_t) hldev->pcicfgmgmt_reg[vp_id]) + offset));
1747		}
1748		*size = sizeof(vxge_hal_pcicfgmgmt_reg_t);
1749		break;
1750
1751	case vxge_hal_mgmt_reg_type_mrpcim:
1752		if (!(hldev->access_rights &
1753		    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)) {
1754			status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
1755			break;
1756		}
1757
1758		if (*size < sizeof(vxge_hal_mrpcim_reg_t)) {
1759			status = VXGE_HAL_ERR_OUT_OF_SPACE;
1760			*size = sizeof(vxge_hal_mrpcim_reg_t);
1761			break;
1762		}
1763
1764		for (offset = 0; offset < sizeof(vxge_hal_mrpcim_reg_t);
1765		    offset += 8) {
1766			*reg_config++ = vxge_os_pio_mem_read64(
1767			    hldev->header.pdev,
1768			    hldev->header.regh0,
1769			    (void *)(((ptr_t) hldev->mrpcim_reg) + offset));
1770		}
1771		*size = sizeof(vxge_hal_mrpcim_reg_t);
1772		break;
1773
1774	case vxge_hal_mgmt_reg_type_srpcim:
1775		if (!(hldev->access_rights &
1776		    VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM)) {
1777			status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
1778			break;
1779		}
1780
1781		if (vp_id > VXGE_HAL_TITAN_SRPCIM_REG_SPACES - 1) {
1782			status = VXGE_HAL_ERR_INVALID_INDEX;
1783			break;
1784		}
1785
1786		if (*size < sizeof(vxge_hal_srpcim_reg_t)) {
1787			status = VXGE_HAL_ERR_OUT_OF_SPACE;
1788			*size = sizeof(vxge_hal_srpcim_reg_t);
1789			break;
1790		}
1791
1792		for (offset = 0; offset < sizeof(vxge_hal_srpcim_reg_t);
1793		    offset += 8) {
1794			*reg_config++ = vxge_os_pio_mem_read64(
1795			    hldev->header.pdev,
1796			    hldev->header.regh0,
1797			    (void *)(((ptr_t) hldev->srpcim_reg[vp_id]) + offset));
1798		}
1799		*size = sizeof(vxge_hal_srpcim_reg_t);
1800		break;
1801
1802	case vxge_hal_mgmt_reg_type_vpmgmt:
1803		if ((vp_id > VXGE_HAL_TITAN_VPMGMT_REG_SPACES - 1) ||
1804		    (!(hldev->vpath_assignments & mBIT(vp_id)))) {
1805			status = VXGE_HAL_ERR_INVALID_INDEX;
1806			break;
1807		}
1808
1809		if (*size < sizeof(vxge_hal_vpmgmt_reg_t)) {
1810			status = VXGE_HAL_ERR_OUT_OF_SPACE;
1811			*size = sizeof(vxge_hal_vpmgmt_reg_t);
1812			break;
1813		}
1814
1815		for (offset = 0; offset < sizeof(vxge_hal_vpmgmt_reg_t);
1816		    offset += 8) {
1817			*reg_config++ = vxge_os_pio_mem_read64(
1818			    hldev->header.pdev,
1819			    hldev->header.regh0,
1820			    (void *)(((ptr_t) hldev->vpmgmt_reg[vp_id]) + offset));
1821		}
1822		*size = sizeof(vxge_hal_vpmgmt_reg_t);
1823		break;
1824
1825	case vxge_hal_mgmt_reg_type_vpath:
1826		if ((vp_id > VXGE_HAL_TITAN_VPATH_REG_SPACES - 1) ||
1827		    (!(hldev->vpath_assignments & mBIT(vp_id)))) {
1828			status = VXGE_HAL_ERR_INVALID_INDEX;
1829			break;
1830		}
1831
1832		if (vp_id > VXGE_HAL_TITAN_VPATH_REG_SPACES - 1) {
1833			status = VXGE_HAL_ERR_INVALID_INDEX;
1834			break;
1835		}
1836
1837		if (*size < sizeof(vxge_hal_vpath_reg_t)) {
1838			status = VXGE_HAL_ERR_OUT_OF_SPACE;
1839			*size = sizeof(vxge_hal_vpath_reg_t);
1840			break;
1841		}
1842
1843		for (offset = 0; offset < sizeof(vxge_hal_vpath_reg_t);
1844		    offset += 8) {
1845			*reg_config++ = vxge_os_pio_mem_read64(
1846			    hldev->header.pdev,
1847			    hldev->header.regh0,
1848			    (void *)(((ptr_t) hldev->vpath_reg[vp_id]) + offset));
1849		}
1850		*size = sizeof(vxge_hal_vpath_reg_t);
1851		break;
1852
1853	default:
1854		status = VXGE_HAL_ERR_INVALID_TYPE;
1855		break;
1856	}
1857
1858	vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
1859	    __FILE__, __func__, __LINE__, status);
1860	return (status);
1861}
1862
1863/*
1864 * vxge_hal_mgmt_read_xfp_current_temp - Read current temparature of given port
1865 * @hldev: HAL device handle.
1866 * @port: Port number
1867 *
1868 * This routine only gets the temperature for XFP modules. Also, updating of the
1869 * NVRAM can sometimes fail and so the reading we might get may not be uptodate.
1870 */
1871u32
1872vxge_hal_mgmt_read_xfp_current_temp(vxge_hal_device_h devh, u32 port)
1873{
1874	u16 val1, val2, count = 0;
1875	u32 actual;
1876	vxge_hal_status_e status;
1877	__hal_device_t *hldev = (__hal_device_t *) devh;
1878
1879	vxge_assert(devh != NULL);
1880
1881	vxge_hal_trace_log_mrpcim("==> %s:%s:%d",
1882	    __FILE__, __func__, __LINE__);
1883
1884	vxge_hal_trace_log_mrpcim("devh = 0x"VXGE_OS_STXFMT", port = %d",
1885	    (ptr_t) devh, port);
1886
1887	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
1888		vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
1889		    __FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_DEVICE);
1890		return (VXGE_HAL_ERR_INVALID_DEVICE);
1891	}
1892
1893	if (!(hldev->access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)) {
1894		vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
1895		    __FILE__, __func__, __LINE__,
1896		    VXGE_HAL_ERR_PRIVILAGED_OPEARATION);
1897		return (VXGE_HAL_ERR_PRIVILAGED_OPEARATION);
1898	}
1899
1900	val1 = VXGE_HAL_MDIO_MGR_ACCESS_PORT_ADDR_EEPROM_NVR_CONTROL_256_BYTES;
1901
1902	status = __hal_mrpcim_mdio_access(devh, port,
1903	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_OP_TYPE_ADDR_WRITE,
1904	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_DEVAD_PMA_PMD,
1905	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_ADDR_EEPROM_NVR_CONTROL,
1906	    &val1);
1907
1908	if (status != VXGE_HAL_OK) {
1909		vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
1910		    __FILE__, __func__, __LINE__, status);
1911		return (status);
1912	}
1913
1914	/* Now wait for the transfer to complete */
1915	do {
1916		vxge_os_mdelay(50);	/* wait 50 milliseonds */
1917
1918		status = __hal_mrpcim_mdio_access(devh, port,
1919		    VXGE_HAL_MDIO_MGR_ACCESS_PORT_OP_TYPE_ADDR_READ,
1920		    VXGE_HAL_MDIO_MGR_ACCESS_PORT_DEVAD_PMA_PMD,
1921		    VXGE_HAL_MDIO_MGR_ACCESS_PORT_ADDR_EEPROM_NVR_CONTROL,
1922		    &val1);
1923
1924		if (status != VXGE_HAL_OK) {
1925			vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
1926			    __FILE__, __func__, __LINE__, status);
1927			return (status);
1928		}
1929
1930		if (count++ > 10) {
1931			/* waited 500 ms which should be plenty of time */
1932			break;
1933		}
1934
1935	} while ((val1 &
1936	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_ADDR_EEPROM_NVR_CONTROL_STAT_MASK)
1937	    == VXGE_HAL_MDIO_MGR_ACCESS_PORT_ADDR_EEPROM_NVR_CONTROL_PROGRESS);
1938
1939	if ((val1 &
1940	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_ADDR_EEPROM_NVR_CONTROL_STAT_MASK) ==
1941	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_ADDR_EEPROM_NVR_CONTROL_FAILED) {
1942		vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
1943		    __FILE__, __func__, __LINE__, status);
1944		return (VXGE_HAL_FAIL);
1945	}
1946
1947	status = __hal_mrpcim_mdio_access(devh, port,
1948	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_OP_TYPE_ADDR_READ,
1949	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_DEVAD_PMA_PMD,
1950	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_ADDR_EEPROM_NVR_DATA_XFP_TEMP_1,
1951	    &val1);
1952
1953	if (status != VXGE_HAL_OK) {
1954		vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
1955		    __FILE__, __func__, __LINE__, status);
1956		return (status);
1957	}
1958
1959	status = __hal_mrpcim_mdio_access(devh, port,
1960	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_OP_TYPE_ADDR_READ,
1961	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_DEVAD_PMA_PMD,
1962	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_ADDR_EEPROM_NVR_DATA_XFP_TEMP_2,
1963	    &val2);
1964
1965	if (status != VXGE_HAL_OK) {
1966		vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
1967		    __FILE__, __func__, __LINE__, status);
1968		return (status);
1969	}
1970
1971	actual = ((val1 << 8) | val2);
1972
1973	if (actual >= 32768)
1974		actual = actual - 65536;
1975
1976	actual = actual / 256;
1977
1978	vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
1979	    __FILE__, __func__, __LINE__, status);
1980
1981	return (actual);
1982
1983}
1984
1985/*
1986 * vxge_hal_mgmt_pma_loopback - Enable or disable PMA loopback
1987 * @devh: HAL device handle.
1988 * @port: Port number
1989 * @enable:Boolean set to 1 to enable and 0 to disable.
1990 *
1991 * Enable or disable PMA loopback.
1992 * Return value:
1993 * 0 on success.
1994 */
1995vxge_hal_status_e
1996vxge_hal_mgmt_pma_loopback(vxge_hal_device_h devh, u32 port, u32 enable)
1997{
1998	u16 val;
1999	vxge_hal_status_e status;
2000	__hal_device_t *hldev = (__hal_device_t *) devh;
2001
2002	vxge_assert(devh != NULL);
2003
2004	vxge_hal_trace_log_mrpcim("==> %s:%s:%d",
2005	    __FILE__, __func__, __LINE__);
2006
2007	vxge_hal_trace_log_mrpcim(
2008	    "devh = 0x"VXGE_OS_STXFMT", port = %d, enable = %d",
2009	    (ptr_t) devh, port, enable);
2010
2011	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
2012		vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
2013		    __FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_DEVICE);
2014		return (VXGE_HAL_ERR_INVALID_DEVICE);
2015	}
2016
2017	if (!(hldev->access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)) {
2018		vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
2019		    __FILE__, __func__, __LINE__,
2020		    VXGE_HAL_ERR_PRIVILAGED_OPEARATION);
2021		return (VXGE_HAL_ERR_PRIVILAGED_OPEARATION);
2022	}
2023
2024	status = __hal_mrpcim_mdio_access(devh, port,
2025	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_OP_TYPE_ADDR_READ,
2026	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_DEVAD_PMA_PMD,
2027	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_ADDR_PMA_CONTROL_1,
2028	    &val);
2029
2030	if (status != VXGE_HAL_OK) {
2031		vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
2032		    __FILE__, __func__, __LINE__, status);
2033		return (status);
2034	}
2035
2036	if (enable)
2037		val |=
2038		    VXGE_HAL_MDIO_MGR_ACCESS_PORT_ADDR_PMA_CONTROL_1_LOOPBACK;
2039	else
2040		val &=
2041		    ~VXGE_HAL_MDIO_MGR_ACCESS_PORT_ADDR_PMA_CONTROL_1_LOOPBACK;
2042
2043	status = __hal_mrpcim_mdio_access(devh, port,
2044	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_OP_TYPE_ADDR_WRITE,
2045	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_DEVAD_PMA_PMD,
2046	    VXGE_HAL_MDIO_MGR_ACCESS_PORT_ADDR_PMA_CONTROL_1,
2047	    &val);
2048
2049	vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
2050	    __FILE__, __func__, __LINE__, status);
2051
2052	return (VXGE_HAL_OK);
2053}
2054
2055/*
2056 * vxge_hal_mgmt_xgmii_loopback - Enable or disable xgmii loopback
2057 * @devh: HAL device handle.
2058 * @port: Port number
2059 * @enable:Boolean set to 1 to enable and 0 to disable.
2060 *
2061 * Enable or disable xgmii loopback.
2062 * Return value:
2063 * 0 on success.
2064 */
2065vxge_hal_status_e
2066vxge_hal_mgmt_xgmii_loopback(vxge_hal_device_h devh, u32 port, u32 enable)
2067{
2068	u64 val64;
2069	__hal_device_t *hldev = (__hal_device_t *) devh;
2070
2071	vxge_assert(devh != NULL);
2072
2073	vxge_hal_trace_log_mrpcim("==> %s:%s:%d",
2074	    __FILE__, __func__, __LINE__);
2075
2076	vxge_hal_trace_log_mrpcim(
2077	    "devh = 0x"VXGE_OS_STXFMT", port = %d, enable = %d",
2078	    (ptr_t) devh, port, enable);
2079
2080	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
2081		vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
2082		    __FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_DEVICE);
2083		return (VXGE_HAL_ERR_INVALID_DEVICE);
2084	}
2085
2086	if (!(hldev->access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)) {
2087		vxge_hal_trace_log_mrpcim("<== %s:%s:%d  Result: %d",
2088		    __FILE__, __func__, __LINE__,
2089		    VXGE_HAL_ERR_PRIVILAGED_OPEARATION);
2090		return (VXGE_HAL_ERR_PRIVILAGED_OPEARATION);
2091	}
2092
2093	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
2094	    hldev->header.regh0,
2095	    &hldev->mrpcim_reg->xmac_cfg_port[port]);
2096	if (enable)
2097		val64 |= VXGE_HAL_XMAC_CFG_PORT_XGMII_LOOPBACK;
2098	else
2099		val64 &= ~VXGE_HAL_XMAC_CFG_PORT_XGMII_LOOPBACK;
2100
2101	vxge_os_pio_mem_write64(hldev->header.pdev,
2102	    hldev->header.regh0,
2103	    val64,
2104	    &hldev->mrpcim_reg->xmac_cfg_port[port]);
2105
2106	vxge_hal_trace_log_mrpcim("<== %s:%s:%d Result = 0",
2107	    __FILE__, __func__, __LINE__);
2108
2109	return (VXGE_HAL_OK);
2110}
2111
2112