vxgehal-device.c revision 331722
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: stable/11/sys/dev/vxge/vxgehal/vxgehal-device.c 331722 2018-03-29 02:50:57Z eadler $*/
32
33#include <dev/vxge/vxgehal/vxgehal.h>
34
35/*
36 * vxge_hal_pio_mem_write32_upper
37 *
38 * Endiann-aware implementation of vxge_os_pio_mem_write32().
39 * Since X3100 has 64bit registers, we differintiate uppper and lower
40 * parts.
41 */
42void
43vxge_hal_pio_mem_write32_upper(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr)
44{
45#if defined(VXGE_OS_HOST_BIG_ENDIAN) && !defined(VXGE_OS_PIO_LITTLE_ENDIAN)
46	vxge_os_pio_mem_write32(pdev, regh, val, addr);
47#else
48	vxge_os_pio_mem_write32(pdev, regh, val, (void *) ((char *) addr + 4));
49#endif
50}
51
52/*
53 * vxge_hal_pio_mem_write32_lower
54 *
55 * Endiann-aware implementation of vxge_os_pio_mem_write32().
56 * Since X3100 has 64bit registers, we differintiate uppper and lower
57 * parts.
58 */
59void
60vxge_hal_pio_mem_write32_lower(pci_dev_h pdev, pci_reg_h regh, u32 val,
61    void *addr)
62{
63#if defined(VXGE_OS_HOST_BIG_ENDIAN) && !defined(VXGE_OS_PIO_LITTLE_ENDIAN)
64	vxge_os_pio_mem_write32(pdev, regh, val,
65	    (void *) ((char *) addr + 4));
66#else
67	vxge_os_pio_mem_write32(pdev, regh, val, addr);
68#endif
69}
70
71/*
72 * vxge_hal_device_pciconfig_get - Read the content of given address
73 *			 in pci config space.
74 * @devh: Device handle.
75 * @offset: Configuration address(offset)to read from
76 * @length: Length of the data (1, 2 or 4 bytes)
77 * @val: Pointer to a buffer to return the content of the address
78 *
79 * Read from the pci config space.
80 *
81 */
82vxge_hal_status_e
83vxge_hal_device_pciconfig_get(
84    vxge_hal_device_h devh,
85    u32 offset,
86    u32 length,
87    void *val)
88{
89	u32 i;
90	vxge_hal_status_e status = VXGE_HAL_OK;
91	__hal_device_t *hldev = (__hal_device_t *) devh;
92
93	vxge_assert((devh != NULL) && (val != NULL));
94
95	vxge_hal_trace_log_device("==> %s:%s:%d",
96	    __FILE__, __func__, __LINE__);
97
98	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
99	    (ptr_t) devh);
100
101	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
102
103		if (!(hldev->vpath_assignments & mBIT(i)))
104			continue;
105
106		status = __hal_vpath_pci_read(hldev, i,
107		    offset, length, val);
108
109		if (status == VXGE_HAL_OK)
110			break;
111
112	}
113
114	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
115	    __FILE__, __func__, __LINE__, status);
116	return (status);
117
118}
119
120/*
121 * __hal_device_pci_caps_list_process
122 * @hldev: HAL device handle.
123 *
124 * Process PCI capabilities and initialize the offsets
125 */
126void
127__hal_device_pci_caps_list_process(__hal_device_t *hldev)
128{
129	u8 cap_id;
130	u16 ext_cap_id;
131	u16 next_ptr;
132	u32 *ptr_32;
133	vxge_hal_pci_config_t *pci_config = &hldev->pci_config_space_bios;
134
135	vxge_assert(hldev != NULL);
136
137	vxge_hal_trace_log_device("==> %s:%s:%d",
138	    __FILE__, __func__, __LINE__);
139
140	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
141	    (ptr_t) hldev);
142
143	next_ptr = pci_config->capabilities_pointer;
144
145	while (next_ptr != 0) {
146
147		cap_id = VXGE_HAL_PCI_CAP_ID((((u8 *) pci_config) + next_ptr));
148
149		switch (cap_id) {
150
151		case VXGE_HAL_PCI_CAP_ID_PM:
152			hldev->pci_caps.pm_cap_offset = next_ptr;
153			break;
154		case VXGE_HAL_PCI_CAP_ID_VPD:
155			hldev->pci_caps.vpd_cap_offset = next_ptr;
156			break;
157		case VXGE_HAL_PCI_CAP_ID_SLOTID:
158			hldev->pci_caps.sid_cap_offset = next_ptr;
159			break;
160		case VXGE_HAL_PCI_CAP_ID_MSI:
161			hldev->pci_caps.msi_cap_offset = next_ptr;
162			break;
163		case VXGE_HAL_PCI_CAP_ID_VS:
164			hldev->pci_caps.vs_cap_offset = next_ptr;
165			break;
166		case VXGE_HAL_PCI_CAP_ID_SHPC:
167			hldev->pci_caps.shpc_cap_offset = next_ptr;
168			break;
169		case VXGE_HAL_PCI_CAP_ID_PCIE:
170			hldev->pci_e_caps = next_ptr;
171			break;
172		case VXGE_HAL_PCI_CAP_ID_MSIX:
173			hldev->pci_caps.msix_cap_offset = next_ptr;
174			break;
175		case VXGE_HAL_PCI_CAP_ID_AGP:
176		case VXGE_HAL_PCI_CAP_ID_CHSWP:
177		case VXGE_HAL_PCI_CAP_ID_PCIX:
178		case VXGE_HAL_PCI_CAP_ID_HT:
179		case VXGE_HAL_PCI_CAP_ID_DBGPORT:
180		case VXGE_HAL_PCI_CAP_ID_CPCICSR:
181		case VXGE_HAL_PCI_CAP_ID_PCIBSVID:
182		case VXGE_HAL_PCI_CAP_ID_AGP8X:
183		case VXGE_HAL_PCI_CAP_ID_SECDEV:
184			vxge_hal_info_log_device("Unexpected Capability = %d",
185			    cap_id);
186			break;
187		default:
188			vxge_hal_info_log_device("Unknown capability = %d",
189			    cap_id);
190			break;
191		}
192
193		next_ptr =
194		    VXGE_HAL_PCI_CAP_NEXT((((u8 *) pci_config) + next_ptr));
195
196	}
197
198	/* CONSTCOND */
199	if (VXGE_HAL_PCI_CONFIG_SPACE_SIZE <= 0x100) {
200		vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
201		    __FILE__, __func__, __LINE__);
202		return;
203	}
204
205	next_ptr = 0x100;
206	while (next_ptr != 0) {
207
208		ptr_32 = (u32 *) ((void *) (((u8 *) pci_config) + next_ptr));
209		ext_cap_id = (u16) (VXGE_HAL_PCI_EXT_CAP_ID(*ptr_32));
210
211		switch (ext_cap_id) {
212
213		case VXGE_HAL_PCI_EXT_CAP_ID_ERR:
214			hldev->pci_e_ext_caps.err_cap_offset = next_ptr;
215			break;
216		case VXGE_HAL_PCI_EXT_CAP_ID_VC:
217			hldev->pci_e_ext_caps.vc_cap_offset = next_ptr;
218			break;
219		case VXGE_HAL_PCI_EXT_CAP_ID_DSN:
220			hldev->pci_e_ext_caps.dsn_cap_offset = next_ptr;
221			break;
222		case VXGE_HAL_PCI_EXT_CAP_ID_PWR:
223			hldev->pci_e_ext_caps.pwr_budget_cap_offset = next_ptr;
224			break;
225
226		default:
227			vxge_hal_info_log_device("Unknown capability = %d",
228			    ext_cap_id);
229			break;
230		}
231
232		next_ptr = (u16) VXGE_HAL_PCI_EXT_CAP_NEXT(*ptr_32);
233	}
234
235	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
236	    __FILE__, __func__, __LINE__);
237}
238
239/*
240 * __hal_device_pci_e_init
241 * @hldev: HAL device handle.
242 *
243 * Initialize certain PCI/PCI-X configuration registers
244 * with recommended values. Save config space for future hw resets.
245 */
246void
247__hal_device_pci_e_init(__hal_device_t *hldev)
248{
249	int i;
250	u16 cmd;
251	u32 *ptr_32;
252
253	vxge_assert(hldev != NULL);
254
255	vxge_hal_trace_log_device("==> %s:%s:%d",
256	    __FILE__, __func__, __LINE__);
257
258	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
259	    (ptr_t) hldev);
260
261	/* save original PCI config space to restore it on device_terminate() */
262	ptr_32 = (u32 *) ((void *) &hldev->pci_config_space_bios);
263	for (i = 0; i < VXGE_HAL_PCI_CONFIG_SPACE_SIZE / 4; i++) {
264		(void) __hal_vpath_pci_read(hldev,
265		    hldev->first_vp_id,
266		    i * 4,
267		    4,
268		    ptr_32 + i);
269	}
270
271	__hal_device_pci_caps_list_process(hldev);
272
273	/* Set the PErr Repconse bit and SERR in PCI command register. */
274	(void) __hal_vpath_pci_read(hldev,
275	    hldev->first_vp_id,
276	    vxge_offsetof(vxge_hal_pci_config_le_t, command),
277	    2,
278	    &cmd);
279	cmd |= 0x140;
280	vxge_os_pci_write16(hldev->header.pdev, hldev->header.cfgh,
281	    vxge_offsetof(vxge_hal_pci_config_le_t, command), cmd);
282
283	/* save PCI config space for future resets */
284	ptr_32 = (u32 *) ((void *) &hldev->pci_config_space);
285	for (i = 0; i < VXGE_HAL_PCI_CONFIG_SPACE_SIZE / 4; i++) {
286		(void) __hal_vpath_pci_read(hldev,
287		    hldev->first_vp_id,
288		    i * 4,
289		    4,
290		    ptr_32 + i);
291	}
292
293	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
294	    __FILE__, __func__, __LINE__);
295}
296
297/*
298 * __hal_device_bus_master_enable
299 * @hldev: HAL device handle.
300 *
301 * Enable bus mastership.
302 */
303static void
304__hal_device_bus_master_enable(__hal_device_t *hldev)
305{
306	u16 cmd;
307	u16 bus_master = 4;
308
309	vxge_assert(hldev != NULL);
310
311	vxge_hal_trace_log_device("==> %s:%s:%d",
312	    __FILE__, __func__, __LINE__);
313
314	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
315	    (ptr_t) hldev);
316
317	(void) __hal_vpath_pci_read(hldev,
318	    hldev->first_vp_id,
319	    vxge_offsetof(vxge_hal_pci_config_le_t, command),
320	    2,
321	    &cmd);
322	/* already enabled? do nothing */
323	if (cmd & bus_master)
324		return;
325
326	cmd |= bus_master;
327	vxge_os_pci_write16(hldev->header.pdev, hldev->header.cfgh,
328	    vxge_offsetof(vxge_hal_pci_config_le_t, command), cmd);
329
330	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
331	    __FILE__, __func__, __LINE__);
332}
333
334/*
335 * vxge_hal_device_register_poll
336 * @pdev: PCI device object.
337 * @regh: BAR mapped memory handle (Solaris), or simply PCI device @pdev
338 *	(Linux and the rest.)
339 * @reg: register to poll for
340 * @op: 0 - bit reset, 1 - bit set
341 * @mask: mask for logical "and" condition based on %op
342 * @max_millis: maximum time to try to poll in milliseconds
343 *
344 * Will poll certain register for specified amount of time.
345 * Will poll until masked bit is not cleared.
346 */
347vxge_hal_status_e
348vxge_hal_device_register_poll(
349    pci_dev_h pdev,
350    pci_reg_h regh,
351    u64 *reg,
352    u32 op,
353    u64 mask,
354    u32 max_millis)
355{
356	u64 val64;
357	u32 i = 0;
358	vxge_hal_status_e ret = VXGE_HAL_FAIL;
359
360	vxge_os_udelay(10);
361
362	do {
363		val64 = vxge_os_pio_mem_read64(pdev, regh, reg);
364		if (op == 0 && !(val64 & mask)) {
365			return (VXGE_HAL_OK);
366		} else if (op == 1 && (val64 & mask) == mask)
367			return (VXGE_HAL_OK);
368		vxge_os_udelay(100);
369	} while (++i <= 9);
370
371	do {
372		val64 = vxge_os_pio_mem_read64(pdev, regh, reg);
373		if (op == 0 && !(val64 & mask)) {
374			return (VXGE_HAL_OK);
375		} else if (op == 1 && (val64 & mask) == mask) {
376			return (VXGE_HAL_OK);
377		}
378		vxge_os_udelay(1000);
379	} while (++i < max_millis);
380
381	return (ret);
382}
383
384/*
385 * __hal_device_register_stall
386 * @pdev: PCI device object.
387 * @regh: BAR mapped memory handle (Solaris), or simply PCI device @pdev
388 *	(Linux and the rest.)
389 * @reg: register to poll for
390 * @op: 0 - bit reset, 1 - bit set
391 * @mask: mask for logical "and" condition based on %op
392 * @max_millis: maximum time to try to poll in milliseconds
393 *
394 * Will poll certain register for specified amount of time.
395 * Will poll until masked bit is not cleared.
396 */
397vxge_hal_status_e
398__hal_device_register_stall(
399    pci_dev_h pdev,
400    pci_reg_h regh,
401    u64 *reg,
402    u32 op,
403    u64 mask,
404    u32 max_millis)
405{
406	u64 val64;
407	u32 i = 0;
408	vxge_hal_status_e ret = VXGE_HAL_FAIL;
409
410	vxge_os_stall(10);
411
412	do {
413		val64 = vxge_os_pio_mem_read64(pdev, regh, reg);
414		if (op == 0 && !(val64 & mask)) {
415			return (VXGE_HAL_OK);
416		} else if (op == 1 && (val64 & mask) == mask)
417			return (VXGE_HAL_OK);
418		vxge_os_stall(100);
419	} while (++i <= 9);
420
421	do {
422		val64 = vxge_os_pio_mem_read64(pdev, regh, reg);
423		if (op == 0 && !(val64 & mask)) {
424			return (VXGE_HAL_OK);
425		} else if (op == 1 && (val64 & mask) == mask) {
426			return (VXGE_HAL_OK);
427		}
428		vxge_os_stall(1000);
429	} while (++i < max_millis);
430
431	return (ret);
432}
433
434void*
435vxge_hal_device_get_legacy_reg(pci_dev_h pdev, pci_reg_h regh, u8 *bar0)
436{
437	vxge_hal_legacy_reg_t *legacy_reg = NULL;
438
439	/*
440	 * If length of Bar0 is 16MB, then assume we are configured
441	 * in MF8P_VP2 mode and add 8MB to get legacy_reg offsets
442	 */
443	if (vxge_os_pci_res_len(pdev, regh) == 0x1000000)
444		legacy_reg = (vxge_hal_legacy_reg_t *)
445		    ((void *) (bar0 + 0x800000));
446	else
447		legacy_reg = (vxge_hal_legacy_reg_t *)
448		    ((void *) bar0);
449
450	return (legacy_reg);
451}
452
453/*
454 * __hal_device_reg_addr_get
455 * @hldev: HAL Device object.
456 *
457 * This routine sets the swapper and reads the toc pointer and initializes the
458 * register location pointers in the device object. It waits until the ric is
459 * completed initializing registers.
460 */
461vxge_hal_status_e
462__hal_device_reg_addr_get(__hal_device_t *hldev)
463{
464	u64 val64;
465	u32 i;
466	vxge_hal_status_e status = VXGE_HAL_OK;
467
468	vxge_assert(hldev);
469
470	vxge_hal_trace_log_device("==> %s:%s:%d",
471	    __FILE__, __func__, __LINE__);
472
473	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
474	    (ptr_t) hldev);
475
476	hldev->legacy_reg = (vxge_hal_legacy_reg_t *)
477	    vxge_hal_device_get_legacy_reg(hldev->header.pdev,
478		hldev->header.regh0, hldev->header.bar0);
479
480	status = __hal_legacy_swapper_set(hldev->header.pdev,
481	    hldev->header.regh0,
482	    hldev->legacy_reg);
483
484	if (status != VXGE_HAL_OK) {
485		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
486		    __FILE__, __func__, __LINE__, status);
487		return (status);
488	}
489
490	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
491	    hldev->header.regh0,
492	    &hldev->legacy_reg->toc_first_pointer);
493
494	hldev->toc_reg = (vxge_hal_toc_reg_t *)
495	    ((void *) (hldev->header.bar0 + val64));
496
497	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
498	    hldev->header.regh0,
499	    &hldev->toc_reg->toc_common_pointer);
500
501	hldev->common_reg = (vxge_hal_common_reg_t *)
502	    ((void *) (hldev->header.bar0 + val64));
503
504	vxge_hal_info_log_device("COMMON = 0x"VXGE_OS_STXFMT,
505	    (ptr_t) hldev->common_reg);
506
507	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
508	    hldev->header.regh0,
509	    &hldev->toc_reg->toc_memrepair_pointer);
510
511	hldev->memrepair_reg = (vxge_hal_memrepair_reg_t *)
512	    ((void *) (hldev->header.bar0 + val64));
513
514	vxge_hal_info_log_device("MEM REPAIR = 0x"VXGE_OS_STXFMT,
515	    (ptr_t) hldev->memrepair_reg);
516
517	for (i = 0; i < VXGE_HAL_TITAN_PCICFGMGMT_REG_SPACES; i++) {
518		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
519		    hldev->header.regh0,
520		    &hldev->toc_reg->toc_pcicfgmgmt_pointer[i]);
521
522		hldev->pcicfgmgmt_reg[i] = (vxge_hal_pcicfgmgmt_reg_t *)
523		    ((void *) (hldev->header.bar0 + val64));
524		vxge_hal_info_log_device("PCICFG_MGMT[%d] = "
525		    "0x"VXGE_OS_STXFMT, i, (ptr_t) hldev->pcicfgmgmt_reg[i]);
526	}
527
528	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
529	    hldev->header.regh0,
530	    &hldev->toc_reg->toc_mrpcim_pointer);
531
532	hldev->mrpcim_reg = (vxge_hal_mrpcim_reg_t *)
533	    ((void *) (hldev->header.bar0 + val64));
534
535	vxge_hal_info_log_device("MEM REPAIR = 0x"VXGE_OS_STXFMT,
536	    (ptr_t) hldev->mrpcim_reg);
537
538	for (i = 0; i < VXGE_HAL_TITAN_SRPCIM_REG_SPACES; i++) {
539
540		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
541		    hldev->header.regh0,
542		    &hldev->toc_reg->toc_srpcim_pointer[i]);
543
544		hldev->srpcim_reg[i] = (vxge_hal_srpcim_reg_t *)
545		    ((void *) (hldev->header.bar0 + val64));
546		vxge_hal_info_log_device("SRPCIM[%d] =0x"VXGE_OS_STXFMT, i,
547		    (ptr_t) hldev->srpcim_reg[i]);
548	}
549
550	for (i = 0; i < VXGE_HAL_TITAN_VPMGMT_REG_SPACES; i++) {
551
552		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
553		    hldev->header.regh0,
554		    &hldev->toc_reg->toc_vpmgmt_pointer[i]);
555
556		hldev->vpmgmt_reg[i] = (vxge_hal_vpmgmt_reg_t *)
557		    ((void *) (hldev->header.bar0 + val64));
558
559		vxge_hal_info_log_device("VPMGMT[%d] = 0x"VXGE_OS_STXFMT, i,
560		    (ptr_t) hldev->vpmgmt_reg[i]);
561	}
562
563	for (i = 0; i < VXGE_HAL_TITAN_VPATH_REG_SPACES; i++) {
564
565		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
566		    hldev->header.regh0,
567		    &hldev->toc_reg->toc_vpath_pointer[i]);
568
569		hldev->vpath_reg[i] = (vxge_hal_vpath_reg_t *)
570		    ((void *) (hldev->header.bar0 + val64));
571
572		vxge_hal_info_log_device("VPATH[%d] = 0x"VXGE_OS_STXFMT, i,
573		    (ptr_t) hldev->vpath_reg[i]);
574
575	}
576
577	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
578	    hldev->header.regh0,
579	    &hldev->toc_reg->toc_kdfc);
580
581	switch (VXGE_HAL_TOC_GET_KDFC_INITIAL_BIR(val64)) {
582	case 0:
583		hldev->kdfc = hldev->header.bar0 +
584		    VXGE_HAL_TOC_GET_KDFC_INITIAL_OFFSET(val64);
585		break;
586	case 2:
587		hldev->kdfc = hldev->header.bar1 +
588		    VXGE_HAL_TOC_GET_KDFC_INITIAL_OFFSET(val64);
589		break;
590	case 4:
591		hldev->kdfc = hldev->header.bar2 +
592		    VXGE_HAL_TOC_GET_KDFC_INITIAL_OFFSET(val64);
593		break;
594	default:
595		vxge_hal_info_log_device("Invalid BIR = 0x"VXGE_OS_STXFMT,
596		    (ptr_t) VXGE_HAL_TOC_GET_KDFC_INITIAL_BIR(val64));
597		break;
598	}
599
600	vxge_hal_info_log_device("KDFC = 0x"VXGE_OS_STXFMT,
601	    (ptr_t) hldev->kdfc);
602
603	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
604	    hldev->header.regh0,
605	    &hldev->toc_reg->toc_usdc);
606
607	switch (VXGE_HAL_TOC_GET_USDC_INITIAL_BIR(val64)) {
608	case 0:
609		hldev->usdc = hldev->header.bar0 +
610		    VXGE_HAL_TOC_GET_USDC_INITIAL_OFFSET(val64);
611		break;
612	case 2:
613		hldev->usdc = hldev->header.bar1 +
614		    VXGE_HAL_TOC_GET_USDC_INITIAL_OFFSET(val64);
615		break;
616	case 4:
617		hldev->usdc = hldev->header.bar2 +
618		    VXGE_HAL_TOC_GET_USDC_INITIAL_OFFSET(val64);
619		break;
620	default:
621		vxge_hal_info_log_device("Invalid BIR = 0x"VXGE_OS_STXFMT,
622		    (ptr_t) VXGE_HAL_TOC_GET_USDC_INITIAL_BIR(val64));
623		break;
624	}
625
626	vxge_hal_info_log_device("USDC = 0x"VXGE_OS_STXFMT,
627	    (ptr_t) hldev->usdc);
628
629	status = vxge_hal_device_register_poll(hldev->header.pdev,
630	    hldev->header.regh0,
631	    &hldev->common_reg->vpath_rst_in_prog, 0,
632	    VXGE_HAL_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(0x1ffff),
633	    VXGE_HAL_DEF_DEVICE_POLL_MILLIS);
634
635	if (status != VXGE_HAL_OK) {
636		vxge_hal_err_log_device("%s:vpath_rst_in_prog is not cleared",
637		    __func__);
638	}
639
640	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
641	    __FILE__, __func__, __LINE__, status);
642
643	return (status);
644}
645
646/*
647 * __hal_device_id_get
648 * @hldev: HAL Device object.
649 *
650 * This routine returns sets the device id and revision numbers into the device
651 * structure
652 */
653void
654__hal_device_id_get(__hal_device_t *hldev)
655{
656	vxge_assert(hldev);
657
658	vxge_hal_trace_log_device("==> %s:%s:%d",
659	    __FILE__, __func__, __LINE__);
660
661	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
662	    (ptr_t) hldev);
663
664	(void) __hal_vpath_pci_read(hldev,
665	    hldev->first_vp_id,
666	    vxge_offsetof(vxge_hal_pci_config_le_t, device_id),
667	    2,
668	    &hldev->header.device_id);
669
670	(void) __hal_vpath_pci_read(hldev,
671	    hldev->first_vp_id,
672	    vxge_offsetof(vxge_hal_pci_config_le_t, revision),
673	    2,
674	    &hldev->header.revision);
675
676	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
677	    __FILE__, __func__, __LINE__);
678}
679
680/*
681 * __hal_device_access_rights_get: Get Access Rights of the driver
682 * @host_type: Host type.
683 * @func_id: Function Id
684 *
685 * This routine returns the Access Rights of the driver
686 */
687u32
688__hal_device_access_rights_get(u32 host_type, u32 func_id)
689{
690	u32 access_rights = VXGE_HAL_DEVICE_ACCESS_RIGHT_VPATH;
691
692	switch (host_type) {
693	case VXGE_HAL_NO_MR_NO_SR_NORMAL_FUNCTION:
694		if (func_id == 0) {
695			access_rights |=
696			    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM |
697			    VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM;
698		}
699		break;
700	case VXGE_HAL_MR_NO_SR_VH0_BASE_FUNCTION:
701		access_rights |= VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM |
702		    VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM;
703		break;
704	case VXGE_HAL_NO_MR_SR_VH0_FUNCTION0:
705		access_rights |= VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM |
706		    VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM;
707		break;
708	case VXGE_HAL_NO_MR_SR_VH0_VIRTUAL_FUNCTION:
709	case VXGE_HAL_SR_VH_VIRTUAL_FUNCTION:
710		break;
711	case VXGE_HAL_MR_SR_VH0_INVALID_CONFIG:
712		break;
713	case VXGE_HAL_SR_VH_FUNCTION0:
714	case VXGE_HAL_VH_NORMAL_FUNCTION:
715		access_rights |= VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM;
716		break;
717	}
718
719	return (access_rights);
720}
721
722/*
723 * __hal_device_host_info_get
724 * @hldev: HAL Device object.
725 *
726 * This routine returns the host type assignments
727 */
728void
729__hal_device_host_info_get(__hal_device_t *hldev)
730{
731	u64 val64;
732	u32 i;
733
734	vxge_assert(hldev);
735
736	vxge_hal_trace_log_device("==> %s:%s:%d",
737	    __FILE__, __func__, __LINE__);
738
739	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
740	    (ptr_t) hldev);
741
742	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
743	    hldev->header.regh0,
744	    &hldev->common_reg->host_type_assignments);
745
746	hldev->host_type = (u32)
747	    VXGE_HAL_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
748
749	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
750	    hldev->header.regh0,
751	    &hldev->common_reg->vplane_assignments);
752
753	hldev->srpcim_id = (u32)
754	    VXGE_HAL_VPLANE_ASSIGNMENTS_GET_VPLANE_ASSIGNMENTS(val64);
755
756	hldev->vpath_assignments = vxge_os_pio_mem_read64(
757	    hldev->header.pdev,
758	    hldev->header.regh0,
759	    &hldev->common_reg->vpath_assignments);
760
761	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
762
763		if (!(hldev->vpath_assignments & mBIT(i)))
764			continue;
765
766		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
767		    hldev->header.regh0,
768		    &hldev->common_reg->debug_assignments);
769		hldev->vh_id =
770		    (u32) VXGE_HAL_DEBUG_ASSIGNMENTS_GET_VHLABEL(val64);
771
772		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
773		    hldev->header.regh0,
774		    &hldev->vpmgmt_reg[i]->vpath_to_func_map_cfg1);
775		hldev->func_id =
776		    (u32) VXGE_HAL_VPATH_TO_FUNC_MAP_CFG1_GET_CFG1(val64);
777
778		hldev->access_rights = __hal_device_access_rights_get(
779		    hldev->host_type, hldev->func_id);
780
781		if (hldev->access_rights &
782		    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM) {
783			hldev->manager_up = TRUE;
784		} else {
785			val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
786			    hldev->header.regh0,
787			    &hldev->vpmgmt_reg[i]->srpcim_to_vpath_wmsg);
788
789			hldev->manager_up = __hal_ifmsg_is_manager_up(val64);
790		}
791
792		hldev->first_vp_id = i;
793
794		break;
795
796	}
797
798	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
799	    __FILE__, __func__, __LINE__);
800}
801
802/*
803 * __hal_device_pci_e_info_get - Get PCI_E bus informations such as link_width
804 *				  and signalling rate
805 * @hldev: HAL device.
806 * @signalling_rate:	pointer to a variable of enumerated type
807 *			vxge_hal_pci_e_signalling_rate_e {}.
808 * @link_width:		pointer to a variable of enumerated type
809 *			vxge_hal_pci_e_link_width_e {}.
810 *
811 * Get pci-e signalling rate and link width.
812 *
813 * Returns: one of the vxge_hal_status_e {} enumerated types.
814 * VXGE_HAL_OK			- for success.
815 * VXGE_HAL_ERR_INVALID_PCI_INFO - for invalid PCI information from the card.
816 * VXGE_HAL_ERR_BAD_DEVICE_ID	- for invalid card.
817 *
818 */
819static vxge_hal_status_e
820__hal_device_pci_e_info_get(
821    __hal_device_t *hldev,
822    vxge_hal_pci_e_signalling_rate_e *signalling_rate,
823    vxge_hal_pci_e_link_width_e *link_width)
824{
825	vxge_hal_status_e status = VXGE_HAL_OK;
826	vxge_hal_pci_e_capability_t *pci_e_caps;
827
828	vxge_assert((hldev != NULL) && (signalling_rate != NULL) &&
829	    (link_width != NULL));
830
831	vxge_hal_trace_log_device("==> %s:%s:%d",
832	    __FILE__, __func__, __LINE__);
833
834	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT
835	    ", signalling_rate = 0x"VXGE_OS_STXFMT", "
836	    "link_width = 0x"VXGE_OS_STXFMT, (ptr_t) hldev,
837	    (ptr_t) signalling_rate, (ptr_t) link_width);
838
839	pci_e_caps = (vxge_hal_pci_e_capability_t *)
840	    (((u8 *) &hldev->pci_config_space_bios) + hldev->pci_e_caps);
841
842	switch (pci_e_caps->pci_e_lnkcap & VXGE_HAL_PCI_EXP_LNKCAP_LNK_SPEED) {
843	case VXGE_HAL_PCI_EXP_LNKCAP_LS_2_5:
844		*signalling_rate = VXGE_HAL_PCI_E_SIGNALLING_RATE_2_5GB;
845		break;
846	case VXGE_HAL_PCI_EXP_LNKCAP_LS_5:
847		*signalling_rate = VXGE_HAL_PCI_E_SIGNALLING_RATE_5GB;
848		break;
849	default:
850		*signalling_rate =
851		    VXGE_HAL_PCI_E_SIGNALLING_RATE_UNKNOWN;
852		break;
853	}
854
855	switch ((pci_e_caps->pci_e_lnksta &
856	    VXGE_HAL_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4) {
857	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X1:
858		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X1;
859		break;
860	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X2:
861		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X2;
862		break;
863	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X4:
864		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X4;
865		break;
866	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X8:
867		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X8;
868		break;
869	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X12:
870		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X12;
871		break;
872	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X16:
873		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X16;
874		break;
875	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X32:
876		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X32;
877		break;
878	case VXGE_HAL_PCI_EXP_LNKCAP_LW_RES:
879	default:
880		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_UNKNOWN;
881		break;
882	}
883
884	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
885	    __FILE__, __func__, __LINE__);
886	return (status);
887}
888
889/*
890 * __hal_device_hw_initialize
891 * @hldev: HAL device handle.
892 *
893 * Initialize X3100-V hardware.
894 */
895vxge_hal_status_e
896__hal_device_hw_initialize(__hal_device_t *hldev)
897{
898	vxge_hal_status_e status = VXGE_HAL_OK;
899
900	vxge_assert(hldev);
901
902	vxge_hal_trace_log_device("==> %s:%s:%d",
903	    __FILE__, __func__, __LINE__);
904
905	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
906	    (ptr_t) hldev);
907
908	__hal_device_pci_e_init(hldev);
909
910	/* update the pci mode, frequency, and width */
911	if (__hal_device_pci_e_info_get(hldev, &hldev->header.signalling_rate,
912	    &hldev->header.link_width) != VXGE_HAL_OK) {
913		hldev->header.signalling_rate =
914		    VXGE_HAL_PCI_E_SIGNALLING_RATE_UNKNOWN;
915		hldev->header.link_width = VXGE_HAL_PCI_E_LINK_WIDTH_UNKNOWN;
916		/*
917		 * FIXME: this cannot happen.
918		 * But if it happens we cannot continue just like that
919		 */
920		vxge_hal_err_log_device("unable to get pci info == > %s : %d",
921		    __func__, __LINE__);
922	}
923
924	if (hldev->access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM) {
925		status = __hal_srpcim_initialize(hldev);
926	}
927
928	if (hldev->access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM) {
929		status = __hal_mrpcim_initialize(hldev);
930	}
931
932	if (status == VXGE_HAL_OK) {
933		hldev->hw_is_initialized = 1;
934		hldev->header.terminating = 0;
935	}
936
937	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
938	    __FILE__, __func__, __LINE__, status);
939	return (status);
940}
941
942/*
943 * vxge_hal_device_reset - Reset device.
944 * @devh: HAL device handle.
945 *
946 * Soft-reset the device, reset the device stats except reset_cnt.
947 *
948 *
949 * Returns:  VXGE_HAL_OK - success.
950 * VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED - Device is not initialized.
951 * VXGE_HAL_ERR_RESET_FAILED - Reset failed.
952 *
953 * See also: vxge_hal_status_e {}.
954 */
955vxge_hal_status_e
956vxge_hal_device_reset(vxge_hal_device_h devh)
957{
958	u32 i;
959	vxge_hal_status_e status = VXGE_HAL_OK;
960	__hal_device_t *hldev = (__hal_device_t *) devh;
961
962	vxge_assert(devh);
963
964	vxge_hal_trace_log_device("==> %s:%s:%d",
965	    __FILE__, __func__, __LINE__);
966
967	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
968	    (ptr_t) devh);
969
970	if (!hldev->header.is_initialized) {
971		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
972		    __FILE__, __func__, __LINE__,
973		    VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED);
974		return (VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED);
975	}
976
977	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
978
979		if (!(hldev->vpaths_deployed & mBIT(i)))
980			continue;
981
982		status = vxge_hal_vpath_reset(
983		    VXGE_HAL_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i]));
984
985		if (status != VXGE_HAL_OK) {
986			vxge_hal_err_log_device("vpath %d Reset Failed", i);
987		}
988
989	}
990
991	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
992	    __FILE__, __func__, __LINE__, status);
993	return (status);
994}
995
996/*
997 * vxge_hal_device_reset_poll - Poll the device for reset complete.
998 * @devh: HAL device handle.
999 *
1000 * Poll the device for reset complete
1001 *
1002 * Returns:  VXGE_HAL_OK - success.
1003 * VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED - Device is not initialized.
1004 * VXGE_HAL_ERR_RESET_FAILED - Reset failed.
1005 *
1006 * See also: vxge_hal_status_e {}.
1007 */
1008vxge_hal_status_e
1009vxge_hal_device_reset_poll(vxge_hal_device_h devh)
1010{
1011	u32 i;
1012	vxge_hal_status_e status = VXGE_HAL_OK;
1013	__hal_device_t *hldev = (__hal_device_t *) devh;
1014
1015	vxge_assert(devh);
1016
1017	vxge_hal_trace_log_device("==> %s:%s:%d",
1018	    __FILE__, __func__, __LINE__);
1019
1020	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1021	    (ptr_t) devh);
1022
1023	if (!hldev->header.is_initialized) {
1024		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1025		    __FILE__, __func__, __LINE__,
1026		    VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED);
1027		return (VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED);
1028	}
1029
1030	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1031
1032		if (!(hldev->vpaths_deployed & mBIT(i)))
1033			continue;
1034
1035		status = vxge_hal_vpath_reset_poll(
1036		    VXGE_HAL_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i]));
1037
1038		if (status != VXGE_HAL_OK) {
1039			vxge_hal_err_log_device("vpath %d Reset Poll Failed",
1040			    i);
1041		}
1042
1043	}
1044
1045	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1046	    __FILE__, __func__, __LINE__, status);
1047
1048	return (status);
1049}
1050
1051/*
1052 * vxge_hal_device_mrpcim_reset_poll - Poll the device for mrpcim reset complete
1053 * @devh: HAL device handle.
1054 *
1055 * Poll the device for mrpcim reset complete
1056 *
1057 * Returns:  VXGE_HAL_OK - success.
1058 * VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED - Device is not initialized.
1059 * VXGE_HAL_ERR_RESET_FAILED - Reset failed.
1060 * VXGE_HAL_ERR_MANAGER_NOT_FOUND - MRPCIM/SRPCIM manager not found
1061 * VXGE_HAL_ERR_TIME_OUT - Device Reset timed out
1062 *
1063 * See also: vxge_hal_status_e {}.
1064 */
1065vxge_hal_status_e
1066vxge_hal_device_mrpcim_reset_poll(vxge_hal_device_h devh)
1067{
1068	u32 i = 0;
1069	vxge_hal_status_e status = VXGE_HAL_OK;
1070	__hal_device_t *hldev = (__hal_device_t *) devh;
1071
1072	vxge_assert(devh);
1073
1074	vxge_hal_trace_log_device("==> %s:%s:%d",
1075	    __FILE__, __func__, __LINE__);
1076
1077	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1078	    (ptr_t) devh);
1079
1080	if (!hldev->header.is_initialized) {
1081		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1082		    __FILE__, __func__, __LINE__,
1083		    VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED);
1084		return (VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED);
1085	}
1086
1087	if (!hldev->manager_up) {
1088		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1089		    __FILE__, __func__, __LINE__,
1090		    VXGE_HAL_ERR_MANAGER_NOT_FOUND);
1091		return (VXGE_HAL_ERR_MANAGER_NOT_FOUND);
1092	}
1093
1094	status = __hal_ifmsg_device_reset_end_poll(
1095	    hldev, hldev->first_vp_id);
1096
1097	if (status != VXGE_HAL_OK) {
1098		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1099		    __FILE__, __func__, __LINE__,
1100		    VXGE_HAL_ERR_TIME_OUT);
1101		return (VXGE_HAL_ERR_TIME_OUT);
1102	}
1103
1104	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1105
1106		if (!(hldev->vpaths_deployed & mBIT(i)))
1107			continue;
1108
1109		status = vxge_hal_vpath_reset_poll(
1110		    VXGE_HAL_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i]));
1111
1112		if (status != VXGE_HAL_OK) {
1113			vxge_hal_err_log_device("vpath %d Reset Poll Failed",
1114			    i);
1115		}
1116
1117	}
1118
1119	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1120	    __FILE__, __func__, __LINE__, status);
1121
1122	return (status);
1123}
1124
1125/*
1126 * vxge_hal_device_status - Check whether X3100 hardware is ready for
1127 * operation.
1128 * @devh: HAL device handle.
1129 * @hw_status: X3100 status register. Returned by HAL.
1130 *
1131 * Check whether X3100 hardware is ready for operation.
1132 * The checking includes TDMA, RDMA, PFC, PIC, MC_DRAM, and the rest
1133 * hardware functional blocks.
1134 *
1135 * Returns: VXGE_HAL_OK if the device is ready for operation. Otherwise
1136 * returns VXGE_HAL_FAIL. Also, fills in  adapter status (in @hw_status).
1137 *
1138 * See also: vxge_hal_status_e {}.
1139 * Usage: See ex_open {}.
1140 */
1141vxge_hal_status_e
1142vxge_hal_device_status(vxge_hal_device_h devh, u64 *hw_status)
1143{
1144	__hal_device_t *hldev = (__hal_device_t *) devh;
1145
1146	vxge_assert((hldev != NULL) && (hw_status != NULL));
1147
1148	vxge_hal_trace_log_device("==> %s:%s:%d",
1149	    __FILE__, __func__, __LINE__);
1150
1151	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1152	    (ptr_t) devh);
1153
1154	*hw_status = vxge_os_pio_mem_read64(hldev->header.pdev,
1155	    hldev->header.regh0,
1156	    &hldev->common_reg->adapter_status);
1157
1158	vxge_hal_trace_log_device("Adapter_Status = 0x"VXGE_OS_LLXFMT,
1159	    *hw_status);
1160
1161	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_RTDMA_RTDMA_READY)) {
1162		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1163		    __FILE__, __func__, __LINE__,
1164		    VXGE_HAL_ERR_RTDMA_RTDMA_READY);
1165		return (VXGE_HAL_ERR_RTDMA_RTDMA_READY);
1166	}
1167
1168	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_WRDMA_WRDMA_READY)) {
1169		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1170		    __FILE__, __func__, __LINE__,
1171		    VXGE_HAL_ERR_WRDMA_WRDMA_READY);
1172		return (VXGE_HAL_ERR_WRDMA_WRDMA_READY);
1173	}
1174
1175	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_KDFC_KDFC_READY)) {
1176		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1177		    __FILE__, __func__, __LINE__,
1178		    VXGE_HAL_ERR_KDFC_KDFC_READY);
1179		return (VXGE_HAL_ERR_KDFC_KDFC_READY);
1180	}
1181
1182	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_TPA_TMAC_BUF_EMPTY)) {
1183		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1184		    __FILE__, __func__, __LINE__,
1185		    VXGE_HAL_ERR_TPA_TMAC_BUF_EMPTY);
1186		return (VXGE_HAL_ERR_TPA_TMAC_BUF_EMPTY);
1187	}
1188
1189	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_RDCTL_PIC_QUIESCENT)) {
1190		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1191		    __FILE__, __func__, __LINE__,
1192		    VXGE_HAL_ERR_RDCTL_PIC_QUIESCENT);
1193		return (VXGE_HAL_ERR_RDCTL_PIC_QUIESCENT);
1194	}
1195
1196	if (*hw_status & VXGE_HAL_ADAPTER_STATUS_XGMAC_NETWORK_FAULT) {
1197		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1198		    __FILE__, __func__, __LINE__,
1199		    VXGE_HAL_ERR_XGMAC_NETWORK_FAULT);
1200		return (VXGE_HAL_ERR_XGMAC_NETWORK_FAULT);
1201	}
1202
1203	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_ROCRC_OFFLOAD_QUIESCENT)) {
1204		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1205		    __FILE__, __func__, __LINE__,
1206		    VXGE_HAL_ERR_ROCRC_OFFLOAD_QUIESCENT);
1207		return (VXGE_HAL_ERR_ROCRC_OFFLOAD_QUIESCENT);
1208	}
1209
1210	if (!(*hw_status &
1211	    VXGE_HAL_ADAPTER_STATUS_G3IF_FB_G3IF_FB_GDDR3_READY)) {
1212		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1213		    __FILE__, __func__, __LINE__,
1214		    VXGE_HAL_ERR_G3IF_FB_G3IF_FB_GDDR3_READY);
1215		return (VXGE_HAL_ERR_G3IF_FB_G3IF_FB_GDDR3_READY);
1216	}
1217
1218	if (!(*hw_status &
1219	    VXGE_HAL_ADAPTER_STATUS_G3IF_CM_G3IF_CM_GDDR3_READY)) {
1220		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1221		    __FILE__, __func__, __LINE__,
1222		    VXGE_HAL_ERR_G3IF_CM_G3IF_CM_GDDR3_READY);
1223		return (VXGE_HAL_ERR_G3IF_CM_G3IF_CM_GDDR3_READY);
1224	}
1225
1226#ifndef	VXGE_HAL_TITAN_EMULATION
1227	if (*hw_status & VXGE_HAL_ADAPTER_STATUS_RIC_RIC_RUNNING) {
1228		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1229		    __FILE__, __func__, __LINE__,
1230		    VXGE_HAL_ERR_RIC_RIC_RUNNING);
1231		return (VXGE_HAL_ERR_RIC_RIC_RUNNING);
1232	}
1233#endif
1234
1235	if (*hw_status & VXGE_HAL_ADAPTER_STATUS_CMG_C_PLL_IN_LOCK) {
1236		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1237		    __FILE__, __func__, __LINE__,
1238		    VXGE_HAL_ERR_CMG_C_PLL_IN_LOCK);
1239		return (VXGE_HAL_ERR_CMG_C_PLL_IN_LOCK);
1240	}
1241
1242	if (*hw_status & VXGE_HAL_ADAPTER_STATUS_XGMAC_X_PLL_IN_LOCK) {
1243		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1244		    __FILE__, __func__, __LINE__,
1245		    VXGE_HAL_ERR_XGMAC_X_PLL_IN_LOCK);
1246		return (VXGE_HAL_ERR_XGMAC_X_PLL_IN_LOCK);
1247	}
1248
1249	if (*hw_status & VXGE_HAL_ADAPTER_STATUS_FBIF_M_PLL_IN_LOCK) {
1250		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1251		    __FILE__, __func__, __LINE__,
1252		    VXGE_HAL_ERR_FBIF_M_PLL_IN_LOCK);
1253		return (VXGE_HAL_ERR_FBIF_M_PLL_IN_LOCK);
1254	}
1255
1256	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_PCC_PCC_IDLE(0xFF))) {
1257		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1258		    __FILE__, __func__, __LINE__,
1259		    VXGE_HAL_ERR_PCC_PCC_IDLE);
1260		return (VXGE_HAL_ERR_PCC_PCC_IDLE);
1261	}
1262
1263	if (!(*hw_status &
1264	    VXGE_HAL_ADAPTER_STATUS_ROCRC_RC_PRC_QUIESCENT(0xFF))) {
1265		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1266		    __FILE__, __func__, __LINE__,
1267		    VXGE_HAL_ERR_ROCRC_RC_PRC_QUIESCENT);
1268		return (VXGE_HAL_ERR_ROCRC_RC_PRC_QUIESCENT);
1269	}
1270
1271	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0x"VXGE_OS_STXFMT,
1272	    __FILE__, __func__, __LINE__, (ptr_t) *hw_status);
1273	return (VXGE_HAL_OK);
1274}
1275
1276/*
1277 * vxge_hal_device_is_slot_freeze
1278 * @devh: the device
1279 *
1280 * Returns non-zero if the slot is freezed.
1281 * The determination is made based on the adapter_status
1282 * register which will never give all FFs, unless PCI read
1283 * cannot go through.
1284 */
1285int
1286vxge_hal_device_is_slot_freeze(vxge_hal_device_h devh)
1287{
1288	__hal_device_t *hldev = (__hal_device_t *) devh;
1289	u16 device_id;
1290	u64 adapter_status;
1291
1292	vxge_assert(devh);
1293
1294	vxge_hal_trace_log_device("==> %s:%s:%d",
1295	    __FILE__, __func__, __LINE__);
1296
1297	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1298	    (ptr_t) devh);
1299
1300	adapter_status = vxge_os_pio_mem_read64(hldev->header.pdev,
1301	    hldev->header.regh0,
1302	    &hldev->common_reg->adapter_status);
1303
1304	(void) __hal_vpath_pci_read(hldev,
1305	    hldev->first_vp_id,
1306	    vxge_offsetof(vxge_hal_pci_config_le_t, device_id),
1307	    2,
1308	    &device_id);
1309	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1310	    __FILE__, __func__, __LINE__,
1311	    (adapter_status == VXGE_HAL_ALL_FOXES) || (device_id == 0xffff));
1312
1313	return ((adapter_status == VXGE_HAL_ALL_FOXES) ||
1314	    (device_id == 0xffff));
1315}
1316
1317/*
1318 * vxge_hal_device_intr_enable - Enable interrupts.
1319 * @devh: HAL device handle.
1320 * @op: One of the vxge_hal_device_intr_e enumerated values specifying
1321 *	  the type(s) of interrupts to enable.
1322 *
1323 * Enable X3100 interrupts. The function is to be executed the last in
1324 * X3100 initialization sequence.
1325 *
1326 * See also: vxge_hal_device_intr_disable()
1327 */
1328void
1329vxge_hal_device_intr_enable(
1330    vxge_hal_device_h devh)
1331{
1332	u32 i;
1333	u64 val64;
1334	u32 val32;
1335	__hal_device_t *hldev = (__hal_device_t *) devh;
1336
1337	vxge_assert(hldev);
1338
1339	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1340	    __FILE__, __func__, __LINE__);
1341
1342	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
1343	    (ptr_t) devh);
1344
1345	vxge_hal_device_mask_all(hldev);
1346
1347	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1348
1349		if (!(hldev->vpaths_deployed & mBIT(i)))
1350			continue;
1351
1352		(void) __hal_vpath_intr_enable(&hldev->virtual_paths[i]);
1353	}
1354
1355	if ((hldev->header.config.intr_mode == VXGE_HAL_INTR_MODE_IRQLINE) ||
1356	    (hldev->header.config.intr_mode == VXGE_HAL_INTR_MODE_EMULATED_INTA)) {
1357
1358		val64 = hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] |
1359		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] |
1360		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_BMAP];
1361
1362		if (val64 != 0) {
1363			vxge_os_pio_mem_write64(hldev->header.pdev,
1364			    hldev->header.regh0,
1365			    val64,
1366			    &hldev->common_reg->tim_int_status0);
1367
1368			vxge_os_pio_mem_write64(hldev->header.pdev,
1369			    hldev->header.regh0,
1370			    ~val64,
1371			    &hldev->common_reg->tim_int_mask0);
1372		}
1373
1374		val32 = hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] |
1375		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] |
1376		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_BMAP];
1377
1378		if (val32 != 0) {
1379			vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
1380			    hldev->header.regh0,
1381			    val32,
1382			    &hldev->common_reg->tim_int_status1);
1383
1384			vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
1385			    hldev->header.regh0,
1386			    ~val32,
1387			    &hldev->common_reg->tim_int_mask1);
1388		}
1389	}
1390
1391	vxge_os_pio_mem_read64(hldev->header.pdev,
1392	    hldev->header.regh0,
1393	    &hldev->common_reg->titan_general_int_status);
1394
1395	vxge_hal_device_unmask_all(hldev);
1396
1397	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1398	    __FILE__, __func__, __LINE__);
1399}
1400
1401/*
1402 * vxge_hal_device_intr_disable - Disable X3100 interrupts.
1403 * @devh: HAL device handle.
1404 * @op: One of the vxge_hal_device_intr_e enumerated values specifying
1405 *	  the type(s) of interrupts to disable.
1406 *
1407 * Disable X3100 interrupts.
1408 *
1409 * See also: vxge_hal_device_intr_enable()
1410 */
1411void
1412vxge_hal_device_intr_disable(
1413    vxge_hal_device_h devh)
1414{
1415	u32 i;
1416	u64 val64;
1417	u32 val32;
1418	__hal_device_t *hldev = (__hal_device_t *) devh;
1419
1420	vxge_assert(hldev);
1421
1422	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1423	    __FILE__, __func__, __LINE__);
1424
1425	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
1426	    (ptr_t) devh);
1427
1428	vxge_hal_device_mask_all(hldev);
1429
1430	if ((hldev->header.config.intr_mode ==
1431	    VXGE_HAL_INTR_MODE_IRQLINE) ||
1432	    (hldev->header.config.intr_mode ==
1433	    VXGE_HAL_INTR_MODE_EMULATED_INTA)) {
1434
1435		val64 = hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] |
1436		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] |
1437		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_BMAP];
1438
1439		if (val64 != 0) {
1440			vxge_os_pio_mem_write64(hldev->header.pdev,
1441			    hldev->header.regh0,
1442			    val64,
1443			    &hldev->common_reg->tim_int_mask0);
1444		}
1445
1446		val32 = hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] |
1447		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] |
1448		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_BMAP];
1449
1450		if (val32 != 0) {
1451			vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
1452			    hldev->header.regh0,
1453			    val32,
1454			    &hldev->common_reg->tim_int_mask1);
1455		}
1456	}
1457
1458	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1459
1460		if (!(hldev->vpaths_deployed & mBIT(i)))
1461			continue;
1462
1463		(void) __hal_vpath_intr_disable(&hldev->virtual_paths[i]);
1464	}
1465
1466	vxge_hal_device_unmask_all(hldev);
1467
1468	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1469	    __FILE__, __func__, __LINE__);
1470}
1471
1472/*
1473 * vxge_hal_device_mask_all - Mask all device interrupts.
1474 * @devh: HAL device handle.
1475 *
1476 * Mask	all	device interrupts.
1477 *
1478 * See also: vxge_hal_device_unmask_all()
1479 */
1480void
1481vxge_hal_device_mask_all(
1482    vxge_hal_device_h devh)
1483{
1484	u64 val64;
1485	__hal_device_t *hldev = (__hal_device_t *) devh;
1486
1487	vxge_assert(hldev);
1488
1489	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1490	    __FILE__, __func__, __LINE__);
1491
1492	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
1493	    (ptr_t) devh);
1494
1495	val64 = VXGE_HAL_TITAN_MASK_ALL_INT_ALARM |
1496	    VXGE_HAL_TITAN_MASK_ALL_INT_TRAFFIC;
1497
1498	vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
1499	    hldev->header.regh0,
1500	    (u32) bVAL32(val64, 0),
1501	    &hldev->common_reg->titan_mask_all_int);
1502
1503	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1504	    __FILE__, __func__, __LINE__);
1505}
1506
1507/*
1508 * vxge_hal_device_unmask_all - Unmask all device interrupts.
1509 * @devh: HAL device handle.
1510 *
1511 * Unmask all device interrupts.
1512 *
1513 * See also: vxge_hal_device_mask_all()
1514 */
1515void
1516vxge_hal_device_unmask_all(
1517    vxge_hal_device_h devh)
1518{
1519	u64 val64 = 0;
1520	__hal_device_t *hldev = (__hal_device_t *) devh;
1521
1522	vxge_assert(hldev);
1523
1524	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1525	    __FILE__, __func__, __LINE__);
1526
1527	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
1528	    (ptr_t) devh);
1529
1530	if (hldev->header.config.intr_mode == VXGE_HAL_INTR_MODE_IRQLINE)
1531		val64 = VXGE_HAL_TITAN_MASK_ALL_INT_TRAFFIC;
1532
1533	vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
1534	    hldev->header.regh0,
1535	    (u32) bVAL32(val64, 0),
1536	    &hldev->common_reg->titan_mask_all_int);
1537
1538	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1539	    __FILE__, __func__, __LINE__);
1540}
1541
1542/*
1543 * vxge_hal_device_begin_irq - Begin IRQ processing.
1544 * @devh: HAL device handle.
1545 * @skip_alarms: Do not clear the alarms
1546 * @reason: "Reason" for the interrupt,	the value of X3100's
1547 *			general_int_status register.
1548 *
1549 * The function	performs two actions, It first checks whether (shared IRQ) the
1550 * interrupt was raised	by the device. Next, it	masks the device interrupts.
1551 *
1552 * Note:
1553 * vxge_hal_device_begin_irq() does not flush MMIO writes through the
1554 * bridge. Therefore, two back-to-back interrupts are potentially possible.
1555 * It is the responsibility	of the ULD to make sure	that only one
1556 * vxge_hal_device_continue_irq() runs at a time.
1557 *
1558 * Returns: 0, if the interrupt	is not "ours" (note that in this case the
1559 * device remain enabled).
1560 * Otherwise, vxge_hal_device_begin_irq() returns 64bit general adapter
1561 * status.
1562 * See also: vxge_hal_device_handle_irq()
1563 */
1564vxge_hal_status_e
1565vxge_hal_device_begin_irq(
1566    vxge_hal_device_h devh,
1567    u32 skip_alarms,
1568    u64 *reason)
1569{
1570	u32 i;
1571	u64 val64;
1572	u64 adapter_status;
1573	u64 vpath_mask;
1574	__hal_device_t *hldev = (__hal_device_t *) devh;
1575	vxge_hal_status_e ret = VXGE_HAL_ERR_WRONG_IRQ;
1576	vxge_hal_status_e status;
1577
1578	vxge_assert((hldev != NULL) && (reason != NULL));
1579
1580	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1581	    __FILE__, __func__, __LINE__);
1582
1583	vxge_hal_trace_log_device_irq(
1584	    "devh = 0x"VXGE_OS_STXFMT", skip_alarms = %d, "
1585	    "reason = 0x"VXGE_OS_STXFMT, (ptr_t) devh,
1586	    skip_alarms, (ptr_t) reason);
1587
1588	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
1589	    hldev->header.regh0,
1590	    &hldev->common_reg->titan_general_int_status);
1591
1592	if (vxge_os_unlikely(!val64)) {
1593		/* not Titan interrupt	 */
1594		*reason = 0;
1595		ret = VXGE_HAL_ERR_WRONG_IRQ;
1596		vxge_hal_info_log_device_irq("wrong_isr general_int_status = \
1597		    0x%llx", val64);
1598		vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = %d",
1599		    __FILE__, __func__, __LINE__, ret);
1600		return (ret);
1601	}
1602
1603	if (vxge_os_unlikely(val64 == VXGE_HAL_ALL_FOXES)) {
1604
1605		adapter_status = vxge_os_pio_mem_read64(hldev->header.pdev,
1606		    hldev->header.regh0,
1607		    &hldev->common_reg->adapter_status);
1608
1609		if (adapter_status == VXGE_HAL_ALL_FOXES) {
1610			vxge_hal_info_log_device_irq("%s:Slot is frozen",
1611			    __func__);
1612			__hal_device_handle_error(hldev,
1613			    NULL_VPID, VXGE_HAL_EVENT_SLOT_FREEZE);
1614			*reason = 0;
1615			ret = VXGE_HAL_ERR_SLOT_FREEZE;
1616			goto exit;
1617
1618		}
1619	}
1620
1621	*reason = val64;
1622
1623	vpath_mask = hldev->vpaths_deployed >>
1624	    (64 - VXGE_HAL_MAX_VIRTUAL_PATHS);
1625
1626	if (val64 &
1627	    VXGE_HAL_TITAN_GENERAL_INT_STATUS_VPATH_TRAFFIC_INT(vpath_mask)) {
1628		hldev->header.traffic_intr_cnt++;
1629		ret = VXGE_HAL_TRAFFIC_INTERRUPT;
1630		vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = %d",
1631		    __FILE__, __func__, __LINE__, ret);
1632		return (ret);
1633	}
1634
1635	hldev->header.not_traffic_intr_cnt++;
1636
1637	if (vxge_os_unlikely(val64 &
1638	    VXGE_HAL_TITAN_GENERAL_INT_STATUS_VPATH_ALARM_INT)) {
1639
1640		for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1641
1642			if (!(hldev->vpaths_deployed & mBIT(i)))
1643				continue;
1644
1645			status = __hal_vpath_alarm_process(
1646			    &hldev->virtual_paths[i],
1647			    skip_alarms);
1648
1649			if (status != VXGE_HAL_ERR_WRONG_IRQ)
1650				ret = status;
1651
1652		}
1653
1654	}
1655exit:
1656	vxge_hal_trace_log_device_irq(
1657	    "<==Error in  %s:%s:%d result = 0x%x general_int_status= 0x%llx",
1658	    __FILE__, __func__, __LINE__, ret, val64);
1659	return (ret);
1660}
1661
1662/*
1663 * vxge_hal_device_continue_irq - Continue handling IRQ:	process	all
1664 *				completed descriptors.
1665 * @devh: HAL device handle.
1666 *
1667 * Process completed descriptors and unmask the	device interrupts.
1668 *
1669 * The vxge_hal_device_continue_irq() walks all open virtual paths
1670 * and calls upper-layer driver	(ULD) via supplied completion
1671 * callback.
1672 *
1673 * Note	that the vxge_hal_device_continue_irq is	part of	the _fast_ path.
1674 * To optimize the processing, the function does _not_ check for
1675 * errors and alarms.
1676 *
1677 * Returns: VXGE_HAL_OK.
1678 *
1679 * See also: vxge_hal_device_handle_irq()
1680 * vxge_hal_ring_rxd_next_completed(),
1681 * vxge_hal_fifo_txdl_next_completed(), vxge_hal_ring_callback_f {},
1682 * vxge_hal_fifo_callback_f {}.
1683 */
1684vxge_hal_status_e
1685vxge_hal_device_continue_irq(
1686    vxge_hal_device_h devh)
1687{
1688	u32 i;
1689	__hal_device_t *hldev = (__hal_device_t *) devh;
1690
1691	vxge_assert(hldev);
1692
1693	vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__,
1694	    __func__, __LINE__);
1695
1696	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
1697	    (ptr_t) devh);
1698
1699	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1700
1701		if (!(hldev->vpaths_deployed & mBIT(i)))
1702			continue;
1703
1704		(void) vxge_hal_vpath_continue_irq(
1705		    VXGE_HAL_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i]));
1706
1707	}
1708
1709	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1710	    __FILE__, __func__, __LINE__);
1711	return (VXGE_HAL_OK);
1712}
1713
1714/*
1715 * vxge_hal_device_handle_irq - Handle device IRQ.
1716 * @devh: HAL device handle.
1717 * @skip_alarms: Do not clear the alarms
1718 *
1719 * Perform the complete	handling of the	line interrupt.	The function
1720 * performs two	calls.
1721 * First it uses vxge_hal_device_begin_irq() to check the reason for
1722 * the interrupt and mask the device interrupts.
1723 * Second, it calls	vxge_hal_device_continue_irq() to process all
1724 * completed descriptors and re-enable the interrupts.
1725 *
1726 * Returns: VXGE_HAL_OK - success;
1727 * VXGE_HAL_ERR_WRONG_IRQ - (shared) IRQ produced by other device.
1728 *
1729 * See also: vxge_hal_device_begin_irq(), vxge_hal_device_continue_irq().
1730 */
1731vxge_hal_status_e
1732vxge_hal_device_handle_irq(
1733    vxge_hal_device_h devh,
1734    u32 skip_alarms)
1735{
1736	u64 reason;
1737	vxge_hal_status_e status;
1738	__hal_device_t *hldev = (__hal_device_t *) devh;
1739
1740	vxge_assert(devh != NULL);
1741
1742	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1743	    __FILE__, __func__, __LINE__);
1744
1745	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT", \
1746	    skip_alarms = %d",
1747	    (ptr_t) devh, skip_alarms);
1748
1749	vxge_hal_device_mask_all(hldev);
1750
1751	status = vxge_hal_device_begin_irq(hldev, skip_alarms, &reason);
1752	if (vxge_os_unlikely(status == VXGE_HAL_ERR_WRONG_IRQ)) {
1753		vxge_hal_device_unmask_all(hldev);
1754		goto exit;
1755	}
1756	if (status == VXGE_HAL_TRAFFIC_INTERRUPT) {
1757
1758		vxge_hal_device_clear_rx(hldev);
1759
1760		status = vxge_hal_device_continue_irq(hldev);
1761
1762		vxge_hal_device_clear_tx(hldev);
1763
1764	}
1765
1766	if (vxge_os_unlikely((status == VXGE_HAL_ERR_CRITICAL) && skip_alarms))
1767		/* ULD needs to unmask explicitely */
1768		goto exit;
1769
1770	vxge_hal_device_unmask_all(hldev);
1771
1772exit:
1773	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = %d",
1774	    __FILE__, __func__, __LINE__, status);
1775	return (status);
1776}
1777
1778/*
1779 * __hal_device_handle_link_up_ind
1780 * @hldev: HAL device handle.
1781 *
1782 * Link up indication handler. The function is invoked by HAL when
1783 * X3100 indicates that the link is up for programmable amount of time.
1784 */
1785vxge_hal_status_e
1786__hal_device_handle_link_up_ind(__hal_device_t *hldev)
1787{
1788	vxge_assert(hldev);
1789
1790	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1791	    __FILE__, __func__, __LINE__);
1792
1793	vxge_hal_trace_log_device_irq("hldev = 0x"VXGE_OS_STXFMT,
1794	    (ptr_t) hldev);
1795
1796	/*
1797	 * If the previous link state is not down, return.
1798	 */
1799	if (hldev->header.link_state == VXGE_HAL_LINK_UP) {
1800		vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1801		    __FILE__, __func__, __LINE__);
1802		return (VXGE_HAL_OK);
1803	}
1804
1805	hldev->header.link_state = VXGE_HAL_LINK_UP;
1806
1807	/* notify ULD */
1808	if (g_vxge_hal_driver->uld_callbacks.link_up) {
1809		g_vxge_hal_driver->uld_callbacks.link_up(
1810		    hldev,
1811		    hldev->header.upper_layer_data);
1812	}
1813
1814	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1815	    __FILE__, __func__, __LINE__);
1816	return (VXGE_HAL_OK);
1817}
1818
1819/*
1820 * __hal_device_handle_link_down_ind
1821 * @hldev: HAL device handle.
1822 *
1823 * Link down indication handler. The function is invoked by HAL when
1824 * X3100 indicates that the link is down.
1825 */
1826vxge_hal_status_e
1827__hal_device_handle_link_down_ind(__hal_device_t *hldev)
1828{
1829	vxge_assert(hldev);
1830
1831	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1832	    __FILE__, __func__, __LINE__);
1833
1834	vxge_hal_trace_log_device_irq("hldev = 0x"VXGE_OS_STXFMT,
1835	    (ptr_t) hldev);
1836
1837	/*
1838	 * If the previous link state is not down, return.
1839	 */
1840	if (hldev->header.link_state == VXGE_HAL_LINK_DOWN) {
1841		vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1842		    __FILE__, __func__, __LINE__);
1843		return (VXGE_HAL_OK);
1844	}
1845
1846	hldev->header.link_state = VXGE_HAL_LINK_DOWN;
1847
1848	/* notify ULD */
1849	if (g_vxge_hal_driver->uld_callbacks.link_down) {
1850		g_vxge_hal_driver->uld_callbacks.link_down(
1851		    hldev,
1852		    hldev->header.upper_layer_data);
1853	}
1854
1855	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1856	    __FILE__, __func__, __LINE__);
1857	return (VXGE_HAL_OK);
1858}
1859
1860/*
1861 * vxge_hal_device_link_state_test - Test the link state.
1862 * @devh: HAL device handle.
1863 *
1864 * Test link state.
1865 * Returns: link state.
1866 */
1867vxge_hal_device_link_state_e
1868vxge_hal_device_link_state_test(
1869    vxge_hal_device_h devh)
1870{
1871	u32 i;
1872	vxge_hal_device_link_state_e status = VXGE_HAL_LINK_NONE;
1873	__hal_device_t *hldev = (__hal_device_t *) devh;
1874
1875	vxge_assert(hldev);
1876
1877	vxge_hal_trace_log_device("==> %s:%s:%d",
1878	    __FILE__, __func__, __LINE__);
1879
1880	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1881	    (ptr_t) devh);
1882
1883	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1884
1885		if (!(hldev->vpath_assignments & mBIT(i)))
1886			continue;
1887
1888		status =
1889		    __hal_vpath_link_state_test(&hldev->virtual_paths[i]);
1890
1891		break;
1892
1893	}
1894
1895	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1896	    __FILE__, __func__, __LINE__, status);
1897	return (status);
1898}
1899
1900/*
1901 * vxge_hal_device_link_state_poll - Poll for the link state.
1902 * @devh: HAL device handle.
1903 *
1904 * Get link state.
1905 * Returns: link state.
1906 */
1907vxge_hal_device_link_state_e
1908vxge_hal_device_link_state_poll(
1909    vxge_hal_device_h devh)
1910{
1911	u32 i;
1912	vxge_hal_device_link_state_e link_state = VXGE_HAL_LINK_NONE;
1913	__hal_device_t *hldev = (__hal_device_t *) devh;
1914
1915	vxge_assert(devh);
1916
1917	vxge_hal_trace_log_device("==> %s:%s:%d",
1918	    __FILE__, __func__, __LINE__);
1919
1920	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1921	    (ptr_t) devh);
1922
1923	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1924
1925		if (!(hldev->vpath_assignments & mBIT(i)))
1926			continue;
1927
1928		hldev->header.link_state = VXGE_HAL_LINK_NONE;
1929
1930		link_state =
1931		    __hal_vpath_link_state_poll(&hldev->virtual_paths[i]);
1932
1933		break;
1934
1935	}
1936
1937	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1938	    __FILE__, __func__, __LINE__, link_state);
1939	return (link_state);
1940}
1941
1942/*
1943 * vxge_hal_device_data_rate_poll - Poll for the data rate.
1944 * @devh: HAL device handle.
1945 *
1946 * Get data rate.
1947 * Returns: data rate.
1948 */
1949vxge_hal_device_data_rate_e
1950vxge_hal_device_data_rate_poll(
1951    vxge_hal_device_h devh)
1952{
1953	u32 i;
1954	vxge_hal_device_data_rate_e data_rate = VXGE_HAL_DATA_RATE_UNKNOWN;
1955	__hal_device_t *hldev = (__hal_device_t *) devh;
1956
1957	vxge_assert(devh);
1958
1959	vxge_hal_trace_log_device("==> %s:%s:%d",
1960	    __FILE__, __func__, __LINE__);
1961
1962	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1963	    (ptr_t) devh);
1964
1965	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1966
1967		if (!(hldev->vpaths_deployed & mBIT(i)))
1968			continue;
1969
1970		data_rate =
1971		    __hal_vpath_data_rate_poll(&hldev->virtual_paths[i]);
1972
1973		break;
1974
1975	}
1976
1977	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1978	    __FILE__, __func__, __LINE__, data_rate);
1979	return (data_rate);
1980}
1981
1982/*
1983 * vxge_hal_device_lag_mode_get - Get Current LAG Mode
1984 * @devh: HAL device handle.
1985 *
1986 * Get Current LAG Mode
1987 */
1988vxge_hal_device_lag_mode_e
1989vxge_hal_device_lag_mode_get(
1990    vxge_hal_device_h devh)
1991{
1992	u32 i;
1993	vxge_hal_device_lag_mode_e lag_mode = VXGE_HAL_DEVICE_LAG_MODE_UNKNOWN;
1994	__hal_device_t *hldev = (__hal_device_t *) devh;
1995
1996	vxge_assert(devh);
1997
1998	vxge_hal_trace_log_device("==> %s:%s:%d",
1999	    __FILE__, __func__, __LINE__);
2000
2001	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
2002	    (ptr_t) devh);
2003
2004	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
2005
2006		if (!(hldev->vpaths_deployed & mBIT(i)))
2007			continue;
2008
2009		lag_mode =
2010		    __hal_vpath_lag_mode_get(&hldev->virtual_paths[i]);
2011
2012		break;
2013
2014	}
2015
2016	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2017	    __FILE__, __func__, __LINE__, lag_mode);
2018	return (lag_mode);
2019}
2020
2021
2022/*
2023 * __hal_device_handle_error - Handle error
2024 * @hldev: HAL device
2025 * @vp_id: Vpath Id
2026 * @type: Error type. Please see vxge_hal_event_e {}
2027 *
2028 * Handle error.
2029 */
2030void
2031__hal_device_handle_error(
2032    __hal_device_t *hldev,
2033    u32 vp_id,
2034    vxge_hal_event_e type)
2035{
2036	vxge_assert(hldev);
2037
2038	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2039	    __FILE__, __func__, __LINE__);
2040
2041	vxge_hal_trace_log_device_irq(
2042	    "hldev = 0x"VXGE_OS_STXFMT", vp_id = %d, type = %d",
2043	    (ptr_t) hldev, vp_id, type);
2044
2045	switch (type) {
2046	default:
2047		vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = %d",
2048		    __FILE__, __func__, __LINE__,
2049		    VXGE_HAL_ERR_INVALID_TYPE);
2050		return;
2051	case VXGE_HAL_EVENT_UNKNOWN:
2052		if (hldev->header.config.dump_on_unknown) {
2053			(void) vxge_hal_aux_device_dump(hldev);
2054		}
2055		break;
2056	case VXGE_HAL_EVENT_SERR:
2057		if (hldev->header.config.dump_on_serr) {
2058			(void) vxge_hal_aux_device_dump(hldev);
2059		}
2060		break;
2061	case VXGE_HAL_EVENT_CRITICAL:
2062	case VXGE_HAL_EVENT_SRPCIM_CRITICAL:
2063	case VXGE_HAL_EVENT_MRPCIM_CRITICAL:
2064		if (hldev->header.config.dump_on_critical) {
2065			(void) vxge_hal_aux_device_dump(hldev);
2066		}
2067		break;
2068	case VXGE_HAL_EVENT_ECCERR:
2069		if (hldev->header.config.dump_on_eccerr) {
2070			(void) vxge_hal_aux_device_dump(hldev);
2071		}
2072		break;
2073	case VXGE_HAL_EVENT_KDFCCTL:
2074		break;
2075	case VXGE_HAL_EVENT_DEVICE_RESET_START:
2076		break;
2077	case VXGE_HAL_EVENT_DEVICE_RESET_COMPLETE:
2078		break;
2079	case VXGE_HAL_EVENT_VPATH_RESET_START:
2080		break;
2081	case VXGE_HAL_EVENT_VPATH_RESET_COMPLETE:
2082		break;
2083	case VXGE_HAL_EVENT_SLOT_FREEZE:
2084		break;
2085	}
2086
2087
2088	/* notify ULD */
2089	if (g_vxge_hal_driver->uld_callbacks.crit_err) {
2090		g_vxge_hal_driver->uld_callbacks.crit_err(
2091		    (vxge_hal_device_h) hldev,
2092		    hldev->header.upper_layer_data,
2093		    type,
2094		    vp_id);
2095	}
2096
2097	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2098	    __FILE__, __func__, __LINE__);
2099}
2100
2101/*
2102 * vxge_hal_device_mask_tx - Mask Tx interrupts.
2103 * @devh: HAL device.
2104 *
2105 * Mask	Tx device interrupts.
2106 *
2107 * See also: vxge_hal_device_unmask_tx(), vxge_hal_device_mask_rx(),
2108 * vxge_hal_device_clear_tx().
2109 */
2110void
2111vxge_hal_device_mask_tx(
2112    vxge_hal_device_h devh)
2113{
2114	__hal_device_t *hldev = (__hal_device_t *) devh;
2115
2116	vxge_assert(devh);
2117
2118	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2119	    __FILE__, __func__, __LINE__);
2120
2121	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2122	    (ptr_t) devh);
2123
2124	if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) {
2125		vxge_os_pio_mem_write64(hldev->header.pdev,
2126		    hldev->header.regh0,
2127		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX],
2128		    &hldev->common_reg->tim_int_mask0);
2129	}
2130
2131	if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) {
2132		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2133		    hldev->header.regh0,
2134		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX],
2135		    &hldev->common_reg->tim_int_mask1);
2136	}
2137
2138	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2139	    __FILE__, __func__, __LINE__);
2140}
2141
2142/*
2143 * vxge_hal_device_clear_tx - Acknowledge (that is, clear) the
2144 * condition that has caused the TX	interrupt.
2145 * @devh: HAL device.
2146 *
2147 * Acknowledge (that is, clear)	the	condition that has caused
2148 * the Tx interrupt.
2149 * See also: vxge_hal_device_begin_irq(), vxge_hal_device_continue_irq(),
2150 * vxge_hal_device_clear_rx(), vxge_hal_device_mask_tx().
2151 */
2152void
2153vxge_hal_device_clear_tx(
2154    vxge_hal_device_h devh)
2155{
2156	__hal_device_t *hldev = (__hal_device_t *) devh;
2157
2158	vxge_assert(devh);
2159
2160	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2161	    __FILE__, __func__, __LINE__);
2162
2163	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2164	    (ptr_t) devh);
2165
2166	if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) {
2167		vxge_os_pio_mem_write64(hldev->header.pdev,
2168		    hldev->header.regh0,
2169		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX],
2170		    &hldev->common_reg->tim_int_status0);
2171	}
2172
2173	if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) {
2174		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2175		    hldev->header.regh0,
2176		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX],
2177		    &hldev->common_reg->tim_int_status1);
2178	}
2179
2180	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2181	    __FILE__, __func__, __LINE__);
2182}
2183
2184/*
2185 * vxge_hal_device_unmask_tx - Unmask Tx	interrupts.
2186 * @devh: HAL device.
2187 *
2188 * Unmask Tx device interrupts.
2189 *
2190 * See also: vxge_hal_device_mask_tx(), vxge_hal_device_clear_tx().
2191 */
2192void
2193vxge_hal_device_unmask_tx(
2194    vxge_hal_device_h devh)
2195{
2196	__hal_device_t *hldev = (__hal_device_t *) devh;
2197
2198	vxge_assert(devh);
2199
2200	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2201	    __FILE__, __func__, __LINE__);
2202
2203	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2204	    (ptr_t) devh);
2205
2206	if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) {
2207		vxge_os_pio_mem_write64(hldev->header.pdev,
2208		    hldev->header.regh0,
2209		    ~(hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX]),
2210		    &hldev->common_reg->tim_int_mask0);
2211	}
2212
2213	if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) {
2214		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2215		    hldev->header.regh0,
2216		    ~(hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX]),
2217		    &hldev->common_reg->tim_int_mask1);
2218	}
2219
2220	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2221	    __FILE__, __func__, __LINE__);
2222}
2223
2224/*
2225 * vxge_hal_device_mask_rx - Mask Rx	interrupts.
2226 * @devh: HAL device.
2227 *
2228 * Mask	Rx device interrupts.
2229 *
2230 * See also: vxge_hal_device_unmask_rx(), vxge_hal_device_mask_tx(),
2231 * vxge_hal_device_clear_rx().
2232 */
2233void
2234vxge_hal_device_mask_rx(
2235    vxge_hal_device_h devh)
2236{
2237	__hal_device_t *hldev = (__hal_device_t *) devh;
2238
2239	vxge_assert(devh);
2240
2241	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2242	    __FILE__, __func__, __LINE__);
2243
2244	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2245	    (ptr_t) devh);
2246
2247	if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0) {
2248		vxge_os_pio_mem_write64(hldev->header.pdev,
2249		    hldev->header.regh0,
2250		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX],
2251		    &hldev->common_reg->tim_int_mask0);
2252	}
2253
2254	if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0) {
2255		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2256		    hldev->header.regh0,
2257		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX],
2258		    &hldev->common_reg->tim_int_mask1);
2259	}
2260
2261	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2262	    __FILE__, __func__, __LINE__);
2263}
2264
2265/*
2266 * vxge_hal_device_clear_rx - Acknowledge (that is, clear) the
2267 * condition that has caused the RX	interrupt.
2268 * @devh: HAL device.
2269 *
2270 * Acknowledge (that is, clear)	the	condition that has caused
2271 * the Rx interrupt.
2272 * See also: vxge_hal_device_begin_irq(), vxge_hal_device_continue_irq(),
2273 * vxge_hal_device_clear_tx(), vxge_hal_device_mask_rx().
2274 */
2275void
2276vxge_hal_device_clear_rx(
2277    vxge_hal_device_h devh)
2278{
2279	__hal_device_t *hldev = (__hal_device_t *) devh;
2280
2281	vxge_assert(devh);
2282
2283	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2284	    __FILE__, __func__, __LINE__);
2285
2286	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2287	    (ptr_t) devh);
2288
2289	if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0) {
2290		vxge_os_pio_mem_write64(hldev->header.pdev,
2291		    hldev->header.regh0,
2292		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX],
2293		    &hldev->common_reg->tim_int_status0);
2294	}
2295
2296	if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0) {
2297		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2298		    hldev->header.regh0,
2299		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX],
2300		    &hldev->common_reg->tim_int_status1);
2301	}
2302
2303	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2304	    __FILE__, __func__, __LINE__);
2305}
2306
2307/*
2308 * vxge_hal_device_unmask_rx - Unmask Rx	interrupts.
2309 * @devh: HAL device.
2310 *
2311 * Unmask Rx device interrupts.
2312 *
2313 * See also: vxge_hal_device_mask_rx(), vxge_hal_device_clear_rx().
2314 */
2315void
2316vxge_hal_device_unmask_rx(
2317    vxge_hal_device_h devh)
2318{
2319	__hal_device_t *hldev = (__hal_device_t *) devh;
2320
2321	vxge_assert(devh);
2322
2323	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2324	    __FILE__, __func__, __LINE__);
2325
2326	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2327	    (ptr_t) devh);
2328
2329	if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0) {
2330		vxge_os_pio_mem_write64(hldev->header.pdev,
2331		    hldev->header.regh0,
2332		    ~(hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX]),
2333		    &hldev->common_reg->tim_int_mask0);
2334	}
2335
2336	if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0) {
2337		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2338		    hldev->header.regh0,
2339		    ~(hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX]),
2340		    &hldev->common_reg->tim_int_mask1);
2341	}
2342
2343	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2344	    __FILE__, __func__, __LINE__);
2345}
2346
2347/*
2348 * vxge_hal_device_mask_tx_rx - Mask Tx and Rx interrupts.
2349 * @devh: HAL device.
2350 *
2351 * Mask Tx and Rx device interrupts.
2352 *
2353 * See also: vxge_hal_device_unmask_tx_rx(), vxge_hal_device_clear_tx_rx().
2354 */
2355void
2356vxge_hal_device_mask_tx_rx(
2357    vxge_hal_device_h devh)
2358{
2359	__hal_device_t *hldev = (__hal_device_t *) devh;
2360
2361	vxge_assert(devh);
2362
2363	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2364	    __FILE__, __func__, __LINE__);
2365
2366	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2367	    (ptr_t) devh);
2368
2369	if ((hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) ||
2370	    (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0)) {
2371		vxge_os_pio_mem_write64(hldev->header.pdev,
2372		    hldev->header.regh0,
2373		    (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] |
2374		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX]),
2375		    &hldev->common_reg->tim_int_mask0);
2376	}
2377
2378	if ((hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) ||
2379	    (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0)) {
2380		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2381		    hldev->header.regh0,
2382		    (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] |
2383		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX]),
2384		    &hldev->common_reg->tim_int_mask1);
2385	}
2386
2387	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2388	    __FILE__, __func__, __LINE__);
2389}
2390
2391/*
2392 * vxge_hal_device_clear_tx_rx - Acknowledge (that is, clear) the
2393 * condition that has caused the Tx and RX interrupt.
2394 * @devh: HAL device.
2395 *
2396 * Acknowledge (that is, clear)	the	condition that has caused
2397 * the Tx and Rx interrupt.
2398 * See also: vxge_hal_device_begin_irq(), vxge_hal_device_continue_irq(),
2399 * vxge_hal_device_mask_tx_rx(), vxge_hal_device_unmask_tx_rx().
2400 */
2401void
2402vxge_hal_device_clear_tx_rx(
2403    vxge_hal_device_h devh)
2404{
2405	__hal_device_t *hldev = (__hal_device_t *) devh;
2406
2407	vxge_assert(devh);
2408
2409	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2410	    __FILE__, __func__, __LINE__);
2411
2412	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2413	    (ptr_t) devh);
2414
2415	if ((hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) ||
2416	    (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0)) {
2417		vxge_os_pio_mem_write64(hldev->header.pdev,
2418		    hldev->header.regh0,
2419		    (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] |
2420		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX]),
2421		    &hldev->common_reg->tim_int_status0);
2422	}
2423
2424	if ((hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) ||
2425	    (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0)) {
2426		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2427		    hldev->header.regh0,
2428		    (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] |
2429		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX]),
2430		    &hldev->common_reg->tim_int_status1);
2431	}
2432
2433	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2434	    __FILE__, __func__, __LINE__);
2435}
2436
2437/*
2438 * vxge_hal_device_unmask_tx_rx - Unmask Tx and Rx interrupts.
2439 * @devh: HAL device.
2440 *
2441 * Unmask Rx device interrupts.
2442 *
2443 * See also: vxge_hal_device_mask_tx_rx(), vxge_hal_device_clear_tx_rx().
2444 */
2445void
2446vxge_hal_device_unmask_tx_rx(
2447    vxge_hal_device_h devh)
2448{
2449	__hal_device_t *hldev = (__hal_device_t *) devh;
2450
2451	vxge_assert(devh);
2452
2453	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2454	    __FILE__, __func__, __LINE__);
2455
2456	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2457	    (ptr_t) devh);
2458
2459	if ((hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) ||
2460	    (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0)) {
2461		vxge_os_pio_mem_write64(hldev->header.pdev,
2462		    hldev->header.regh0,
2463		    ~(hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] |
2464		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX]),
2465		    &hldev->common_reg->tim_int_mask0);
2466	}
2467
2468	if ((hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) ||
2469	    (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0)) {
2470		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2471		    hldev->header.regh0,
2472		    ~(hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] |
2473		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX]),
2474		    &hldev->common_reg->tim_int_mask1);
2475	}
2476
2477	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2478	    __FILE__, __func__, __LINE__);
2479}
2480
2481/*
2482 * vxge_hal_device_hw_info_get - Get the hw information
2483 * @pdev: PCI device object.
2484 * @regh0: BAR0 mapped memory handle (Solaris), or simply PCI device @pdev
2485 *	(Linux and the rest.)
2486 * @bar0: Address of BAR0 in PCI config
2487 * @hw_info: Buffer to return vxge_hal_device_hw_info_t {} structure
2488 *
2489 * Returns the vpath mask that has the bits set for each vpath allocated
2490 * for the driver, FW version information and the first mac addresse for
2491 * each vpath
2492 */
2493vxge_hal_status_e
2494vxge_hal_device_hw_info_get(
2495    pci_dev_h pdev,
2496    pci_reg_h regh0,
2497    u8 *bar0,
2498    vxge_hal_device_hw_info_t *hw_info)
2499{
2500	u32 i;
2501	u64 val64;
2502	vxge_hal_legacy_reg_t *legacy_reg;
2503	vxge_hal_toc_reg_t *toc_reg;
2504	vxge_hal_mrpcim_reg_t *mrpcim_reg;
2505	vxge_hal_common_reg_t *common_reg;
2506	vxge_hal_vpath_reg_t *vpath_reg;
2507	vxge_hal_vpmgmt_reg_t *vpmgmt_reg;
2508	vxge_hal_status_e status;
2509
2510	vxge_hal_trace_log_driver("==> %s:%s:%d",
2511	    __FILE__, __func__, __LINE__);
2512
2513	vxge_hal_trace_log_driver(
2514	    "pdev = 0x"VXGE_OS_STXFMT", regh0 = 0x"VXGE_OS_STXFMT", "
2515	    "bar0 = 0x"VXGE_OS_STXFMT", hw_info = 0x"VXGE_OS_STXFMT,
2516	    (ptr_t) pdev, (ptr_t) regh0, (ptr_t) bar0, (ptr_t) hw_info);
2517
2518	vxge_assert((bar0 != NULL) && (hw_info != NULL));
2519
2520	vxge_os_memzero(hw_info, sizeof(vxge_hal_device_hw_info_t));
2521
2522	legacy_reg = (vxge_hal_legacy_reg_t *)
2523	    vxge_hal_device_get_legacy_reg(pdev, regh0, bar0);
2524
2525	status = __hal_legacy_swapper_set(pdev, regh0, legacy_reg);
2526
2527	if (status != VXGE_HAL_OK) {
2528		vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
2529		    __FILE__, __func__, __LINE__, status);
2530		return (status);
2531	}
2532
2533	val64 = vxge_os_pio_mem_read64(pdev, regh0,
2534	    &legacy_reg->toc_first_pointer);
2535
2536	toc_reg = (vxge_hal_toc_reg_t *) ((void *) (bar0 + val64));
2537
2538	val64 =
2539	    vxge_os_pio_mem_read64(pdev, regh0, &toc_reg->toc_common_pointer);
2540
2541	common_reg = (vxge_hal_common_reg_t *) ((void *) (bar0 + val64));
2542
2543	status = vxge_hal_device_register_poll(pdev, regh0,
2544	    &common_reg->vpath_rst_in_prog, 0,
2545	    VXGE_HAL_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(0x1ffff),
2546	    VXGE_HAL_DEF_DEVICE_POLL_MILLIS);
2547
2548	if (status != VXGE_HAL_OK) {
2549
2550		vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
2551		    __FILE__, __func__, __LINE__, status);
2552		return (status);
2553	}
2554
2555	hw_info->vpath_mask = vxge_os_pio_mem_read64(pdev, regh0,
2556	    &common_reg->vpath_assignments);
2557
2558	val64 = vxge_os_pio_mem_read64(pdev, regh0,
2559	    &common_reg->host_type_assignments);
2560
2561	hw_info->host_type = (u32)
2562	    VXGE_HAL_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
2563
2564	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
2565
2566		if (!((hw_info->vpath_mask) & mBIT(i)))
2567			continue;
2568
2569		val64 = vxge_os_pio_mem_read64(pdev, regh0,
2570		    &toc_reg->toc_vpmgmt_pointer[i]);
2571
2572		vpmgmt_reg = (vxge_hal_vpmgmt_reg_t *)
2573		    ((void *) (bar0 + val64));
2574
2575		val64 = vxge_os_pio_mem_read64(pdev, regh0,
2576		    &vpmgmt_reg->vpath_to_func_map_cfg1);
2577		hw_info->func_id = (u32)
2578		    VXGE_HAL_VPATH_TO_FUNC_MAP_CFG1_GET_CFG1(
2579		    val64);
2580
2581		if (__hal_device_access_rights_get(hw_info->host_type,
2582		    hw_info->func_id) & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM) {
2583
2584			val64 = vxge_os_pio_mem_read64(pdev, regh0,
2585			    &toc_reg->toc_mrpcim_pointer);
2586
2587			mrpcim_reg = (vxge_hal_mrpcim_reg_t *)
2588			    ((void *) (bar0 + val64));
2589
2590			vxge_os_pio_mem_write64(pdev, regh0,
2591			    0,
2592			    &mrpcim_reg->xgmac_gen_fw_memo_mask);
2593			vxge_os_wmb();
2594		}
2595
2596		val64 = vxge_os_pio_mem_read64(pdev, regh0,
2597		    &toc_reg->toc_vpath_pointer[i]);
2598
2599		vpath_reg = (vxge_hal_vpath_reg_t *) ((void *) (bar0 + val64));
2600
2601		(void) __hal_vpath_fw_flash_ver_get(pdev, regh0, i, vpath_reg,
2602		    &hw_info->fw_version,
2603		    &hw_info->fw_date,
2604		    &hw_info->flash_version,
2605		    &hw_info->flash_date);
2606
2607		(void) __hal_vpath_card_info_get(pdev, regh0, i, vpath_reg,
2608		    hw_info->serial_number,
2609		    hw_info->part_number,
2610		    hw_info->product_description);
2611
2612		(void) __hal_vpath_pmd_info_get(pdev, regh0, i, vpath_reg,
2613		    &hw_info->ports,
2614		    &hw_info->pmd_port0,
2615		    &hw_info->pmd_port1);
2616
2617		hw_info->function_mode =
2618		    __hal_vpath_pci_func_mode_get(pdev, regh0, i, vpath_reg);
2619
2620		break;
2621	}
2622
2623	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
2624
2625		if (!((hw_info->vpath_mask) & mBIT(i)))
2626			continue;
2627
2628		val64 = vxge_os_pio_mem_read64(pdev, regh0,
2629		    &toc_reg->toc_vpath_pointer[i]);
2630
2631		vpath_reg = (vxge_hal_vpath_reg_t *) ((void *) (bar0 + val64));
2632
2633		status = __hal_vpath_hw_addr_get(pdev, regh0, i, vpath_reg,
2634		    hw_info->mac_addrs[i], hw_info->mac_addr_masks[i]);
2635
2636		if (status != VXGE_HAL_OK) {
2637
2638			vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
2639			    __FILE__, __func__, __LINE__, status);
2640			return (status);
2641
2642		}
2643
2644	}
2645
2646	vxge_hal_trace_log_driver("<== %s:%s:%d Result = 0",
2647	    __FILE__, __func__, __LINE__);
2648
2649	return (VXGE_HAL_OK);
2650}
2651
2652/*
2653 * vxge_hal_device_initialize - Initialize X3100 device.
2654 * @hldev: HAL device handle.
2655 * @attr: pointer to vxge_hal_device_attr_t structure
2656 * @device_config: Configuration to be _applied_ to the device,
2657 *		For the X3100 configuration "knobs" please
2658 *		refer to vxge_hal_device_config_t and X3100
2659 *		User Guide.
2660 *
2661 * Initialize X3100 device. Note that all the arguments of this public API
2662 * are 'IN', including @hldev. Upper-layer driver (ULD) cooperates with
2663 * OS to find new X3100 device, locate its PCI and memory spaces.
2664 *
2665 * When done, the ULD allocates sizeof(__hal_device_t) bytes for HAL
2666 * to enable the latter to perform X3100 hardware initialization.
2667 *
2668 * Returns: VXGE_HAL_OK - success.
2669 * VXGE_HAL_ERR_DRIVER_NOT_INITIALIZED - Driver is not initialized.
2670 * VXGE_HAL_ERR_BAD_DEVICE_CONFIG - Device configuration params are not
2671 * valid.
2672 * VXGE_HAL_ERR_OUT_OF_MEMORY - Memory allocation failed.
2673 * VXGE_HAL_ERR_BAD_SUBSYSTEM_ID - Device subsystem id is invalid.
2674 * VXGE_HAL_ERR_INVALID_MAC_ADDRESS - Device mac address in not valid.
2675 * VXGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to retrieve the mac
2676 * address within the time(timeout) or TTI/RTI initialization failed.
2677 * VXGE_HAL_ERR_SWAPPER_CTRL - Failed to configure swapper control.
2678 *
2679 * See also: __hal_device_terminate(), vxge_hal_status_e {}
2680 * vxge_hal_device_attr_t {}.
2681 */
2682vxge_hal_status_e
2683vxge_hal_device_initialize(
2684    vxge_hal_device_h *devh,
2685    vxge_hal_device_attr_t *attr,
2686    vxge_hal_device_config_t *device_config)
2687{
2688	u32 i;
2689	u32 nblocks = 0;
2690	__hal_device_t *hldev;
2691	vxge_hal_status_e status;
2692
2693	vxge_assert((devh != NULL) &&
2694	    (attr != NULL) && (device_config != NULL));
2695
2696	vxge_hal_trace_log_driver("==> %s:%s:%d",
2697	    __FILE__, __func__, __LINE__);
2698
2699	vxge_hal_trace_log_driver(
2700	    "devh = 0x"VXGE_OS_STXFMT", attr = 0x"VXGE_OS_STXFMT", "
2701	    "device_config = 0x"VXGE_OS_STXFMT, (ptr_t) devh, (ptr_t) attr,
2702	    (ptr_t) device_config);
2703
2704	/* sanity check */
2705	if (g_vxge_hal_driver == NULL ||
2706	    !g_vxge_hal_driver->is_initialized) {
2707		vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
2708		    __FILE__, __func__, __LINE__,
2709		    VXGE_HAL_ERR_DRIVER_NOT_INITIALIZED);
2710		return (VXGE_HAL_ERR_DRIVER_NOT_INITIALIZED);
2711	}
2712
2713	status = __hal_device_config_check(device_config);
2714
2715	if (status != VXGE_HAL_OK) {
2716		vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
2717		    __FILE__, __func__, __LINE__, status);
2718		return (status);
2719	}
2720
2721	hldev = (__hal_device_t *) vxge_os_malloc(attr->pdev,
2722	    sizeof(__hal_device_t));
2723
2724	if (hldev == NULL) {
2725		vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
2726		    __FILE__, __func__, __LINE__,
2727		    VXGE_HAL_ERR_OUT_OF_MEMORY);
2728		return (VXGE_HAL_ERR_OUT_OF_MEMORY);
2729	}
2730
2731	vxge_os_memzero(hldev, sizeof(__hal_device_t));
2732
2733	hldev->header.magic = VXGE_HAL_DEVICE_MAGIC;
2734
2735	__hal_channel_init_pending_list(hldev);
2736
2737	vxge_hal_device_debug_set(hldev,
2738	    device_config->debug_level,
2739	    device_config->debug_mask);
2740
2741#if defined(VXGE_TRACE_INTO_CIRCULAR_ARR)
2742	hldev->trace_buf.size = device_config->tracebuf_size;
2743	hldev->trace_buf.data =
2744	    (u8 *) vxge_os_malloc(attr->pdev, hldev->trace_buf.size);
2745	if (hldev->trace_buf.data == NULL) {
2746		vxge_os_printf("cannot allocate trace buffer!\n");
2747		return (VXGE_HAL_ERR_OUT_OF_MEMORY);
2748	}
2749	hldev->trace_buf.offset = 0;
2750	hldev->trace_buf.wrapped_count = 0;
2751	vxge_hal_trace_log_device("==> %s:%s:%d",
2752	    __FILE__, __func__, __LINE__);
2753#endif
2754
2755	vxge_hal_info_log_device("device 0x"VXGE_OS_STXFMT" is initializing",
2756	    (ptr_t) hldev);
2757
2758	/* apply config */
2759	vxge_os_memcpy(&hldev->header.config, device_config,
2760	    sizeof(vxge_hal_device_config_t));
2761
2762	hldev->header.regh0 = attr->regh0;
2763	hldev->header.regh1 = attr->regh1;
2764	hldev->header.regh2 = attr->regh2;
2765	hldev->header.bar0 = attr->bar0;
2766	hldev->header.bar1 = attr->bar1;
2767	hldev->header.bar2 = attr->bar2;
2768	hldev->header.pdev = attr->pdev;
2769	hldev->header.irqh = attr->irqh;
2770	hldev->header.cfgh = attr->cfgh;
2771
2772	if ((status = __hal_device_reg_addr_get(hldev)) != VXGE_HAL_OK) {
2773		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2774		    __FILE__, __func__, __LINE__, status);
2775		vxge_hal_device_terminate(hldev);
2776		return (status);
2777	}
2778
2779	__hal_device_id_get(hldev);
2780
2781	__hal_device_host_info_get(hldev);
2782
2783
2784	nblocks += 1;		/* For MRPCIM stats */
2785
2786	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
2787
2788		if (!(hldev->vpath_assignments & mBIT(i)))
2789			continue;
2790
2791		if (device_config->vp_config[i].ring.enable ==
2792		    VXGE_HAL_RING_ENABLE) {
2793			nblocks +=
2794			    (device_config->vp_config[i].ring.ring_length +
2795			    vxge_hal_ring_rxds_per_block_get(
2796			    device_config->vp_config[i].ring.buffer_mode) - 1) /
2797			    vxge_hal_ring_rxds_per_block_get(
2798			    device_config->vp_config[i].ring.buffer_mode);
2799		}
2800
2801		if ((device_config->vp_config[i].fifo.enable ==
2802		    VXGE_HAL_FIFO_ENABLE) &&
2803		    ((device_config->vp_config[i].fifo.max_frags *
2804		    sizeof(vxge_hal_fifo_txd_t)) <=
2805		    VXGE_OS_HOST_PAGE_SIZE)) {
2806			nblocks +=
2807			    ((device_config->vp_config[i].fifo.fifo_length *
2808			    sizeof(vxge_hal_fifo_txd_t) *
2809			    device_config->vp_config[i].fifo.max_frags) +
2810			    VXGE_OS_HOST_PAGE_SIZE - 1) /
2811			    VXGE_OS_HOST_PAGE_SIZE;
2812		}
2813
2814
2815		nblocks += 1;	/* For vpath stats */
2816
2817	}
2818
2819	if (__hal_blockpool_create(hldev,
2820	    &hldev->block_pool,
2821	    device_config->dma_blockpool_initial + nblocks,
2822	    device_config->dma_blockpool_incr,
2823	    device_config->dma_blockpool_min,
2824	    device_config->dma_blockpool_max + nblocks) != VXGE_HAL_OK) {
2825		vxge_hal_info_log_device("%s:__hal_blockpool_create failed",
2826		    __func__);
2827		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2828		    __FILE__, __func__, __LINE__,
2829		    VXGE_HAL_ERR_OUT_OF_MEMORY);
2830		vxge_hal_device_terminate(hldev);
2831		return (VXGE_HAL_ERR_OUT_OF_MEMORY);
2832	}
2833
2834
2835	status = __hal_device_hw_initialize(hldev);
2836
2837	if (status != VXGE_HAL_OK) {
2838		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2839		    __FILE__, __func__, __LINE__, status);
2840		vxge_hal_device_terminate(hldev);
2841		return (status);
2842	}
2843
2844	hldev->dump_buf = (char *) vxge_os_malloc(hldev->header.pdev,
2845	    VXGE_HAL_DUMP_BUF_SIZE);
2846	if (hldev->dump_buf == NULL) {
2847		vxge_hal_info_log_device("%s:vxge_os_malloc failed ",
2848		    __func__);
2849		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2850		    __FILE__, __func__, __LINE__,
2851		    VXGE_HAL_ERR_OUT_OF_MEMORY);
2852		vxge_hal_device_terminate(hldev);
2853		return (VXGE_HAL_ERR_OUT_OF_MEMORY);
2854	}
2855
2856	hldev->header.is_initialized = 1;
2857
2858	*devh = hldev;
2859
2860	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
2861	    __FILE__, __func__, __LINE__);
2862	return (VXGE_HAL_OK);
2863}
2864
2865/*
2866 * vxge_hal_device_terminate - Terminate X3100 device.
2867 * @devh: HAL device handle.
2868 *
2869 * Terminate HAL device.
2870 *
2871 * See also: vxge_hal_device_initialize().
2872 */
2873void
2874vxge_hal_device_terminate(vxge_hal_device_h devh)
2875{
2876	__hal_device_t *hldev = (__hal_device_t *) devh;
2877
2878	vxge_assert(g_vxge_hal_driver != NULL);
2879	vxge_assert(hldev != NULL);
2880	vxge_assert(hldev->header.magic == VXGE_HAL_DEVICE_MAGIC);
2881
2882	vxge_hal_trace_log_device("==> %s:%s:%d",
2883	    __FILE__, __func__, __LINE__);
2884
2885	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
2886	    (ptr_t) devh);
2887
2888	hldev->header.terminating = 1;
2889	hldev->header.is_initialized = 0;
2890	hldev->in_poll = 0;
2891	hldev->header.magic = VXGE_HAL_DEVICE_DEAD;
2892
2893	if (hldev->dump_buf) {
2894		vxge_os_free(hldev->header.pdev, hldev->dump_buf,
2895		    VXGE_HAL_DUMP_BUF_SIZE);
2896		hldev->dump_buf = NULL;
2897	}
2898
2899	if (hldev->srpcim != NULL)
2900		(void) __hal_srpcim_terminate(hldev);
2901
2902	if (hldev->mrpcim != NULL)
2903		(void) __hal_mrpcim_terminate(hldev);
2904
2905	__hal_channel_destroy_pending_list(hldev);
2906
2907
2908	__hal_blockpool_destroy(&hldev->block_pool);
2909
2910#if defined(VXGE_TRACE_INTO_CIRCULAR_ARR)
2911	if (hldev->trace_buf.size) {
2912		vxge_os_free(NULL,
2913		    hldev->trace_buf.data,
2914		    hldev->trace_buf.size);
2915	}
2916#endif
2917
2918	vxge_os_free(hldev->header.pdev, hldev, sizeof(__hal_device_t));
2919
2920	vxge_hal_trace_log_driver("<== %s:%s:%d Result = 0",
2921	    __FILE__, __func__, __LINE__);
2922}
2923
2924/*
2925 * vxge_hal_device_enable - Enable device.
2926 * @devh: HAL device handle.
2927 *
2928 * Enable the specified device: bring up the link/interface.
2929 *
2930 */
2931vxge_hal_status_e
2932vxge_hal_device_enable(
2933    vxge_hal_device_h devh)
2934{
2935	vxge_hal_status_e status = VXGE_HAL_OK;
2936	__hal_device_t *hldev = (__hal_device_t *) devh;
2937
2938	vxge_assert(devh != NULL);
2939
2940	vxge_hal_trace_log_device("==> %s:%s:%d",
2941	    __FILE__, __func__, __LINE__);
2942
2943	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
2944	    (ptr_t) devh);
2945
2946	if (!hldev->hw_is_initialized) {
2947
2948		status = __hal_device_hw_initialize(hldev);
2949		if (status != VXGE_HAL_OK) {
2950			vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2951			    __FILE__, __func__, __LINE__, status);
2952			return (status);
2953		}
2954	}
2955
2956	__hal_device_bus_master_enable(hldev);
2957
2958	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2959	    __FILE__, __func__, __LINE__, status);
2960	return (status);
2961}
2962
2963/*
2964 * vxge_hal_device_disable - Disable X3100 adapter.
2965 * @devh: HAL device handle.
2966 *
2967 * Disable this device. To gracefully reset the adapter, the host should:
2968 *
2969 *	- call vxge_hal_device_disable();
2970 *
2971 *	- call vxge_hal_device_intr_disable();
2972 *
2973 *	- do some work (error recovery, change mtu, reset, etc);
2974 *
2975 *	- call vxge_hal_device_enable();
2976 *
2977 *	- call vxge_hal_device_intr_enable().
2978 *
2979 * Note: Disabling the device does _not_ include disabling of interrupts.
2980 * After disabling the device stops receiving new frames but those frames
2981 * that were already in the pipe will keep coming for some few milliseconds.
2982 *
2983 *
2984 */
2985vxge_hal_status_e
2986vxge_hal_device_disable(
2987    vxge_hal_device_h devh)
2988{
2989	vxge_hal_status_e status = VXGE_HAL_OK;
2990
2991	vxge_assert(devh != NULL);
2992
2993#if (VXGE_COMPONENT_HAL_DEVICE & VXGE_DEBUG_MODULE_MASK)
2994
2995	__hal_device_t *hldev = (__hal_device_t *) devh;
2996
2997	vxge_hal_trace_log_device("==> %s:%s:%d",
2998	    __FILE__, __func__, __LINE__);
2999
3000	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
3001	    (ptr_t) devh);
3002
3003	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
3004	    __FILE__, __func__, __LINE__, status);
3005#endif
3006
3007	return (status);
3008}
3009
3010/*
3011 * vxge_hal_device_hw_stats_enable - Enable device h/w statistics.
3012 * @devh: HAL Device.
3013 *
3014 * Enable the DMA vpath statistics for the device. The function is to be called
3015 * to re-enable the adapter to update stats into the host memory
3016 *
3017 * See also: vxge_hal_device_hw_stats_disable()
3018 */
3019vxge_hal_status_e
3020vxge_hal_device_hw_stats_enable(
3021    vxge_hal_device_h devh)
3022{
3023	u32 i;
3024	u64 val64;
3025	vxge_hal_status_e status = VXGE_HAL_OK;
3026	__hal_device_t *hldev = (__hal_device_t *) devh;
3027
3028	vxge_assert(devh != NULL);
3029
3030	vxge_hal_trace_log_stats("==> %s:%s:%d",
3031	    __FILE__, __func__, __LINE__);
3032
3033	vxge_hal_trace_log_stats("devh = 0x"VXGE_OS_STXFMT,
3034	    (ptr_t) devh);
3035
3036	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
3037	    hldev->header.regh0,
3038	    &hldev->common_reg->stats_cfg0);
3039
3040	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
3041
3042		if (!(hldev->vpaths_deployed & mBIT(i)))
3043			continue;
3044
3045		vxge_os_memcpy(hldev->virtual_paths[i].hw_stats_sav,
3046		    hldev->virtual_paths[i].hw_stats,
3047		    sizeof(vxge_hal_vpath_stats_hw_info_t));
3048		if (hldev->header.config.stats_read_method ==
3049		    VXGE_HAL_STATS_READ_METHOD_DMA) {
3050			val64 |=
3051			    VXGE_HAL_STATS_CFG0_STATS_ENABLE((1 << (16 - i)));
3052		} else {
3053			status = __hal_vpath_hw_stats_get(
3054			    &hldev->virtual_paths[i],
3055			    hldev->virtual_paths[i].hw_stats);
3056		}
3057
3058	}
3059
3060	vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
3061	    hldev->header.regh0,
3062	    (u32) bVAL32(val64, 0),
3063	    &hldev->common_reg->stats_cfg0);
3064
3065	vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3066	    __FILE__, __func__, __LINE__, status);
3067	return (status);
3068}
3069
3070/*
3071 * vxge_hal_device_hw_stats_disable - Disable device h/w statistics.
3072 * @devh: HAL Device.
3073 *
3074 * Enable the DMA vpath statistics for the device. The function is to be called
3075 * to disable the adapter to update stats into the host memory. This function
3076 * is not needed to be called, normally.
3077 *
3078 * See also: vxge_hal_device_hw_stats_enable()
3079 */
3080vxge_hal_status_e
3081vxge_hal_device_hw_stats_disable(
3082    vxge_hal_device_h devh)
3083{
3084	u32 i;
3085	u64 val64;
3086	vxge_hal_status_e status = VXGE_HAL_OK;
3087	__hal_device_t *hldev = (__hal_device_t *) devh;
3088
3089	vxge_assert(devh != NULL);
3090
3091	vxge_hal_trace_log_stats("==> %s:%s:%d",
3092	    __FILE__, __func__, __LINE__);
3093
3094	vxge_hal_trace_log_stats("devh = 0x"VXGE_OS_STXFMT,
3095	    (ptr_t) devh);
3096
3097	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
3098	    hldev->header.regh0,
3099	    &hldev->common_reg->stats_cfg0);
3100
3101	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
3102
3103		if (!(hldev->vpaths_deployed & mBIT(i)))
3104			continue;
3105
3106		val64 &= ~VXGE_HAL_STATS_CFG0_STATS_ENABLE((1 << (16 - i)));
3107
3108	}
3109
3110	vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
3111	    hldev->header.regh0,
3112	    (u32) bVAL32(val64, 0),
3113	    &hldev->common_reg->stats_cfg0);
3114
3115	vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3116	    __FILE__, __func__, __LINE__, status);
3117	return (status);
3118}
3119
3120/*
3121 * vxge_hal_device_hw_stats_get - Get the device hw statistics.
3122 * @devh: HAL Device.
3123 * @hw_stats: Hardware stats
3124 *
3125 * Returns the vpath h/w stats for the device.
3126 *
3127 * See also: vxge_hal_device_hw_stats_enable(),
3128 * vxge_hal_device_hw_stats_disable()
3129 */
3130vxge_hal_status_e
3131vxge_hal_device_hw_stats_get(
3132    vxge_hal_device_h devh,
3133    vxge_hal_device_stats_hw_info_t *hw_stats)
3134{
3135	u32 i;
3136	u64 val64 = 0;
3137	vxge_hal_status_e status = VXGE_HAL_OK;
3138	__hal_device_t *hldev = (__hal_device_t *) devh;
3139
3140	vxge_assert((devh != NULL) && (hw_stats != NULL));
3141
3142	vxge_hal_trace_log_stats("==> %s:%s:%d",
3143	    __FILE__, __func__, __LINE__);
3144
3145	vxge_hal_trace_log_stats(
3146	    "devh = 0x"VXGE_OS_STXFMT", hw_stats = 0x"VXGE_OS_STXFMT,
3147	    (ptr_t) devh, (ptr_t) hw_stats);
3148
3149	if (hldev->header.config.stats_read_method ==
3150	    VXGE_HAL_STATS_READ_METHOD_DMA) {
3151
3152		for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
3153
3154			if (!(hldev->vpaths_deployed & mBIT(i)))
3155				continue;
3156
3157			val64 |=
3158			    VXGE_HAL_STATS_CFG0_STATS_ENABLE((1 << (16 - i)));
3159
3160		}
3161
3162		status = vxge_hal_device_register_poll(hldev->header.pdev,
3163		    hldev->header.regh0,
3164		    &hldev->common_reg->stats_cfg0,
3165		    0,
3166		    val64,
3167		    hldev->header.config.device_poll_millis);
3168
3169	}
3170
3171	if (status == VXGE_HAL_OK) {
3172		vxge_os_memcpy(hw_stats,
3173		    &hldev->stats.hw_dev_info_stats,
3174		    sizeof(vxge_hal_device_stats_hw_info_t));
3175	}
3176
3177	vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3178	    __FILE__, __func__, __LINE__, status);
3179	return (status);
3180}
3181
3182/*
3183 * vxge_hal_device_sw_stats_get - Get the device sw statistics.
3184 * @devh: HAL Device.
3185 * @sw_stats: Software stats
3186 *
3187 * Returns the vpath s/w stats for the device.
3188 *
3189 * See also: vxge_hal_device_hw_stats_get()
3190 */
3191vxge_hal_status_e
3192vxge_hal_device_sw_stats_get(
3193    vxge_hal_device_h devh,
3194    vxge_hal_device_stats_sw_info_t *sw_stats)
3195{
3196	vxge_hal_status_e status = VXGE_HAL_OK;
3197	__hal_device_t *hldev = (__hal_device_t *) devh;
3198
3199	vxge_assert((hldev != NULL) && (sw_stats != NULL));
3200
3201	vxge_hal_trace_log_stats("==> %s:%s:%d",
3202	    __FILE__, __func__, __LINE__);
3203
3204	vxge_hal_trace_log_stats(
3205	    "devh = 0x"VXGE_OS_STXFMT", sw_stats = 0x"VXGE_OS_STXFMT,
3206	    (ptr_t) devh, (ptr_t) sw_stats);
3207
3208	vxge_os_memcpy(sw_stats,
3209	    &hldev->stats.sw_dev_info_stats,
3210	    sizeof(vxge_hal_device_stats_sw_info_t));
3211
3212	vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3213	    __FILE__, __func__, __LINE__, status);
3214	return (status);
3215}
3216
3217/*
3218 * vxge_hal_device_stats_get - Get the device statistics.
3219 * @devh: HAL Device.
3220 * @stats: Device stats
3221 *
3222 * Returns the device stats for the device.
3223 *
3224 * See also: vxge_hal_device_hw_stats_get(), vxge_hal_device_sw_stats_get()
3225 */
3226vxge_hal_status_e
3227vxge_hal_device_stats_get(
3228    vxge_hal_device_h devh,
3229    vxge_hal_device_stats_t *stats)
3230{
3231	vxge_hal_status_e status = VXGE_HAL_OK;
3232	__hal_device_t *hldev = (__hal_device_t *) devh;
3233
3234	vxge_assert((hldev != NULL) && (stats != NULL));
3235
3236	vxge_hal_trace_log_stats("==> %s:%s:%d",
3237	    __FILE__, __func__, __LINE__);
3238
3239	vxge_hal_trace_log_stats(
3240	    "devh = 0x"VXGE_OS_STXFMT", stats = 0x"VXGE_OS_STXFMT,
3241	    (ptr_t) devh, (ptr_t) stats);
3242
3243	vxge_os_memcpy(stats,
3244	    &hldev->stats,
3245	    sizeof(vxge_hal_device_stats_t));
3246
3247	vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3248	    __FILE__, __func__, __LINE__, status);
3249	return (status);
3250}
3251
3252/*
3253 * vxge_hal_device_xmac_stats_get - Get the Device XMAC Statistics
3254 * @devh: HAL device handle.
3255 * @xmac_stats: Buffer to return XMAC Statistics.
3256 *
3257 * Get the XMAC Statistics
3258 *
3259 */
3260vxge_hal_status_e
3261vxge_hal_device_xmac_stats_get(vxge_hal_device_h devh,
3262    vxge_hal_device_xmac_stats_t *xmac_stats)
3263{
3264	vxge_hal_status_e status = VXGE_HAL_OK;
3265	u32 i;
3266	__hal_device_t *hldev = (__hal_device_t *) devh;
3267
3268	vxge_assert((hldev != NULL) && (xmac_stats != NULL));
3269
3270	vxge_hal_trace_log_stats("==> %s:%s:%d",
3271	    __FILE__, __func__, __LINE__);
3272
3273	vxge_hal_trace_log_stats(
3274	    "devh = 0x"VXGE_OS_STXFMT", xmac_stats = 0x"VXGE_OS_STXFMT,
3275	    (ptr_t) devh, (ptr_t) xmac_stats);
3276
3277	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
3278
3279
3280		if (!(hldev->vpaths_deployed & mBIT(i)))
3281			continue;
3282
3283		status = __hal_vpath_xmac_tx_stats_get(&hldev->virtual_paths[i],
3284		    &xmac_stats->vpath_tx_stats[i]);
3285
3286		if (status != VXGE_HAL_OK) {
3287			vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3288			    __FILE__, __func__, __LINE__, status);
3289			return (status);
3290		}
3291
3292		status = __hal_vpath_xmac_rx_stats_get(&hldev->virtual_paths[i],
3293		    &xmac_stats->vpath_rx_stats[i]);
3294
3295		if (status != VXGE_HAL_OK) {
3296			vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3297			    __FILE__, __func__, __LINE__, status);
3298			return (status);
3299		}
3300
3301	}
3302
3303	vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3304	    __FILE__, __func__, __LINE__, status);
3305	return (status);
3306}
3307
3308#if defined(VXGE_TRACE_INTO_CIRCULAR_ARR)
3309
3310/*
3311 * vxge_hal_device_trace_write - Write the trace from the given buffer into
3312 *				 circular trace buffer
3313 * @devh: HAL device handle.
3314 * @trace_buf: Buffer containing the trace.
3315 * @trace_len: Length of the trace in the buffer
3316 *
3317 * Writes the trace from the given buffer into the circular trace buffer
3318 *
3319 */
3320void
3321vxge_hal_device_trace_write(vxge_hal_device_h devh,
3322    u8 *trace_buf,
3323    u32 trace_len)
3324{
3325	__hal_device_t *hldev = (__hal_device_t *) devh;
3326	u32 offset;
3327
3328	if (hldev == NULL)
3329		return;
3330
3331	offset = hldev->trace_buf.offset;
3332
3333	if (trace_len > 1) {
3334
3335		u32 leftsize = hldev->trace_buf.size - offset;
3336
3337		if (trace_len > leftsize) {
3338			vxge_os_memzero(hldev->trace_buf.data + offset,
3339			    leftsize);
3340			offset = 0;
3341			hldev->trace_buf.wrapped_count++;
3342		}
3343
3344		vxge_os_memcpy(hldev->trace_buf.data + offset,
3345		    trace_buf, trace_len);
3346		offset += trace_len;
3347		hldev->trace_buf.offset = offset;
3348
3349	}
3350}
3351
3352/*
3353 * vxge_hal_device_trace_dump - Dump the trace buffer.
3354 * @devh: HAL device handle.
3355 *
3356 * Dump the trace buffer contents.
3357 */
3358void
3359vxge_hal_device_trace_dump(vxge_hal_device_h devh)
3360{
3361	__hal_device_t *hldev = (__hal_device_t *) devh;
3362	u32 offset, i = 0;
3363
3364	if (hldev == NULL)
3365		return;
3366
3367	offset = hldev->trace_buf.offset;
3368
3369	vxge_os_printf("################ Trace dump Begin ###############\n");
3370
3371	if (hldev->trace_buf.wrapped_count) {
3372		for (i = hldev->trace_buf.offset;
3373		    i < hldev->trace_buf.size; i += offset) {
3374			if (*(hldev->trace_buf.data + i))
3375				vxge_os_printf(hldev->trace_buf.data + i);
3376			offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1;
3377		}
3378	}
3379
3380	for (i = 0; i < hldev->trace_buf.offset; i += offset) {
3381		if (*(hldev->trace_buf.data + i))
3382			vxge_os_printf(hldev->trace_buf.data + i);
3383		offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1;
3384	}
3385
3386	vxge_os_printf("################ Trace dump End ###############\n");
3387
3388}
3389
3390/*
3391 * vxge_hal_device_trace_read - Read trace buffer contents.
3392 * @devh: HAL device handle.
3393 * @buffer: Buffer to store the trace buffer contents.
3394 * @buf_size: Size of the buffer.
3395 * @read_length: Size of the valid data in the buffer.
3396 *
3397 * Read  HAL trace buffer contents starting from the offset
3398 * up to the size of the buffer or till EOF is reached.
3399 *
3400 * Returns: VXGE_HAL_OK - success.
3401 * VXGE_HAL_EOF_TRACE_BUF - No more data in the trace buffer.
3402 *
3403 */
3404vxge_hal_status_e
3405vxge_hal_device_trace_read(vxge_hal_device_h devh,
3406    char *buffer,
3407    unsigned buf_size,
3408    unsigned *read_length)
3409{
3410	__hal_device_t *hldev = (__hal_device_t *) devh;
3411	u32 offset, i = 0, buf_off = 0;
3412
3413	*read_length = 0;
3414	*buffer = 0;
3415
3416	if (hldev == NULL)
3417		return (VXGE_HAL_FAIL);
3418
3419	offset = hldev->trace_buf.offset;
3420
3421	if (hldev->trace_buf.wrapped_count) {
3422		for (i = hldev->trace_buf.offset;
3423		    i < hldev->trace_buf.size; i += offset) {
3424			if (*(hldev->trace_buf.data + i)) {
3425				vxge_os_sprintf(buffer + buf_off, "%s\n",
3426				    hldev->trace_buf.data + i);
3427				buf_off += vxge_os_strlen(
3428				    hldev->trace_buf.data + i) + 1;
3429				if (buf_off > buf_size)
3430					return (VXGE_HAL_ERR_OUT_OF_MEMORY);
3431			}
3432			offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1;
3433		}
3434	}
3435
3436	for (i = 0; i < hldev->trace_buf.offset; i += offset) {
3437		if (*(hldev->trace_buf.data + i)) {
3438			vxge_os_sprintf(buffer + buf_off, "%s\n",
3439			    hldev->trace_buf.data + i);
3440			buf_off += vxge_os_strlen(
3441			    hldev->trace_buf.data + i) + 1;
3442			if (buf_off > buf_size)
3443				return (VXGE_HAL_ERR_OUT_OF_MEMORY);
3444		}
3445		offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1;
3446	}
3447
3448	*read_length = buf_off;
3449	*(buffer + buf_off + 1) = 0;
3450
3451	return (VXGE_HAL_OK);
3452}
3453
3454#endif
3455
3456/*
3457 * vxge_hal_device_debug_set - Set the debug module, level and timestamp
3458 * @devh: Hal device object
3459 * @level: Debug level as defined in enum vxge_debug_level_e
3460 * @module masks: An or value of component masks as defined in vxge_debug.h
3461 *
3462 * This routine is used to dynamically change the debug output
3463 */
3464void
3465vxge_hal_device_debug_set(
3466    vxge_hal_device_h devh,
3467    vxge_debug_level_e level,
3468    u32 mask)
3469{
3470	__hal_device_t *hldev = (__hal_device_t *) devh;
3471
3472	hldev->header.debug_module_mask = mask;
3473	hldev->header.debug_level = level;
3474
3475	hldev->d_trace_mask = 0;
3476	hldev->d_info_mask = 0;
3477	hldev->d_err_mask = 0;
3478
3479	switch (level) {
3480	case VXGE_TRACE:
3481		hldev->d_trace_mask = mask;
3482		/* FALLTHROUGH */
3483
3484	case VXGE_INFO:
3485		hldev->d_info_mask = mask;
3486		/* FALLTHROUGH */
3487
3488	case VXGE_ERR:
3489		hldev->d_err_mask = mask;
3490		/* FALLTHROUGH */
3491
3492	default:
3493		break;
3494	}
3495}
3496
3497/*
3498 * vxge_hal_device_flick_link_led - Flick (blink) link LED.
3499 * @devh: HAL device handle.
3500 * @port : Port number 0, or 1
3501 * @on_off: TRUE if flickering to be on, FALSE to be off
3502 *
3503 * Flicker the link LED.
3504 */
3505vxge_hal_status_e
3506vxge_hal_device_flick_link_led(vxge_hal_device_h devh, u32 port, u32 on_off)
3507{
3508	vxge_hal_status_e status;
3509	__hal_device_t *hldev = (__hal_device_t *) devh;
3510
3511	vxge_assert(devh != NULL);
3512
3513	vxge_hal_trace_log_device("==> %s:%s:%d",
3514	    __FILE__, __func__, __LINE__);
3515
3516	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT
3517	    ", port = %d, on_off = %d", (ptr_t) devh, port, on_off);
3518
3519	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
3520		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
3521		    __FILE__, __func__, __LINE__,
3522		    VXGE_HAL_ERR_INVALID_DEVICE);
3523
3524		return (VXGE_HAL_ERR_INVALID_DEVICE);
3525	}
3526
3527	status = __hal_vpath_flick_link_led(hldev,
3528	    hldev->first_vp_id, port, on_off);
3529
3530	vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
3531	    __FILE__, __func__, __LINE__, status);
3532
3533	return (status);
3534}
3535
3536/*
3537 * vxge_hal_device_getpause_data -Pause frame frame generation and reception.
3538 * @devh: HAL device handle.
3539 * @port : Port number 0, 1, or 2
3540 * @tx : A field to return the pause generation capability of the NIC.
3541 * @rx : A field to return the pause reception capability of the NIC.
3542 *
3543 * Returns the Pause frame generation and reception capability of the NIC.
3544 * Return value:
3545 * status
3546 */
3547vxge_hal_status_e
3548vxge_hal_device_getpause_data(
3549    vxge_hal_device_h devh,
3550    u32 port,
3551    u32 *tx,
3552    u32 *rx)
3553{
3554	u32 i;
3555	u64 val64;
3556	vxge_hal_status_e status = VXGE_HAL_ERR_VPATH_NOT_AVAILABLE;
3557	__hal_device_t *hldev = (__hal_device_t *) devh;
3558
3559	vxge_assert(devh != NULL);
3560
3561	vxge_hal_trace_log_device("==> %s:%s:%d",
3562	    __FILE__, __func__, __LINE__);
3563
3564	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT", "
3565	    "port = %d, tx = 0x"VXGE_OS_STXFMT", "
3566	    "rx = 0x"VXGE_OS_STXFMT, (ptr_t) devh, port, (ptr_t) tx,
3567	    (ptr_t) rx);
3568
3569	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
3570		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
3571		    __FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_DEVICE);
3572		return (VXGE_HAL_ERR_INVALID_DEVICE);
3573	}
3574
3575	if (port >= VXGE_HAL_MAC_MAX_PORTS) {
3576		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
3577		    __FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_PORT);
3578		return (VXGE_HAL_ERR_INVALID_PORT);
3579	}
3580
3581	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
3582
3583		if (!(hldev->vpath_assignments & mBIT(i)))
3584			continue;
3585
3586		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
3587		    hldev->header.regh0,
3588		    &hldev->vpmgmt_reg[i]->
3589		    rxmac_pause_cfg_port_vpmgmt_clone[port]);
3590
3591		if (val64 & VXGE_HAL_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_GEN_EN)
3592			*tx = 1;
3593
3594		if (val64 & VXGE_HAL_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_RCV_EN)
3595			*rx = 1;
3596
3597		status = VXGE_HAL_OK;
3598
3599		break;
3600	}
3601
3602	vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
3603	    __FILE__, __func__, __LINE__, status);
3604
3605	return (status);
3606}
3607
3608vxge_hal_status_e
3609vxge_hal_device_is_privileged(u32 host_type, u32 func_id)
3610{
3611	u32 access_rights;
3612	vxge_hal_status_e status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
3613
3614	access_rights = __hal_device_access_rights_get(host_type, func_id);
3615
3616	if (access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)
3617		status = VXGE_HAL_OK;
3618
3619	return (status);
3620}
3621