1221167Sgnn/*-
2221167Sgnn * Copyright(c) 2002-2011 Exar Corp.
3221167Sgnn * All rights reserved.
4221167Sgnn *
5221167Sgnn * Redistribution and use in source and binary forms, with or without
6221167Sgnn * modification are permitted provided the following conditions are met:
7221167Sgnn *
8221167Sgnn *    1. Redistributions of source code must retain the above copyright notice,
9221167Sgnn *       this list of conditions and the following disclaimer.
10221167Sgnn *
11221167Sgnn *    2. Redistributions in binary form must reproduce the above copyright
12221167Sgnn *       notice, this list of conditions and the following disclaimer in the
13221167Sgnn *       documentation and/or other materials provided with the distribution.
14221167Sgnn *
15221167Sgnn *    3. Neither the name of the Exar Corporation nor the names of its
16221167Sgnn *       contributors may be used to endorse or promote products derived from
17221167Sgnn *       this software without specific prior written permission.
18221167Sgnn *
19221167Sgnn * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20221167Sgnn * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21221167Sgnn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22221167Sgnn * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23221167Sgnn * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24221167Sgnn * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25221167Sgnn * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26221167Sgnn * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27221167Sgnn * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28221167Sgnn * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29221167Sgnn * POSSIBILITY OF SUCH DAMAGE.
30221167Sgnn */
31221167Sgnn/*$FreeBSD$*/
32221167Sgnn
33221167Sgnn#include <dev/vxge/vxgehal/vxgehal.h>
34221167Sgnn
35221167Sgnn/*
36221167Sgnn * vxge_hal_pio_mem_write32_upper
37221167Sgnn *
38221167Sgnn * Endiann-aware implementation of vxge_os_pio_mem_write32().
39221167Sgnn * Since X3100 has 64bit registers, we differintiate uppper and lower
40221167Sgnn * parts.
41221167Sgnn */
42221167Sgnnvoid
43221167Sgnnvxge_hal_pio_mem_write32_upper(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr)
44221167Sgnn{
45221167Sgnn#if defined(VXGE_OS_HOST_BIG_ENDIAN) && !defined(VXGE_OS_PIO_LITTLE_ENDIAN)
46221167Sgnn	vxge_os_pio_mem_write32(pdev, regh, val, addr);
47221167Sgnn#else
48221167Sgnn	vxge_os_pio_mem_write32(pdev, regh, val, (void *) ((char *) addr + 4));
49221167Sgnn#endif
50221167Sgnn}
51221167Sgnn
52221167Sgnn/*
53221167Sgnn * vxge_hal_pio_mem_write32_lower
54221167Sgnn *
55221167Sgnn * Endiann-aware implementation of vxge_os_pio_mem_write32().
56221167Sgnn * Since X3100 has 64bit registers, we differintiate uppper and lower
57221167Sgnn * parts.
58221167Sgnn */
59221167Sgnnvoid
60221167Sgnnvxge_hal_pio_mem_write32_lower(pci_dev_h pdev, pci_reg_h regh, u32 val,
61221167Sgnn    void *addr)
62221167Sgnn{
63221167Sgnn#if defined(VXGE_OS_HOST_BIG_ENDIAN) && !defined(VXGE_OS_PIO_LITTLE_ENDIAN)
64221167Sgnn	vxge_os_pio_mem_write32(pdev, regh, val,
65221167Sgnn	    (void *) ((char *) addr + 4));
66221167Sgnn#else
67221167Sgnn	vxge_os_pio_mem_write32(pdev, regh, val, addr);
68221167Sgnn#endif
69221167Sgnn}
70221167Sgnn
71221167Sgnn/*
72221167Sgnn * vxge_hal_device_pciconfig_get - Read the content of given address
73221167Sgnn *			 in pci config space.
74221167Sgnn * @devh: Device handle.
75221167Sgnn * @offset: Configuration address(offset)to read from
76221167Sgnn * @length: Length of the data (1, 2 or 4 bytes)
77221167Sgnn * @val: Pointer to a buffer to return the content of the address
78221167Sgnn *
79221167Sgnn * Read from the pci config space.
80221167Sgnn *
81221167Sgnn */
82221167Sgnnvxge_hal_status_e
83221167Sgnnvxge_hal_device_pciconfig_get(
84221167Sgnn    vxge_hal_device_h devh,
85221167Sgnn    u32 offset,
86221167Sgnn    u32 length,
87221167Sgnn    void *val)
88221167Sgnn{
89221167Sgnn	u32 i;
90221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
91221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
92221167Sgnn
93221167Sgnn	vxge_assert((devh != NULL) && (val != NULL));
94221167Sgnn
95221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
96221167Sgnn	    __FILE__, __func__, __LINE__);
97221167Sgnn
98221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
99221167Sgnn	    (ptr_t) devh);
100221167Sgnn
101221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
102221167Sgnn
103221167Sgnn		if (!(hldev->vpath_assignments & mBIT(i)))
104221167Sgnn			continue;
105221167Sgnn
106221167Sgnn		status = __hal_vpath_pci_read(hldev, i,
107221167Sgnn		    offset, length, val);
108221167Sgnn
109221167Sgnn		if (status == VXGE_HAL_OK)
110221167Sgnn			break;
111221167Sgnn
112221167Sgnn	}
113221167Sgnn
114221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
115221167Sgnn	    __FILE__, __func__, __LINE__, status);
116221167Sgnn	return (status);
117221167Sgnn
118221167Sgnn}
119221167Sgnn
120221167Sgnn/*
121221167Sgnn * __hal_device_pci_caps_list_process
122221167Sgnn * @hldev: HAL device handle.
123221167Sgnn *
124221167Sgnn * Process PCI capabilities and initialize the offsets
125221167Sgnn */
126221167Sgnnvoid
127221167Sgnn__hal_device_pci_caps_list_process(__hal_device_t *hldev)
128221167Sgnn{
129221167Sgnn	u8 cap_id;
130221167Sgnn	u16 ext_cap_id;
131221167Sgnn	u16 next_ptr;
132221167Sgnn	u32 *ptr_32;
133221167Sgnn	vxge_hal_pci_config_t *pci_config = &hldev->pci_config_space_bios;
134221167Sgnn
135221167Sgnn	vxge_assert(hldev != NULL);
136221167Sgnn
137221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
138221167Sgnn	    __FILE__, __func__, __LINE__);
139221167Sgnn
140221167Sgnn	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
141221167Sgnn	    (ptr_t) hldev);
142221167Sgnn
143221167Sgnn	next_ptr = pci_config->capabilities_pointer;
144221167Sgnn
145221167Sgnn	while (next_ptr != 0) {
146221167Sgnn
147221167Sgnn		cap_id = VXGE_HAL_PCI_CAP_ID((((u8 *) pci_config) + next_ptr));
148221167Sgnn
149221167Sgnn		switch (cap_id) {
150221167Sgnn
151221167Sgnn		case VXGE_HAL_PCI_CAP_ID_PM:
152221167Sgnn			hldev->pci_caps.pm_cap_offset = next_ptr;
153221167Sgnn			break;
154221167Sgnn		case VXGE_HAL_PCI_CAP_ID_VPD:
155221167Sgnn			hldev->pci_caps.vpd_cap_offset = next_ptr;
156221167Sgnn			break;
157221167Sgnn		case VXGE_HAL_PCI_CAP_ID_SLOTID:
158221167Sgnn			hldev->pci_caps.sid_cap_offset = next_ptr;
159221167Sgnn			break;
160221167Sgnn		case VXGE_HAL_PCI_CAP_ID_MSI:
161221167Sgnn			hldev->pci_caps.msi_cap_offset = next_ptr;
162221167Sgnn			break;
163221167Sgnn		case VXGE_HAL_PCI_CAP_ID_VS:
164221167Sgnn			hldev->pci_caps.vs_cap_offset = next_ptr;
165221167Sgnn			break;
166221167Sgnn		case VXGE_HAL_PCI_CAP_ID_SHPC:
167221167Sgnn			hldev->pci_caps.shpc_cap_offset = next_ptr;
168221167Sgnn			break;
169221167Sgnn		case VXGE_HAL_PCI_CAP_ID_PCIE:
170221167Sgnn			hldev->pci_e_caps = next_ptr;
171221167Sgnn			break;
172221167Sgnn		case VXGE_HAL_PCI_CAP_ID_MSIX:
173221167Sgnn			hldev->pci_caps.msix_cap_offset = next_ptr;
174221167Sgnn			break;
175221167Sgnn		case VXGE_HAL_PCI_CAP_ID_AGP:
176221167Sgnn		case VXGE_HAL_PCI_CAP_ID_CHSWP:
177221167Sgnn		case VXGE_HAL_PCI_CAP_ID_PCIX:
178221167Sgnn		case VXGE_HAL_PCI_CAP_ID_HT:
179221167Sgnn		case VXGE_HAL_PCI_CAP_ID_DBGPORT:
180221167Sgnn		case VXGE_HAL_PCI_CAP_ID_CPCICSR:
181221167Sgnn		case VXGE_HAL_PCI_CAP_ID_PCIBSVID:
182221167Sgnn		case VXGE_HAL_PCI_CAP_ID_AGP8X:
183221167Sgnn		case VXGE_HAL_PCI_CAP_ID_SECDEV:
184221167Sgnn			vxge_hal_info_log_device("Unexpected Capability = %d",
185221167Sgnn			    cap_id);
186221167Sgnn			break;
187221167Sgnn		default:
188221167Sgnn			vxge_hal_info_log_device("Unknown capability = %d",
189221167Sgnn			    cap_id);
190221167Sgnn			break;
191221167Sgnn		}
192221167Sgnn
193221167Sgnn		next_ptr =
194221167Sgnn		    VXGE_HAL_PCI_CAP_NEXT((((u8 *) pci_config) + next_ptr));
195221167Sgnn
196221167Sgnn	}
197221167Sgnn
198221167Sgnn	/* CONSTCOND */
199221167Sgnn	if (VXGE_HAL_PCI_CONFIG_SPACE_SIZE <= 0x100) {
200221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
201221167Sgnn		    __FILE__, __func__, __LINE__);
202221167Sgnn		return;
203221167Sgnn	}
204221167Sgnn
205221167Sgnn	next_ptr = 0x100;
206221167Sgnn	while (next_ptr != 0) {
207221167Sgnn
208221167Sgnn		ptr_32 = (u32 *) ((void *) (((u8 *) pci_config) + next_ptr));
209221167Sgnn		ext_cap_id = (u16) (VXGE_HAL_PCI_EXT_CAP_ID(*ptr_32));
210221167Sgnn
211221167Sgnn		switch (ext_cap_id) {
212221167Sgnn
213221167Sgnn		case VXGE_HAL_PCI_EXT_CAP_ID_ERR:
214221167Sgnn			hldev->pci_e_ext_caps.err_cap_offset = next_ptr;
215221167Sgnn			break;
216221167Sgnn		case VXGE_HAL_PCI_EXT_CAP_ID_VC:
217221167Sgnn			hldev->pci_e_ext_caps.vc_cap_offset = next_ptr;
218221167Sgnn			break;
219221167Sgnn		case VXGE_HAL_PCI_EXT_CAP_ID_DSN:
220221167Sgnn			hldev->pci_e_ext_caps.dsn_cap_offset = next_ptr;
221221167Sgnn			break;
222221167Sgnn		case VXGE_HAL_PCI_EXT_CAP_ID_PWR:
223221167Sgnn			hldev->pci_e_ext_caps.pwr_budget_cap_offset = next_ptr;
224221167Sgnn			break;
225221167Sgnn
226221167Sgnn		default:
227221167Sgnn			vxge_hal_info_log_device("Unknown capability = %d",
228221167Sgnn			    ext_cap_id);
229221167Sgnn			break;
230221167Sgnn		}
231221167Sgnn
232221167Sgnn		next_ptr = (u16) VXGE_HAL_PCI_EXT_CAP_NEXT(*ptr_32);
233221167Sgnn	}
234221167Sgnn
235221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
236221167Sgnn	    __FILE__, __func__, __LINE__);
237221167Sgnn}
238221167Sgnn
239221167Sgnn/*
240221167Sgnn * __hal_device_pci_e_init
241221167Sgnn * @hldev: HAL device handle.
242221167Sgnn *
243221167Sgnn * Initialize certain PCI/PCI-X configuration registers
244221167Sgnn * with recommended values. Save config space for future hw resets.
245221167Sgnn */
246221167Sgnnvoid
247221167Sgnn__hal_device_pci_e_init(__hal_device_t *hldev)
248221167Sgnn{
249221167Sgnn	int i;
250221167Sgnn	u16 cmd;
251221167Sgnn	u32 *ptr_32;
252221167Sgnn
253221167Sgnn	vxge_assert(hldev != NULL);
254221167Sgnn
255221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
256221167Sgnn	    __FILE__, __func__, __LINE__);
257221167Sgnn
258221167Sgnn	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
259221167Sgnn	    (ptr_t) hldev);
260221167Sgnn
261221167Sgnn	/* save original PCI config space to restore it on device_terminate() */
262221167Sgnn	ptr_32 = (u32 *) ((void *) &hldev->pci_config_space_bios);
263221167Sgnn	for (i = 0; i < VXGE_HAL_PCI_CONFIG_SPACE_SIZE / 4; i++) {
264221167Sgnn		(void) __hal_vpath_pci_read(hldev,
265221167Sgnn		    hldev->first_vp_id,
266221167Sgnn		    i * 4,
267221167Sgnn		    4,
268221167Sgnn		    ptr_32 + i);
269221167Sgnn	}
270221167Sgnn
271221167Sgnn	__hal_device_pci_caps_list_process(hldev);
272221167Sgnn
273221167Sgnn	/* Set the PErr Repconse bit and SERR in PCI command register. */
274221167Sgnn	(void) __hal_vpath_pci_read(hldev,
275221167Sgnn	    hldev->first_vp_id,
276221167Sgnn	    vxge_offsetof(vxge_hal_pci_config_le_t, command),
277221167Sgnn	    2,
278221167Sgnn	    &cmd);
279221167Sgnn	cmd |= 0x140;
280221167Sgnn	vxge_os_pci_write16(hldev->header.pdev, hldev->header.cfgh,
281221167Sgnn	    vxge_offsetof(vxge_hal_pci_config_le_t, command), cmd);
282221167Sgnn
283221167Sgnn	/* save PCI config space for future resets */
284221167Sgnn	ptr_32 = (u32 *) ((void *) &hldev->pci_config_space);
285221167Sgnn	for (i = 0; i < VXGE_HAL_PCI_CONFIG_SPACE_SIZE / 4; i++) {
286221167Sgnn		(void) __hal_vpath_pci_read(hldev,
287221167Sgnn		    hldev->first_vp_id,
288221167Sgnn		    i * 4,
289221167Sgnn		    4,
290221167Sgnn		    ptr_32 + i);
291221167Sgnn	}
292221167Sgnn
293221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
294221167Sgnn	    __FILE__, __func__, __LINE__);
295221167Sgnn}
296221167Sgnn
297221167Sgnn/*
298221167Sgnn * __hal_device_bus_master_enable
299221167Sgnn * @hldev: HAL device handle.
300221167Sgnn *
301221167Sgnn * Enable bus mastership.
302221167Sgnn */
303221167Sgnnstatic void
304221167Sgnn__hal_device_bus_master_enable(__hal_device_t *hldev)
305221167Sgnn{
306221167Sgnn	u16 cmd;
307221167Sgnn	u16 bus_master = 4;
308221167Sgnn
309221167Sgnn	vxge_assert(hldev != NULL);
310221167Sgnn
311221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
312221167Sgnn	    __FILE__, __func__, __LINE__);
313221167Sgnn
314221167Sgnn	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
315221167Sgnn	    (ptr_t) hldev);
316221167Sgnn
317221167Sgnn	(void) __hal_vpath_pci_read(hldev,
318221167Sgnn	    hldev->first_vp_id,
319221167Sgnn	    vxge_offsetof(vxge_hal_pci_config_le_t, command),
320221167Sgnn	    2,
321221167Sgnn	    &cmd);
322221167Sgnn	/* already enabled? do nothing */
323221167Sgnn	if (cmd & bus_master)
324221167Sgnn		return;
325221167Sgnn
326221167Sgnn	cmd |= bus_master;
327221167Sgnn	vxge_os_pci_write16(hldev->header.pdev, hldev->header.cfgh,
328221167Sgnn	    vxge_offsetof(vxge_hal_pci_config_le_t, command), cmd);
329221167Sgnn
330221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
331221167Sgnn	    __FILE__, __func__, __LINE__);
332221167Sgnn}
333221167Sgnn
334221167Sgnn/*
335221167Sgnn * vxge_hal_device_register_poll
336221167Sgnn * @pdev: PCI device object.
337221167Sgnn * @regh: BAR mapped memory handle (Solaris), or simply PCI device @pdev
338221167Sgnn *	(Linux and the rest.)
339221167Sgnn * @reg: register to poll for
340221167Sgnn * @op: 0 - bit reset, 1 - bit set
341221167Sgnn * @mask: mask for logical "and" condition based on %op
342221167Sgnn * @max_millis: maximum time to try to poll in milliseconds
343221167Sgnn *
344221167Sgnn * Will poll certain register for specified amount of time.
345221167Sgnn * Will poll until masked bit is not cleared.
346221167Sgnn */
347221167Sgnnvxge_hal_status_e
348221167Sgnnvxge_hal_device_register_poll(
349221167Sgnn    pci_dev_h pdev,
350221167Sgnn    pci_reg_h regh,
351221167Sgnn    u64 *reg,
352221167Sgnn    u32 op,
353221167Sgnn    u64 mask,
354221167Sgnn    u32 max_millis)
355221167Sgnn{
356221167Sgnn	u64 val64;
357221167Sgnn	u32 i = 0;
358221167Sgnn	vxge_hal_status_e ret = VXGE_HAL_FAIL;
359221167Sgnn
360221167Sgnn	vxge_os_udelay(10);
361221167Sgnn
362221167Sgnn	do {
363221167Sgnn		val64 = vxge_os_pio_mem_read64(pdev, regh, reg);
364221167Sgnn		if (op == 0 && !(val64 & mask)) {
365221167Sgnn			return (VXGE_HAL_OK);
366221167Sgnn		} else if (op == 1 && (val64 & mask) == mask)
367221167Sgnn			return (VXGE_HAL_OK);
368221167Sgnn		vxge_os_udelay(100);
369221167Sgnn	} while (++i <= 9);
370221167Sgnn
371221167Sgnn	do {
372221167Sgnn		val64 = vxge_os_pio_mem_read64(pdev, regh, reg);
373221167Sgnn		if (op == 0 && !(val64 & mask)) {
374221167Sgnn			return (VXGE_HAL_OK);
375221167Sgnn		} else if (op == 1 && (val64 & mask) == mask) {
376221167Sgnn			return (VXGE_HAL_OK);
377221167Sgnn		}
378221167Sgnn		vxge_os_udelay(1000);
379221167Sgnn	} while (++i < max_millis);
380221167Sgnn
381221167Sgnn	return (ret);
382221167Sgnn}
383221167Sgnn
384221167Sgnn/*
385221167Sgnn * __hal_device_register_stall
386221167Sgnn * @pdev: PCI device object.
387221167Sgnn * @regh: BAR mapped memory handle (Solaris), or simply PCI device @pdev
388221167Sgnn *	(Linux and the rest.)
389221167Sgnn * @reg: register to poll for
390221167Sgnn * @op: 0 - bit reset, 1 - bit set
391221167Sgnn * @mask: mask for logical "and" condition based on %op
392221167Sgnn * @max_millis: maximum time to try to poll in milliseconds
393221167Sgnn *
394221167Sgnn * Will poll certain register for specified amount of time.
395221167Sgnn * Will poll until masked bit is not cleared.
396221167Sgnn */
397221167Sgnnvxge_hal_status_e
398221167Sgnn__hal_device_register_stall(
399221167Sgnn    pci_dev_h pdev,
400221167Sgnn    pci_reg_h regh,
401221167Sgnn    u64 *reg,
402221167Sgnn    u32 op,
403221167Sgnn    u64 mask,
404221167Sgnn    u32 max_millis)
405221167Sgnn{
406221167Sgnn	u64 val64;
407221167Sgnn	u32 i = 0;
408221167Sgnn	vxge_hal_status_e ret = VXGE_HAL_FAIL;
409221167Sgnn
410221167Sgnn	vxge_os_stall(10);
411221167Sgnn
412221167Sgnn	do {
413221167Sgnn		val64 = vxge_os_pio_mem_read64(pdev, regh, reg);
414221167Sgnn		if (op == 0 && !(val64 & mask)) {
415221167Sgnn			return (VXGE_HAL_OK);
416221167Sgnn		} else if (op == 1 && (val64 & mask) == mask)
417221167Sgnn			return (VXGE_HAL_OK);
418221167Sgnn		vxge_os_stall(100);
419221167Sgnn	} while (++i <= 9);
420221167Sgnn
421221167Sgnn	do {
422221167Sgnn		val64 = vxge_os_pio_mem_read64(pdev, regh, reg);
423221167Sgnn		if (op == 0 && !(val64 & mask)) {
424221167Sgnn			return (VXGE_HAL_OK);
425221167Sgnn		} else if (op == 1 && (val64 & mask) == mask) {
426221167Sgnn			return (VXGE_HAL_OK);
427221167Sgnn		}
428221167Sgnn		vxge_os_stall(1000);
429221167Sgnn	} while (++i < max_millis);
430221167Sgnn
431221167Sgnn	return (ret);
432221167Sgnn}
433221167Sgnn
434221167Sgnnvoid*
435221167Sgnnvxge_hal_device_get_legacy_reg(pci_dev_h pdev, pci_reg_h regh, u8 *bar0)
436221167Sgnn{
437221167Sgnn	vxge_hal_legacy_reg_t *legacy_reg = NULL;
438221167Sgnn
439221167Sgnn	/*
440221167Sgnn	 * If length of Bar0 is 16MB, then assume we are configured
441221167Sgnn	 * in MF8P_VP2 mode and add 8MB to get legacy_reg offsets
442221167Sgnn	 */
443221167Sgnn	if (vxge_os_pci_res_len(pdev, regh) == 0x1000000)
444221167Sgnn		legacy_reg = (vxge_hal_legacy_reg_t *)
445221167Sgnn		    ((void *) (bar0 + 0x800000));
446221167Sgnn	else
447221167Sgnn		legacy_reg = (vxge_hal_legacy_reg_t *)
448221167Sgnn		    ((void *) bar0);
449221167Sgnn
450221167Sgnn	return (legacy_reg);
451221167Sgnn}
452221167Sgnn
453221167Sgnn/*
454221167Sgnn * __hal_device_reg_addr_get
455221167Sgnn * @hldev: HAL Device object.
456221167Sgnn *
457221167Sgnn * This routine sets the swapper and reads the toc pointer and initializes the
458221167Sgnn * register location pointers in the device object. It waits until the ric is
459221167Sgnn * completed initializing registers.
460221167Sgnn */
461221167Sgnnvxge_hal_status_e
462221167Sgnn__hal_device_reg_addr_get(__hal_device_t *hldev)
463221167Sgnn{
464221167Sgnn	u64 val64;
465221167Sgnn	u32 i;
466221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
467221167Sgnn
468221167Sgnn	vxge_assert(hldev);
469221167Sgnn
470221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
471221167Sgnn	    __FILE__, __func__, __LINE__);
472221167Sgnn
473221167Sgnn	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
474221167Sgnn	    (ptr_t) hldev);
475221167Sgnn
476221167Sgnn	hldev->legacy_reg = (vxge_hal_legacy_reg_t *)
477221167Sgnn	    vxge_hal_device_get_legacy_reg(hldev->header.pdev,
478221167Sgnn		hldev->header.regh0, hldev->header.bar0);
479221167Sgnn
480221167Sgnn	status = __hal_legacy_swapper_set(hldev->header.pdev,
481221167Sgnn	    hldev->header.regh0,
482221167Sgnn	    hldev->legacy_reg);
483221167Sgnn
484221167Sgnn	if (status != VXGE_HAL_OK) {
485221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
486221167Sgnn		    __FILE__, __func__, __LINE__, status);
487221167Sgnn		return (status);
488221167Sgnn	}
489221167Sgnn
490221167Sgnn	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
491221167Sgnn	    hldev->header.regh0,
492221167Sgnn	    &hldev->legacy_reg->toc_first_pointer);
493221167Sgnn
494221167Sgnn	hldev->toc_reg = (vxge_hal_toc_reg_t *)
495221167Sgnn	    ((void *) (hldev->header.bar0 + val64));
496221167Sgnn
497221167Sgnn	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
498221167Sgnn	    hldev->header.regh0,
499221167Sgnn	    &hldev->toc_reg->toc_common_pointer);
500221167Sgnn
501221167Sgnn	hldev->common_reg = (vxge_hal_common_reg_t *)
502221167Sgnn	    ((void *) (hldev->header.bar0 + val64));
503221167Sgnn
504221167Sgnn	vxge_hal_info_log_device("COMMON = 0x"VXGE_OS_STXFMT,
505221167Sgnn	    (ptr_t) hldev->common_reg);
506221167Sgnn
507221167Sgnn	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
508221167Sgnn	    hldev->header.regh0,
509221167Sgnn	    &hldev->toc_reg->toc_memrepair_pointer);
510221167Sgnn
511221167Sgnn	hldev->memrepair_reg = (vxge_hal_memrepair_reg_t *)
512221167Sgnn	    ((void *) (hldev->header.bar0 + val64));
513221167Sgnn
514221167Sgnn	vxge_hal_info_log_device("MEM REPAIR = 0x"VXGE_OS_STXFMT,
515221167Sgnn	    (ptr_t) hldev->memrepair_reg);
516221167Sgnn
517221167Sgnn	for (i = 0; i < VXGE_HAL_TITAN_PCICFGMGMT_REG_SPACES; i++) {
518221167Sgnn		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
519221167Sgnn		    hldev->header.regh0,
520221167Sgnn		    &hldev->toc_reg->toc_pcicfgmgmt_pointer[i]);
521221167Sgnn
522221167Sgnn		hldev->pcicfgmgmt_reg[i] = (vxge_hal_pcicfgmgmt_reg_t *)
523221167Sgnn		    ((void *) (hldev->header.bar0 + val64));
524221167Sgnn		vxge_hal_info_log_device("PCICFG_MGMT[%d] = "
525221167Sgnn		    "0x"VXGE_OS_STXFMT, i, (ptr_t) hldev->pcicfgmgmt_reg[i]);
526221167Sgnn	}
527221167Sgnn
528221167Sgnn	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
529221167Sgnn	    hldev->header.regh0,
530221167Sgnn	    &hldev->toc_reg->toc_mrpcim_pointer);
531221167Sgnn
532221167Sgnn	hldev->mrpcim_reg = (vxge_hal_mrpcim_reg_t *)
533221167Sgnn	    ((void *) (hldev->header.bar0 + val64));
534221167Sgnn
535221167Sgnn	vxge_hal_info_log_device("MEM REPAIR = 0x"VXGE_OS_STXFMT,
536221167Sgnn	    (ptr_t) hldev->mrpcim_reg);
537221167Sgnn
538221167Sgnn	for (i = 0; i < VXGE_HAL_TITAN_SRPCIM_REG_SPACES; i++) {
539221167Sgnn
540221167Sgnn		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
541221167Sgnn		    hldev->header.regh0,
542221167Sgnn		    &hldev->toc_reg->toc_srpcim_pointer[i]);
543221167Sgnn
544221167Sgnn		hldev->srpcim_reg[i] = (vxge_hal_srpcim_reg_t *)
545221167Sgnn		    ((void *) (hldev->header.bar0 + val64));
546221167Sgnn		vxge_hal_info_log_device("SRPCIM[%d] =0x"VXGE_OS_STXFMT, i,
547221167Sgnn		    (ptr_t) hldev->srpcim_reg[i]);
548221167Sgnn	}
549221167Sgnn
550221167Sgnn	for (i = 0; i < VXGE_HAL_TITAN_VPMGMT_REG_SPACES; i++) {
551221167Sgnn
552221167Sgnn		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
553221167Sgnn		    hldev->header.regh0,
554221167Sgnn		    &hldev->toc_reg->toc_vpmgmt_pointer[i]);
555221167Sgnn
556221167Sgnn		hldev->vpmgmt_reg[i] = (vxge_hal_vpmgmt_reg_t *)
557221167Sgnn		    ((void *) (hldev->header.bar0 + val64));
558221167Sgnn
559221167Sgnn		vxge_hal_info_log_device("VPMGMT[%d] = 0x"VXGE_OS_STXFMT, i,
560221167Sgnn		    (ptr_t) hldev->vpmgmt_reg[i]);
561221167Sgnn	}
562221167Sgnn
563221167Sgnn	for (i = 0; i < VXGE_HAL_TITAN_VPATH_REG_SPACES; i++) {
564221167Sgnn
565221167Sgnn		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
566221167Sgnn		    hldev->header.regh0,
567221167Sgnn		    &hldev->toc_reg->toc_vpath_pointer[i]);
568221167Sgnn
569221167Sgnn		hldev->vpath_reg[i] = (vxge_hal_vpath_reg_t *)
570221167Sgnn		    ((void *) (hldev->header.bar0 + val64));
571221167Sgnn
572221167Sgnn		vxge_hal_info_log_device("VPATH[%d] = 0x"VXGE_OS_STXFMT, i,
573221167Sgnn		    (ptr_t) hldev->vpath_reg[i]);
574221167Sgnn
575221167Sgnn	}
576221167Sgnn
577221167Sgnn	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
578221167Sgnn	    hldev->header.regh0,
579221167Sgnn	    &hldev->toc_reg->toc_kdfc);
580221167Sgnn
581221167Sgnn	switch (VXGE_HAL_TOC_GET_KDFC_INITIAL_BIR(val64)) {
582221167Sgnn	case 0:
583221167Sgnn		hldev->kdfc = hldev->header.bar0 +
584221167Sgnn		    VXGE_HAL_TOC_GET_KDFC_INITIAL_OFFSET(val64);
585221167Sgnn		break;
586221167Sgnn	case 2:
587221167Sgnn		hldev->kdfc = hldev->header.bar1 +
588221167Sgnn		    VXGE_HAL_TOC_GET_KDFC_INITIAL_OFFSET(val64);
589221167Sgnn		break;
590221167Sgnn	case 4:
591221167Sgnn		hldev->kdfc = hldev->header.bar2 +
592221167Sgnn		    VXGE_HAL_TOC_GET_KDFC_INITIAL_OFFSET(val64);
593221167Sgnn		break;
594221167Sgnn	default:
595221167Sgnn		vxge_hal_info_log_device("Invalid BIR = 0x"VXGE_OS_STXFMT,
596221167Sgnn		    (ptr_t) VXGE_HAL_TOC_GET_KDFC_INITIAL_BIR(val64));
597221167Sgnn		break;
598221167Sgnn	}
599221167Sgnn
600221167Sgnn	vxge_hal_info_log_device("KDFC = 0x"VXGE_OS_STXFMT,
601221167Sgnn	    (ptr_t) hldev->kdfc);
602221167Sgnn
603221167Sgnn	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
604221167Sgnn	    hldev->header.regh0,
605221167Sgnn	    &hldev->toc_reg->toc_usdc);
606221167Sgnn
607221167Sgnn	switch (VXGE_HAL_TOC_GET_USDC_INITIAL_BIR(val64)) {
608221167Sgnn	case 0:
609221167Sgnn		hldev->usdc = hldev->header.bar0 +
610221167Sgnn		    VXGE_HAL_TOC_GET_USDC_INITIAL_OFFSET(val64);
611221167Sgnn		break;
612221167Sgnn	case 2:
613221167Sgnn		hldev->usdc = hldev->header.bar1 +
614221167Sgnn		    VXGE_HAL_TOC_GET_USDC_INITIAL_OFFSET(val64);
615221167Sgnn		break;
616221167Sgnn	case 4:
617221167Sgnn		hldev->usdc = hldev->header.bar2 +
618221167Sgnn		    VXGE_HAL_TOC_GET_USDC_INITIAL_OFFSET(val64);
619221167Sgnn		break;
620221167Sgnn	default:
621221167Sgnn		vxge_hal_info_log_device("Invalid BIR = 0x"VXGE_OS_STXFMT,
622221167Sgnn		    (ptr_t) VXGE_HAL_TOC_GET_USDC_INITIAL_BIR(val64));
623221167Sgnn		break;
624221167Sgnn	}
625221167Sgnn
626221167Sgnn	vxge_hal_info_log_device("USDC = 0x"VXGE_OS_STXFMT,
627221167Sgnn	    (ptr_t) hldev->usdc);
628221167Sgnn
629221167Sgnn	status = vxge_hal_device_register_poll(hldev->header.pdev,
630221167Sgnn	    hldev->header.regh0,
631221167Sgnn	    &hldev->common_reg->vpath_rst_in_prog, 0,
632221167Sgnn	    VXGE_HAL_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(0x1ffff),
633221167Sgnn	    VXGE_HAL_DEF_DEVICE_POLL_MILLIS);
634221167Sgnn
635221167Sgnn	if (status != VXGE_HAL_OK) {
636221167Sgnn		vxge_hal_err_log_device("%s:vpath_rst_in_prog is not cleared",
637221167Sgnn		    __func__);
638221167Sgnn	}
639221167Sgnn
640221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
641221167Sgnn	    __FILE__, __func__, __LINE__, status);
642221167Sgnn
643221167Sgnn	return (status);
644221167Sgnn}
645221167Sgnn
646221167Sgnn/*
647221167Sgnn * __hal_device_id_get
648221167Sgnn * @hldev: HAL Device object.
649221167Sgnn *
650221167Sgnn * This routine returns sets the device id and revision numbers into the device
651221167Sgnn * structure
652221167Sgnn */
653221167Sgnnvoid
654221167Sgnn__hal_device_id_get(__hal_device_t *hldev)
655221167Sgnn{
656221167Sgnn	vxge_assert(hldev);
657221167Sgnn
658221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
659221167Sgnn	    __FILE__, __func__, __LINE__);
660221167Sgnn
661221167Sgnn	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
662221167Sgnn	    (ptr_t) hldev);
663221167Sgnn
664221167Sgnn	(void) __hal_vpath_pci_read(hldev,
665221167Sgnn	    hldev->first_vp_id,
666221167Sgnn	    vxge_offsetof(vxge_hal_pci_config_le_t, device_id),
667221167Sgnn	    2,
668221167Sgnn	    &hldev->header.device_id);
669221167Sgnn
670221167Sgnn	(void) __hal_vpath_pci_read(hldev,
671221167Sgnn	    hldev->first_vp_id,
672221167Sgnn	    vxge_offsetof(vxge_hal_pci_config_le_t, revision),
673221167Sgnn	    2,
674221167Sgnn	    &hldev->header.revision);
675221167Sgnn
676221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
677221167Sgnn	    __FILE__, __func__, __LINE__);
678221167Sgnn}
679221167Sgnn
680221167Sgnn/*
681221167Sgnn * __hal_device_access_rights_get: Get Access Rights of the driver
682221167Sgnn * @host_type: Host type.
683221167Sgnn * @func_id: Function Id
684221167Sgnn *
685221167Sgnn * This routine returns the Access Rights of the driver
686221167Sgnn */
687221167Sgnnu32
688221167Sgnn__hal_device_access_rights_get(u32 host_type, u32 func_id)
689221167Sgnn{
690221167Sgnn	u32 access_rights = VXGE_HAL_DEVICE_ACCESS_RIGHT_VPATH;
691221167Sgnn
692221167Sgnn	switch (host_type) {
693221167Sgnn	case VXGE_HAL_NO_MR_NO_SR_NORMAL_FUNCTION:
694221167Sgnn		if (func_id == 0) {
695221167Sgnn			access_rights |=
696221167Sgnn			    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM |
697221167Sgnn			    VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM;
698221167Sgnn		}
699221167Sgnn		break;
700221167Sgnn	case VXGE_HAL_MR_NO_SR_VH0_BASE_FUNCTION:
701221167Sgnn		access_rights |= VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM |
702221167Sgnn		    VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM;
703221167Sgnn		break;
704221167Sgnn	case VXGE_HAL_NO_MR_SR_VH0_FUNCTION0:
705221167Sgnn		access_rights |= VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM |
706221167Sgnn		    VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM;
707221167Sgnn		break;
708221167Sgnn	case VXGE_HAL_NO_MR_SR_VH0_VIRTUAL_FUNCTION:
709221167Sgnn	case VXGE_HAL_SR_VH_VIRTUAL_FUNCTION:
710221167Sgnn		break;
711221167Sgnn	case VXGE_HAL_MR_SR_VH0_INVALID_CONFIG:
712221167Sgnn		break;
713221167Sgnn	case VXGE_HAL_SR_VH_FUNCTION0:
714221167Sgnn	case VXGE_HAL_VH_NORMAL_FUNCTION:
715221167Sgnn		access_rights |= VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM;
716221167Sgnn		break;
717221167Sgnn	}
718221167Sgnn
719221167Sgnn	return (access_rights);
720221167Sgnn}
721221167Sgnn
722221167Sgnn/*
723221167Sgnn * __hal_device_host_info_get
724221167Sgnn * @hldev: HAL Device object.
725221167Sgnn *
726221167Sgnn * This routine returns the host type assignments
727221167Sgnn */
728221167Sgnnvoid
729221167Sgnn__hal_device_host_info_get(__hal_device_t *hldev)
730221167Sgnn{
731221167Sgnn	u64 val64;
732221167Sgnn	u32 i;
733221167Sgnn
734221167Sgnn	vxge_assert(hldev);
735221167Sgnn
736221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
737221167Sgnn	    __FILE__, __func__, __LINE__);
738221167Sgnn
739221167Sgnn	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
740221167Sgnn	    (ptr_t) hldev);
741221167Sgnn
742221167Sgnn	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
743221167Sgnn	    hldev->header.regh0,
744221167Sgnn	    &hldev->common_reg->host_type_assignments);
745221167Sgnn
746221167Sgnn	hldev->host_type = (u32)
747221167Sgnn	    VXGE_HAL_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
748221167Sgnn
749221167Sgnn	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
750221167Sgnn	    hldev->header.regh0,
751221167Sgnn	    &hldev->common_reg->vplane_assignments);
752221167Sgnn
753221167Sgnn	hldev->srpcim_id = (u32)
754221167Sgnn	    VXGE_HAL_VPLANE_ASSIGNMENTS_GET_VPLANE_ASSIGNMENTS(val64);
755221167Sgnn
756221167Sgnn	hldev->vpath_assignments = vxge_os_pio_mem_read64(
757221167Sgnn	    hldev->header.pdev,
758221167Sgnn	    hldev->header.regh0,
759221167Sgnn	    &hldev->common_reg->vpath_assignments);
760221167Sgnn
761221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
762221167Sgnn
763221167Sgnn		if (!(hldev->vpath_assignments & mBIT(i)))
764221167Sgnn			continue;
765221167Sgnn
766221167Sgnn		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
767221167Sgnn		    hldev->header.regh0,
768221167Sgnn		    &hldev->common_reg->debug_assignments);
769221167Sgnn		hldev->vh_id =
770221167Sgnn		    (u32) VXGE_HAL_DEBUG_ASSIGNMENTS_GET_VHLABEL(val64);
771221167Sgnn
772221167Sgnn		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
773221167Sgnn		    hldev->header.regh0,
774221167Sgnn		    &hldev->vpmgmt_reg[i]->vpath_to_func_map_cfg1);
775221167Sgnn		hldev->func_id =
776221167Sgnn		    (u32) VXGE_HAL_VPATH_TO_FUNC_MAP_CFG1_GET_CFG1(val64);
777221167Sgnn
778221167Sgnn		hldev->access_rights = __hal_device_access_rights_get(
779221167Sgnn		    hldev->host_type, hldev->func_id);
780221167Sgnn
781221167Sgnn		if (hldev->access_rights &
782221167Sgnn		    VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM) {
783221167Sgnn			hldev->manager_up = TRUE;
784221167Sgnn		} else {
785221167Sgnn			val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
786221167Sgnn			    hldev->header.regh0,
787221167Sgnn			    &hldev->vpmgmt_reg[i]->srpcim_to_vpath_wmsg);
788221167Sgnn
789221167Sgnn			hldev->manager_up = __hal_ifmsg_is_manager_up(val64);
790221167Sgnn		}
791221167Sgnn
792221167Sgnn		hldev->first_vp_id = i;
793221167Sgnn
794221167Sgnn		break;
795221167Sgnn
796221167Sgnn	}
797221167Sgnn
798221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
799221167Sgnn	    __FILE__, __func__, __LINE__);
800221167Sgnn}
801221167Sgnn
802221167Sgnn/*
803221167Sgnn * __hal_device_pci_e_info_get - Get PCI_E bus informations such as link_width
804221167Sgnn *				  and signalling rate
805221167Sgnn * @hldev: HAL device.
806221167Sgnn * @signalling_rate:	pointer to a variable of enumerated type
807221167Sgnn *			vxge_hal_pci_e_signalling_rate_e {}.
808221167Sgnn * @link_width:		pointer to a variable of enumerated type
809221167Sgnn *			vxge_hal_pci_e_link_width_e {}.
810221167Sgnn *
811221167Sgnn * Get pci-e signalling rate and link width.
812221167Sgnn *
813221167Sgnn * Returns: one of the vxge_hal_status_e {} enumerated types.
814221167Sgnn * VXGE_HAL_OK			- for success.
815221167Sgnn * VXGE_HAL_ERR_INVALID_PCI_INFO - for invalid PCI information from the card.
816221167Sgnn * VXGE_HAL_ERR_BAD_DEVICE_ID	- for invalid card.
817221167Sgnn *
818221167Sgnn */
819221167Sgnnstatic vxge_hal_status_e
820221167Sgnn__hal_device_pci_e_info_get(
821221167Sgnn    __hal_device_t *hldev,
822221167Sgnn    vxge_hal_pci_e_signalling_rate_e *signalling_rate,
823221167Sgnn    vxge_hal_pci_e_link_width_e *link_width)
824221167Sgnn{
825221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
826221167Sgnn	vxge_hal_pci_e_capability_t *pci_e_caps;
827221167Sgnn
828221167Sgnn	vxge_assert((hldev != NULL) && (signalling_rate != NULL) &&
829221167Sgnn	    (link_width != NULL));
830221167Sgnn
831221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
832221167Sgnn	    __FILE__, __func__, __LINE__);
833221167Sgnn
834221167Sgnn	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT
835221167Sgnn	    ", signalling_rate = 0x"VXGE_OS_STXFMT", "
836221167Sgnn	    "link_width = 0x"VXGE_OS_STXFMT, (ptr_t) hldev,
837221167Sgnn	    (ptr_t) signalling_rate, (ptr_t) link_width);
838221167Sgnn
839221167Sgnn	pci_e_caps = (vxge_hal_pci_e_capability_t *)
840221167Sgnn	    (((u8 *) &hldev->pci_config_space_bios) + hldev->pci_e_caps);
841221167Sgnn
842221167Sgnn	switch (pci_e_caps->pci_e_lnkcap & VXGE_HAL_PCI_EXP_LNKCAP_LNK_SPEED) {
843221167Sgnn	case VXGE_HAL_PCI_EXP_LNKCAP_LS_2_5:
844221167Sgnn		*signalling_rate = VXGE_HAL_PCI_E_SIGNALLING_RATE_2_5GB;
845221167Sgnn		break;
846221167Sgnn	case VXGE_HAL_PCI_EXP_LNKCAP_LS_5:
847221167Sgnn		*signalling_rate = VXGE_HAL_PCI_E_SIGNALLING_RATE_5GB;
848221167Sgnn		break;
849221167Sgnn	default:
850221167Sgnn		*signalling_rate =
851221167Sgnn		    VXGE_HAL_PCI_E_SIGNALLING_RATE_UNKNOWN;
852221167Sgnn		break;
853221167Sgnn	}
854221167Sgnn
855221167Sgnn	switch ((pci_e_caps->pci_e_lnksta &
856221167Sgnn	    VXGE_HAL_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4) {
857221167Sgnn	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X1:
858221167Sgnn		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X1;
859221167Sgnn		break;
860221167Sgnn	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X2:
861221167Sgnn		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X2;
862221167Sgnn		break;
863221167Sgnn	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X4:
864221167Sgnn		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X4;
865221167Sgnn		break;
866221167Sgnn	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X8:
867221167Sgnn		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X8;
868221167Sgnn		break;
869221167Sgnn	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X12:
870221167Sgnn		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X12;
871221167Sgnn		break;
872221167Sgnn	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X16:
873221167Sgnn		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X16;
874221167Sgnn		break;
875221167Sgnn	case VXGE_HAL_PCI_EXP_LNKCAP_LW_X32:
876221167Sgnn		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X32;
877221167Sgnn		break;
878221167Sgnn	case VXGE_HAL_PCI_EXP_LNKCAP_LW_RES:
879221167Sgnn	default:
880221167Sgnn		*link_width = VXGE_HAL_PCI_E_LINK_WIDTH_UNKNOWN;
881221167Sgnn		break;
882221167Sgnn	}
883221167Sgnn
884221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
885221167Sgnn	    __FILE__, __func__, __LINE__);
886221167Sgnn	return (status);
887221167Sgnn}
888221167Sgnn
889221167Sgnn/*
890221167Sgnn * __hal_device_hw_initialize
891221167Sgnn * @hldev: HAL device handle.
892221167Sgnn *
893221167Sgnn * Initialize X3100-V hardware.
894221167Sgnn */
895221167Sgnnvxge_hal_status_e
896221167Sgnn__hal_device_hw_initialize(__hal_device_t *hldev)
897221167Sgnn{
898221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
899221167Sgnn
900221167Sgnn	vxge_assert(hldev);
901221167Sgnn
902221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
903221167Sgnn	    __FILE__, __func__, __LINE__);
904221167Sgnn
905221167Sgnn	vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT,
906221167Sgnn	    (ptr_t) hldev);
907221167Sgnn
908221167Sgnn	__hal_device_pci_e_init(hldev);
909221167Sgnn
910221167Sgnn	/* update the pci mode, frequency, and width */
911221167Sgnn	if (__hal_device_pci_e_info_get(hldev, &hldev->header.signalling_rate,
912221167Sgnn	    &hldev->header.link_width) != VXGE_HAL_OK) {
913221167Sgnn		hldev->header.signalling_rate =
914221167Sgnn		    VXGE_HAL_PCI_E_SIGNALLING_RATE_UNKNOWN;
915221167Sgnn		hldev->header.link_width = VXGE_HAL_PCI_E_LINK_WIDTH_UNKNOWN;
916221167Sgnn		/*
917221167Sgnn		 * FIXME: this cannot happen.
918221167Sgnn		 * But if it happens we cannot continue just like that
919221167Sgnn		 */
920221167Sgnn		vxge_hal_err_log_device("unable to get pci info == > %s : %d",
921221167Sgnn		    __func__, __LINE__);
922221167Sgnn	}
923221167Sgnn
924221167Sgnn	if (hldev->access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM) {
925221167Sgnn		status = __hal_srpcim_initialize(hldev);
926221167Sgnn	}
927221167Sgnn
928221167Sgnn	if (hldev->access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM) {
929221167Sgnn		status = __hal_mrpcim_initialize(hldev);
930221167Sgnn	}
931221167Sgnn
932221167Sgnn	if (status == VXGE_HAL_OK) {
933221167Sgnn		hldev->hw_is_initialized = 1;
934221167Sgnn		hldev->header.terminating = 0;
935221167Sgnn	}
936221167Sgnn
937221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
938221167Sgnn	    __FILE__, __func__, __LINE__, status);
939221167Sgnn	return (status);
940221167Sgnn}
941221167Sgnn
942221167Sgnn/*
943221167Sgnn * vxge_hal_device_reset - Reset device.
944221167Sgnn * @devh: HAL device handle.
945221167Sgnn *
946221167Sgnn * Soft-reset the device, reset the device stats except reset_cnt.
947221167Sgnn *
948221167Sgnn *
949221167Sgnn * Returns:  VXGE_HAL_OK - success.
950221167Sgnn * VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED - Device is not initialized.
951221167Sgnn * VXGE_HAL_ERR_RESET_FAILED - Reset failed.
952221167Sgnn *
953221167Sgnn * See also: vxge_hal_status_e {}.
954221167Sgnn */
955221167Sgnnvxge_hal_status_e
956221167Sgnnvxge_hal_device_reset(vxge_hal_device_h devh)
957221167Sgnn{
958221167Sgnn	u32 i;
959221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
960221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
961221167Sgnn
962221167Sgnn	vxge_assert(devh);
963221167Sgnn
964221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
965221167Sgnn	    __FILE__, __func__, __LINE__);
966221167Sgnn
967221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
968221167Sgnn	    (ptr_t) devh);
969221167Sgnn
970221167Sgnn	if (!hldev->header.is_initialized) {
971221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
972221167Sgnn		    __FILE__, __func__, __LINE__,
973221167Sgnn		    VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED);
974221167Sgnn		return (VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED);
975221167Sgnn	}
976221167Sgnn
977221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
978221167Sgnn
979221167Sgnn		if (!(hldev->vpaths_deployed & mBIT(i)))
980221167Sgnn			continue;
981221167Sgnn
982221167Sgnn		status = vxge_hal_vpath_reset(
983221167Sgnn		    VXGE_HAL_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i]));
984221167Sgnn
985221167Sgnn		if (status != VXGE_HAL_OK) {
986221167Sgnn			vxge_hal_err_log_device("vpath %d Reset Failed", i);
987221167Sgnn		}
988221167Sgnn
989221167Sgnn	}
990221167Sgnn
991221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
992221167Sgnn	    __FILE__, __func__, __LINE__, status);
993221167Sgnn	return (status);
994221167Sgnn}
995221167Sgnn
996221167Sgnn/*
997221167Sgnn * vxge_hal_device_reset_poll - Poll the device for reset complete.
998221167Sgnn * @devh: HAL device handle.
999221167Sgnn *
1000221167Sgnn * Poll the device for reset complete
1001221167Sgnn *
1002221167Sgnn * Returns:  VXGE_HAL_OK - success.
1003221167Sgnn * VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED - Device is not initialized.
1004221167Sgnn * VXGE_HAL_ERR_RESET_FAILED - Reset failed.
1005221167Sgnn *
1006221167Sgnn * See also: vxge_hal_status_e {}.
1007221167Sgnn */
1008221167Sgnnvxge_hal_status_e
1009221167Sgnnvxge_hal_device_reset_poll(vxge_hal_device_h devh)
1010221167Sgnn{
1011221167Sgnn	u32 i;
1012221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
1013221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1014221167Sgnn
1015221167Sgnn	vxge_assert(devh);
1016221167Sgnn
1017221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
1018221167Sgnn	    __FILE__, __func__, __LINE__);
1019221167Sgnn
1020221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1021221167Sgnn	    (ptr_t) devh);
1022221167Sgnn
1023221167Sgnn	if (!hldev->header.is_initialized) {
1024221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1025221167Sgnn		    __FILE__, __func__, __LINE__,
1026221167Sgnn		    VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED);
1027221167Sgnn		return (VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED);
1028221167Sgnn	}
1029221167Sgnn
1030221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1031221167Sgnn
1032221167Sgnn		if (!(hldev->vpaths_deployed & mBIT(i)))
1033221167Sgnn			continue;
1034221167Sgnn
1035221167Sgnn		status = vxge_hal_vpath_reset_poll(
1036221167Sgnn		    VXGE_HAL_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i]));
1037221167Sgnn
1038221167Sgnn		if (status != VXGE_HAL_OK) {
1039221167Sgnn			vxge_hal_err_log_device("vpath %d Reset Poll Failed",
1040221167Sgnn			    i);
1041221167Sgnn		}
1042221167Sgnn
1043221167Sgnn	}
1044221167Sgnn
1045221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1046221167Sgnn	    __FILE__, __func__, __LINE__, status);
1047221167Sgnn
1048221167Sgnn	return (status);
1049221167Sgnn}
1050221167Sgnn
1051221167Sgnn/*
1052221167Sgnn * vxge_hal_device_mrpcim_reset_poll - Poll the device for mrpcim reset complete
1053221167Sgnn * @devh: HAL device handle.
1054221167Sgnn *
1055221167Sgnn * Poll the device for mrpcim reset complete
1056221167Sgnn *
1057221167Sgnn * Returns:  VXGE_HAL_OK - success.
1058221167Sgnn * VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED - Device is not initialized.
1059221167Sgnn * VXGE_HAL_ERR_RESET_FAILED - Reset failed.
1060221167Sgnn * VXGE_HAL_ERR_MANAGER_NOT_FOUND - MRPCIM/SRPCIM manager not found
1061221167Sgnn * VXGE_HAL_ERR_TIME_OUT - Device Reset timed out
1062221167Sgnn *
1063221167Sgnn * See also: vxge_hal_status_e {}.
1064221167Sgnn */
1065221167Sgnnvxge_hal_status_e
1066221167Sgnnvxge_hal_device_mrpcim_reset_poll(vxge_hal_device_h devh)
1067221167Sgnn{
1068221167Sgnn	u32 i = 0;
1069221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
1070221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1071221167Sgnn
1072221167Sgnn	vxge_assert(devh);
1073221167Sgnn
1074221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
1075221167Sgnn	    __FILE__, __func__, __LINE__);
1076221167Sgnn
1077221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1078221167Sgnn	    (ptr_t) devh);
1079221167Sgnn
1080221167Sgnn	if (!hldev->header.is_initialized) {
1081221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1082221167Sgnn		    __FILE__, __func__, __LINE__,
1083221167Sgnn		    VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED);
1084221167Sgnn		return (VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED);
1085221167Sgnn	}
1086221167Sgnn
1087221167Sgnn	if (!hldev->manager_up) {
1088221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1089221167Sgnn		    __FILE__, __func__, __LINE__,
1090221167Sgnn		    VXGE_HAL_ERR_MANAGER_NOT_FOUND);
1091221167Sgnn		return (VXGE_HAL_ERR_MANAGER_NOT_FOUND);
1092221167Sgnn	}
1093221167Sgnn
1094221167Sgnn	status = __hal_ifmsg_device_reset_end_poll(
1095221167Sgnn	    hldev, hldev->first_vp_id);
1096221167Sgnn
1097221167Sgnn	if (status != VXGE_HAL_OK) {
1098221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1099221167Sgnn		    __FILE__, __func__, __LINE__,
1100221167Sgnn		    VXGE_HAL_ERR_TIME_OUT);
1101221167Sgnn		return (VXGE_HAL_ERR_TIME_OUT);
1102221167Sgnn	}
1103221167Sgnn
1104221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1105221167Sgnn
1106221167Sgnn		if (!(hldev->vpaths_deployed & mBIT(i)))
1107221167Sgnn			continue;
1108221167Sgnn
1109221167Sgnn		status = vxge_hal_vpath_reset_poll(
1110221167Sgnn		    VXGE_HAL_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i]));
1111221167Sgnn
1112221167Sgnn		if (status != VXGE_HAL_OK) {
1113221167Sgnn			vxge_hal_err_log_device("vpath %d Reset Poll Failed",
1114221167Sgnn			    i);
1115221167Sgnn		}
1116221167Sgnn
1117221167Sgnn	}
1118221167Sgnn
1119221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1120221167Sgnn	    __FILE__, __func__, __LINE__, status);
1121221167Sgnn
1122221167Sgnn	return (status);
1123221167Sgnn}
1124221167Sgnn
1125221167Sgnn/*
1126221167Sgnn * vxge_hal_device_status - Check whether X3100 hardware is ready for
1127221167Sgnn * operation.
1128221167Sgnn * @devh: HAL device handle.
1129221167Sgnn * @hw_status: X3100 status register. Returned by HAL.
1130221167Sgnn *
1131221167Sgnn * Check whether X3100 hardware is ready for operation.
1132221167Sgnn * The checking includes TDMA, RDMA, PFC, PIC, MC_DRAM, and the rest
1133221167Sgnn * hardware functional blocks.
1134221167Sgnn *
1135221167Sgnn * Returns: VXGE_HAL_OK if the device is ready for operation. Otherwise
1136221167Sgnn * returns VXGE_HAL_FAIL. Also, fills in  adapter status (in @hw_status).
1137221167Sgnn *
1138221167Sgnn * See also: vxge_hal_status_e {}.
1139221167Sgnn * Usage: See ex_open {}.
1140221167Sgnn */
1141221167Sgnnvxge_hal_status_e
1142221167Sgnnvxge_hal_device_status(vxge_hal_device_h devh, u64 *hw_status)
1143221167Sgnn{
1144221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1145221167Sgnn
1146221167Sgnn	vxge_assert((hldev != NULL) && (hw_status != NULL));
1147221167Sgnn
1148221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
1149221167Sgnn	    __FILE__, __func__, __LINE__);
1150221167Sgnn
1151221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1152221167Sgnn	    (ptr_t) devh);
1153221167Sgnn
1154221167Sgnn	*hw_status = vxge_os_pio_mem_read64(hldev->header.pdev,
1155221167Sgnn	    hldev->header.regh0,
1156221167Sgnn	    &hldev->common_reg->adapter_status);
1157221167Sgnn
1158221167Sgnn	vxge_hal_trace_log_device("Adapter_Status = 0x"VXGE_OS_LLXFMT,
1159221167Sgnn	    *hw_status);
1160221167Sgnn
1161221167Sgnn	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_RTDMA_RTDMA_READY)) {
1162221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1163221167Sgnn		    __FILE__, __func__, __LINE__,
1164221167Sgnn		    VXGE_HAL_ERR_RTDMA_RTDMA_READY);
1165221167Sgnn		return (VXGE_HAL_ERR_RTDMA_RTDMA_READY);
1166221167Sgnn	}
1167221167Sgnn
1168221167Sgnn	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_WRDMA_WRDMA_READY)) {
1169221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1170221167Sgnn		    __FILE__, __func__, __LINE__,
1171221167Sgnn		    VXGE_HAL_ERR_WRDMA_WRDMA_READY);
1172221167Sgnn		return (VXGE_HAL_ERR_WRDMA_WRDMA_READY);
1173221167Sgnn	}
1174221167Sgnn
1175221167Sgnn	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_KDFC_KDFC_READY)) {
1176221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1177221167Sgnn		    __FILE__, __func__, __LINE__,
1178221167Sgnn		    VXGE_HAL_ERR_KDFC_KDFC_READY);
1179221167Sgnn		return (VXGE_HAL_ERR_KDFC_KDFC_READY);
1180221167Sgnn	}
1181221167Sgnn
1182221167Sgnn	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_TPA_TMAC_BUF_EMPTY)) {
1183221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1184221167Sgnn		    __FILE__, __func__, __LINE__,
1185221167Sgnn		    VXGE_HAL_ERR_TPA_TMAC_BUF_EMPTY);
1186221167Sgnn		return (VXGE_HAL_ERR_TPA_TMAC_BUF_EMPTY);
1187221167Sgnn	}
1188221167Sgnn
1189221167Sgnn	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_RDCTL_PIC_QUIESCENT)) {
1190221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1191221167Sgnn		    __FILE__, __func__, __LINE__,
1192221167Sgnn		    VXGE_HAL_ERR_RDCTL_PIC_QUIESCENT);
1193221167Sgnn		return (VXGE_HAL_ERR_RDCTL_PIC_QUIESCENT);
1194221167Sgnn	}
1195221167Sgnn
1196221167Sgnn	if (*hw_status & VXGE_HAL_ADAPTER_STATUS_XGMAC_NETWORK_FAULT) {
1197221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1198221167Sgnn		    __FILE__, __func__, __LINE__,
1199221167Sgnn		    VXGE_HAL_ERR_XGMAC_NETWORK_FAULT);
1200221167Sgnn		return (VXGE_HAL_ERR_XGMAC_NETWORK_FAULT);
1201221167Sgnn	}
1202221167Sgnn
1203221167Sgnn	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_ROCRC_OFFLOAD_QUIESCENT)) {
1204221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1205221167Sgnn		    __FILE__, __func__, __LINE__,
1206221167Sgnn		    VXGE_HAL_ERR_ROCRC_OFFLOAD_QUIESCENT);
1207221167Sgnn		return (VXGE_HAL_ERR_ROCRC_OFFLOAD_QUIESCENT);
1208221167Sgnn	}
1209221167Sgnn
1210221167Sgnn	if (!(*hw_status &
1211221167Sgnn	    VXGE_HAL_ADAPTER_STATUS_G3IF_FB_G3IF_FB_GDDR3_READY)) {
1212221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1213221167Sgnn		    __FILE__, __func__, __LINE__,
1214221167Sgnn		    VXGE_HAL_ERR_G3IF_FB_G3IF_FB_GDDR3_READY);
1215221167Sgnn		return (VXGE_HAL_ERR_G3IF_FB_G3IF_FB_GDDR3_READY);
1216221167Sgnn	}
1217221167Sgnn
1218221167Sgnn	if (!(*hw_status &
1219221167Sgnn	    VXGE_HAL_ADAPTER_STATUS_G3IF_CM_G3IF_CM_GDDR3_READY)) {
1220221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1221221167Sgnn		    __FILE__, __func__, __LINE__,
1222221167Sgnn		    VXGE_HAL_ERR_G3IF_CM_G3IF_CM_GDDR3_READY);
1223221167Sgnn		return (VXGE_HAL_ERR_G3IF_CM_G3IF_CM_GDDR3_READY);
1224221167Sgnn	}
1225221167Sgnn
1226221167Sgnn#ifndef	VXGE_HAL_TITAN_EMULATION
1227221167Sgnn	if (*hw_status & VXGE_HAL_ADAPTER_STATUS_RIC_RIC_RUNNING) {
1228221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1229221167Sgnn		    __FILE__, __func__, __LINE__,
1230221167Sgnn		    VXGE_HAL_ERR_RIC_RIC_RUNNING);
1231221167Sgnn		return (VXGE_HAL_ERR_RIC_RIC_RUNNING);
1232221167Sgnn	}
1233221167Sgnn#endif
1234221167Sgnn
1235221167Sgnn	if (*hw_status & VXGE_HAL_ADAPTER_STATUS_CMG_C_PLL_IN_LOCK) {
1236221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1237221167Sgnn		    __FILE__, __func__, __LINE__,
1238221167Sgnn		    VXGE_HAL_ERR_CMG_C_PLL_IN_LOCK);
1239221167Sgnn		return (VXGE_HAL_ERR_CMG_C_PLL_IN_LOCK);
1240221167Sgnn	}
1241221167Sgnn
1242221167Sgnn	if (*hw_status & VXGE_HAL_ADAPTER_STATUS_XGMAC_X_PLL_IN_LOCK) {
1243221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1244221167Sgnn		    __FILE__, __func__, __LINE__,
1245221167Sgnn		    VXGE_HAL_ERR_XGMAC_X_PLL_IN_LOCK);
1246221167Sgnn		return (VXGE_HAL_ERR_XGMAC_X_PLL_IN_LOCK);
1247221167Sgnn	}
1248221167Sgnn
1249221167Sgnn	if (*hw_status & VXGE_HAL_ADAPTER_STATUS_FBIF_M_PLL_IN_LOCK) {
1250221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1251221167Sgnn		    __FILE__, __func__, __LINE__,
1252221167Sgnn		    VXGE_HAL_ERR_FBIF_M_PLL_IN_LOCK);
1253221167Sgnn		return (VXGE_HAL_ERR_FBIF_M_PLL_IN_LOCK);
1254221167Sgnn	}
1255221167Sgnn
1256221167Sgnn	if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_PCC_PCC_IDLE(0xFF))) {
1257221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1258221167Sgnn		    __FILE__, __func__, __LINE__,
1259221167Sgnn		    VXGE_HAL_ERR_PCC_PCC_IDLE);
1260221167Sgnn		return (VXGE_HAL_ERR_PCC_PCC_IDLE);
1261221167Sgnn	}
1262221167Sgnn
1263221167Sgnn	if (!(*hw_status &
1264221167Sgnn	    VXGE_HAL_ADAPTER_STATUS_ROCRC_RC_PRC_QUIESCENT(0xFF))) {
1265221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1266221167Sgnn		    __FILE__, __func__, __LINE__,
1267221167Sgnn		    VXGE_HAL_ERR_ROCRC_RC_PRC_QUIESCENT);
1268221167Sgnn		return (VXGE_HAL_ERR_ROCRC_RC_PRC_QUIESCENT);
1269221167Sgnn	}
1270221167Sgnn
1271221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0x"VXGE_OS_STXFMT,
1272221167Sgnn	    __FILE__, __func__, __LINE__, (ptr_t) *hw_status);
1273221167Sgnn	return (VXGE_HAL_OK);
1274221167Sgnn}
1275221167Sgnn
1276221167Sgnn/*
1277221167Sgnn * vxge_hal_device_is_slot_freeze
1278221167Sgnn * @devh: the device
1279221167Sgnn *
1280221167Sgnn * Returns non-zero if the slot is freezed.
1281221167Sgnn * The determination is made based on the adapter_status
1282221167Sgnn * register which will never give all FFs, unless PCI read
1283221167Sgnn * cannot go through.
1284221167Sgnn */
1285221167Sgnnint
1286221167Sgnnvxge_hal_device_is_slot_freeze(vxge_hal_device_h devh)
1287221167Sgnn{
1288221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1289221167Sgnn	u16 device_id;
1290221167Sgnn	u64 adapter_status;
1291221167Sgnn
1292221167Sgnn	vxge_assert(devh);
1293221167Sgnn
1294221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
1295221167Sgnn	    __FILE__, __func__, __LINE__);
1296221167Sgnn
1297221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1298221167Sgnn	    (ptr_t) devh);
1299221167Sgnn
1300221167Sgnn	adapter_status = vxge_os_pio_mem_read64(hldev->header.pdev,
1301221167Sgnn	    hldev->header.regh0,
1302221167Sgnn	    &hldev->common_reg->adapter_status);
1303221167Sgnn
1304221167Sgnn	(void) __hal_vpath_pci_read(hldev,
1305221167Sgnn	    hldev->first_vp_id,
1306221167Sgnn	    vxge_offsetof(vxge_hal_pci_config_le_t, device_id),
1307221167Sgnn	    2,
1308221167Sgnn	    &device_id);
1309221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1310221167Sgnn	    __FILE__, __func__, __LINE__,
1311221167Sgnn	    (adapter_status == VXGE_HAL_ALL_FOXES) || (device_id == 0xffff));
1312221167Sgnn
1313221167Sgnn	return ((adapter_status == VXGE_HAL_ALL_FOXES) ||
1314221167Sgnn	    (device_id == 0xffff));
1315221167Sgnn}
1316221167Sgnn
1317221167Sgnn/*
1318221167Sgnn * vxge_hal_device_intr_enable - Enable interrupts.
1319221167Sgnn * @devh: HAL device handle.
1320221167Sgnn * @op: One of the vxge_hal_device_intr_e enumerated values specifying
1321221167Sgnn *	  the type(s) of interrupts to enable.
1322221167Sgnn *
1323221167Sgnn * Enable X3100 interrupts. The function is to be executed the last in
1324221167Sgnn * X3100 initialization sequence.
1325221167Sgnn *
1326221167Sgnn * See also: vxge_hal_device_intr_disable()
1327221167Sgnn */
1328221167Sgnnvoid
1329221167Sgnnvxge_hal_device_intr_enable(
1330221167Sgnn    vxge_hal_device_h devh)
1331221167Sgnn{
1332221167Sgnn	u32 i;
1333221167Sgnn	u64 val64;
1334221167Sgnn	u32 val32;
1335221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1336221167Sgnn
1337221167Sgnn	vxge_assert(hldev);
1338221167Sgnn
1339221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1340221167Sgnn	    __FILE__, __func__, __LINE__);
1341221167Sgnn
1342221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
1343221167Sgnn	    (ptr_t) devh);
1344221167Sgnn
1345221167Sgnn	vxge_hal_device_mask_all(hldev);
1346221167Sgnn
1347221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1348221167Sgnn
1349221167Sgnn		if (!(hldev->vpaths_deployed & mBIT(i)))
1350221167Sgnn			continue;
1351221167Sgnn
1352221167Sgnn		(void) __hal_vpath_intr_enable(&hldev->virtual_paths[i]);
1353221167Sgnn	}
1354221167Sgnn
1355221167Sgnn	if ((hldev->header.config.intr_mode == VXGE_HAL_INTR_MODE_IRQLINE) ||
1356221167Sgnn	    (hldev->header.config.intr_mode == VXGE_HAL_INTR_MODE_EMULATED_INTA)) {
1357221167Sgnn
1358221167Sgnn		val64 = hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] |
1359221167Sgnn		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] |
1360221167Sgnn		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_BMAP];
1361221167Sgnn
1362221167Sgnn		if (val64 != 0) {
1363221167Sgnn			vxge_os_pio_mem_write64(hldev->header.pdev,
1364221167Sgnn			    hldev->header.regh0,
1365221167Sgnn			    val64,
1366221167Sgnn			    &hldev->common_reg->tim_int_status0);
1367221167Sgnn
1368221167Sgnn			vxge_os_pio_mem_write64(hldev->header.pdev,
1369221167Sgnn			    hldev->header.regh0,
1370221167Sgnn			    ~val64,
1371221167Sgnn			    &hldev->common_reg->tim_int_mask0);
1372221167Sgnn		}
1373221167Sgnn
1374221167Sgnn		val32 = hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] |
1375221167Sgnn		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] |
1376221167Sgnn		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_BMAP];
1377221167Sgnn
1378221167Sgnn		if (val32 != 0) {
1379221167Sgnn			vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
1380221167Sgnn			    hldev->header.regh0,
1381221167Sgnn			    val32,
1382221167Sgnn			    &hldev->common_reg->tim_int_status1);
1383221167Sgnn
1384221167Sgnn			vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
1385221167Sgnn			    hldev->header.regh0,
1386221167Sgnn			    ~val32,
1387221167Sgnn			    &hldev->common_reg->tim_int_mask1);
1388221167Sgnn		}
1389221167Sgnn	}
1390221167Sgnn
1391221167Sgnn	vxge_os_pio_mem_read64(hldev->header.pdev,
1392221167Sgnn	    hldev->header.regh0,
1393221167Sgnn	    &hldev->common_reg->titan_general_int_status);
1394221167Sgnn
1395221167Sgnn	vxge_hal_device_unmask_all(hldev);
1396221167Sgnn
1397221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1398221167Sgnn	    __FILE__, __func__, __LINE__);
1399221167Sgnn}
1400221167Sgnn
1401221167Sgnn/*
1402221167Sgnn * vxge_hal_device_intr_disable - Disable X3100 interrupts.
1403221167Sgnn * @devh: HAL device handle.
1404221167Sgnn * @op: One of the vxge_hal_device_intr_e enumerated values specifying
1405221167Sgnn *	  the type(s) of interrupts to disable.
1406221167Sgnn *
1407221167Sgnn * Disable X3100 interrupts.
1408221167Sgnn *
1409221167Sgnn * See also: vxge_hal_device_intr_enable()
1410221167Sgnn */
1411221167Sgnnvoid
1412221167Sgnnvxge_hal_device_intr_disable(
1413221167Sgnn    vxge_hal_device_h devh)
1414221167Sgnn{
1415221167Sgnn	u32 i;
1416221167Sgnn	u64 val64;
1417221167Sgnn	u32 val32;
1418221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1419221167Sgnn
1420221167Sgnn	vxge_assert(hldev);
1421221167Sgnn
1422221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1423221167Sgnn	    __FILE__, __func__, __LINE__);
1424221167Sgnn
1425221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
1426221167Sgnn	    (ptr_t) devh);
1427221167Sgnn
1428221167Sgnn	vxge_hal_device_mask_all(hldev);
1429221167Sgnn
1430221167Sgnn	if ((hldev->header.config.intr_mode ==
1431221167Sgnn	    VXGE_HAL_INTR_MODE_IRQLINE) ||
1432221167Sgnn	    (hldev->header.config.intr_mode ==
1433221167Sgnn	    VXGE_HAL_INTR_MODE_EMULATED_INTA)) {
1434221167Sgnn
1435221167Sgnn		val64 = hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] |
1436221167Sgnn		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] |
1437221167Sgnn		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_BMAP];
1438221167Sgnn
1439221167Sgnn		if (val64 != 0) {
1440221167Sgnn			vxge_os_pio_mem_write64(hldev->header.pdev,
1441221167Sgnn			    hldev->header.regh0,
1442221167Sgnn			    val64,
1443221167Sgnn			    &hldev->common_reg->tim_int_mask0);
1444221167Sgnn		}
1445221167Sgnn
1446221167Sgnn		val32 = hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] |
1447221167Sgnn		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] |
1448221167Sgnn		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_BMAP];
1449221167Sgnn
1450221167Sgnn		if (val32 != 0) {
1451221167Sgnn			vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
1452221167Sgnn			    hldev->header.regh0,
1453221167Sgnn			    val32,
1454221167Sgnn			    &hldev->common_reg->tim_int_mask1);
1455221167Sgnn		}
1456221167Sgnn	}
1457221167Sgnn
1458221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1459221167Sgnn
1460221167Sgnn		if (!(hldev->vpaths_deployed & mBIT(i)))
1461221167Sgnn			continue;
1462221167Sgnn
1463221167Sgnn		(void) __hal_vpath_intr_disable(&hldev->virtual_paths[i]);
1464221167Sgnn	}
1465221167Sgnn
1466221167Sgnn	vxge_hal_device_unmask_all(hldev);
1467221167Sgnn
1468221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1469221167Sgnn	    __FILE__, __func__, __LINE__);
1470221167Sgnn}
1471221167Sgnn
1472221167Sgnn/*
1473221167Sgnn * vxge_hal_device_mask_all - Mask all device interrupts.
1474221167Sgnn * @devh: HAL device handle.
1475221167Sgnn *
1476221167Sgnn * Mask	all	device interrupts.
1477221167Sgnn *
1478221167Sgnn * See also: vxge_hal_device_unmask_all()
1479221167Sgnn */
1480221167Sgnnvoid
1481221167Sgnnvxge_hal_device_mask_all(
1482221167Sgnn    vxge_hal_device_h devh)
1483221167Sgnn{
1484221167Sgnn	u64 val64;
1485221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1486221167Sgnn
1487221167Sgnn	vxge_assert(hldev);
1488221167Sgnn
1489221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1490221167Sgnn	    __FILE__, __func__, __LINE__);
1491221167Sgnn
1492221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
1493221167Sgnn	    (ptr_t) devh);
1494221167Sgnn
1495221167Sgnn	val64 = VXGE_HAL_TITAN_MASK_ALL_INT_ALARM |
1496221167Sgnn	    VXGE_HAL_TITAN_MASK_ALL_INT_TRAFFIC;
1497221167Sgnn
1498221167Sgnn	vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
1499221167Sgnn	    hldev->header.regh0,
1500221167Sgnn	    (u32) bVAL32(val64, 0),
1501221167Sgnn	    &hldev->common_reg->titan_mask_all_int);
1502221167Sgnn
1503221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1504221167Sgnn	    __FILE__, __func__, __LINE__);
1505221167Sgnn}
1506221167Sgnn
1507221167Sgnn/*
1508221167Sgnn * vxge_hal_device_unmask_all - Unmask all device interrupts.
1509221167Sgnn * @devh: HAL device handle.
1510221167Sgnn *
1511221167Sgnn * Unmask all device interrupts.
1512221167Sgnn *
1513221167Sgnn * See also: vxge_hal_device_mask_all()
1514221167Sgnn */
1515221167Sgnnvoid
1516221167Sgnnvxge_hal_device_unmask_all(
1517221167Sgnn    vxge_hal_device_h devh)
1518221167Sgnn{
1519221167Sgnn	u64 val64 = 0;
1520221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1521221167Sgnn
1522221167Sgnn	vxge_assert(hldev);
1523221167Sgnn
1524221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1525221167Sgnn	    __FILE__, __func__, __LINE__);
1526221167Sgnn
1527221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
1528221167Sgnn	    (ptr_t) devh);
1529221167Sgnn
1530221167Sgnn	if (hldev->header.config.intr_mode == VXGE_HAL_INTR_MODE_IRQLINE)
1531221167Sgnn		val64 = VXGE_HAL_TITAN_MASK_ALL_INT_TRAFFIC;
1532221167Sgnn
1533221167Sgnn	vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
1534221167Sgnn	    hldev->header.regh0,
1535221167Sgnn	    (u32) bVAL32(val64, 0),
1536221167Sgnn	    &hldev->common_reg->titan_mask_all_int);
1537221167Sgnn
1538221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1539221167Sgnn	    __FILE__, __func__, __LINE__);
1540221167Sgnn}
1541221167Sgnn
1542221167Sgnn/*
1543221167Sgnn * vxge_hal_device_begin_irq - Begin IRQ processing.
1544221167Sgnn * @devh: HAL device handle.
1545221167Sgnn * @skip_alarms: Do not clear the alarms
1546221167Sgnn * @reason: "Reason" for the interrupt,	the value of X3100's
1547221167Sgnn *			general_int_status register.
1548221167Sgnn *
1549221167Sgnn * The function	performs two actions, It first checks whether (shared IRQ) the
1550221167Sgnn * interrupt was raised	by the device. Next, it	masks the device interrupts.
1551221167Sgnn *
1552221167Sgnn * Note:
1553221167Sgnn * vxge_hal_device_begin_irq() does not flush MMIO writes through the
1554221167Sgnn * bridge. Therefore, two back-to-back interrupts are potentially possible.
1555221167Sgnn * It is the responsibility	of the ULD to make sure	that only one
1556221167Sgnn * vxge_hal_device_continue_irq() runs at a time.
1557221167Sgnn *
1558221167Sgnn * Returns: 0, if the interrupt	is not "ours" (note that in this case the
1559221167Sgnn * device remain enabled).
1560221167Sgnn * Otherwise, vxge_hal_device_begin_irq() returns 64bit general adapter
1561221167Sgnn * status.
1562221167Sgnn * See also: vxge_hal_device_handle_irq()
1563221167Sgnn */
1564221167Sgnnvxge_hal_status_e
1565221167Sgnnvxge_hal_device_begin_irq(
1566221167Sgnn    vxge_hal_device_h devh,
1567221167Sgnn    u32 skip_alarms,
1568221167Sgnn    u64 *reason)
1569221167Sgnn{
1570221167Sgnn	u32 i;
1571221167Sgnn	u64 val64;
1572221167Sgnn	u64 adapter_status;
1573221167Sgnn	u64 vpath_mask;
1574221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1575221167Sgnn	vxge_hal_status_e ret = VXGE_HAL_ERR_WRONG_IRQ;
1576221167Sgnn	vxge_hal_status_e status;
1577221167Sgnn
1578221167Sgnn	vxge_assert((hldev != NULL) && (reason != NULL));
1579221167Sgnn
1580221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1581221167Sgnn	    __FILE__, __func__, __LINE__);
1582221167Sgnn
1583221167Sgnn	vxge_hal_trace_log_device_irq(
1584221167Sgnn	    "devh = 0x"VXGE_OS_STXFMT", skip_alarms = %d, "
1585221167Sgnn	    "reason = 0x"VXGE_OS_STXFMT, (ptr_t) devh,
1586221167Sgnn	    skip_alarms, (ptr_t) reason);
1587221167Sgnn
1588221167Sgnn	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
1589221167Sgnn	    hldev->header.regh0,
1590221167Sgnn	    &hldev->common_reg->titan_general_int_status);
1591221167Sgnn
1592221167Sgnn	if (vxge_os_unlikely(!val64)) {
1593221167Sgnn		/* not Titan interrupt	 */
1594221167Sgnn		*reason = 0;
1595221167Sgnn		ret = VXGE_HAL_ERR_WRONG_IRQ;
1596221167Sgnn		vxge_hal_info_log_device_irq("wrong_isr general_int_status = \
1597221167Sgnn		    0x%llx", val64);
1598221167Sgnn		vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = %d",
1599221167Sgnn		    __FILE__, __func__, __LINE__, ret);
1600221167Sgnn		return (ret);
1601221167Sgnn	}
1602221167Sgnn
1603221167Sgnn	if (vxge_os_unlikely(val64 == VXGE_HAL_ALL_FOXES)) {
1604221167Sgnn
1605221167Sgnn		adapter_status = vxge_os_pio_mem_read64(hldev->header.pdev,
1606221167Sgnn		    hldev->header.regh0,
1607221167Sgnn		    &hldev->common_reg->adapter_status);
1608221167Sgnn
1609221167Sgnn		if (adapter_status == VXGE_HAL_ALL_FOXES) {
1610221167Sgnn			vxge_hal_info_log_device_irq("%s:Slot is frozen",
1611221167Sgnn			    __func__);
1612221167Sgnn			__hal_device_handle_error(hldev,
1613221167Sgnn			    NULL_VPID, VXGE_HAL_EVENT_SLOT_FREEZE);
1614221167Sgnn			*reason = 0;
1615221167Sgnn			ret = VXGE_HAL_ERR_SLOT_FREEZE;
1616221167Sgnn			goto exit;
1617221167Sgnn
1618221167Sgnn		}
1619221167Sgnn	}
1620221167Sgnn
1621221167Sgnn	*reason = val64;
1622221167Sgnn
1623221167Sgnn	vpath_mask = hldev->vpaths_deployed >>
1624221167Sgnn	    (64 - VXGE_HAL_MAX_VIRTUAL_PATHS);
1625221167Sgnn
1626221167Sgnn	if (val64 &
1627221167Sgnn	    VXGE_HAL_TITAN_GENERAL_INT_STATUS_VPATH_TRAFFIC_INT(vpath_mask)) {
1628221167Sgnn		hldev->header.traffic_intr_cnt++;
1629221167Sgnn		ret = VXGE_HAL_TRAFFIC_INTERRUPT;
1630221167Sgnn		vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = %d",
1631221167Sgnn		    __FILE__, __func__, __LINE__, ret);
1632221167Sgnn		return (ret);
1633221167Sgnn	}
1634221167Sgnn
1635221167Sgnn	hldev->header.not_traffic_intr_cnt++;
1636221167Sgnn
1637221167Sgnn	if (vxge_os_unlikely(val64 &
1638221167Sgnn	    VXGE_HAL_TITAN_GENERAL_INT_STATUS_VPATH_ALARM_INT)) {
1639221167Sgnn
1640221167Sgnn		for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1641221167Sgnn
1642221167Sgnn			if (!(hldev->vpaths_deployed & mBIT(i)))
1643221167Sgnn				continue;
1644221167Sgnn
1645221167Sgnn			status = __hal_vpath_alarm_process(
1646221167Sgnn			    &hldev->virtual_paths[i],
1647221167Sgnn			    skip_alarms);
1648221167Sgnn
1649221167Sgnn			if (status != VXGE_HAL_ERR_WRONG_IRQ)
1650221167Sgnn				ret = status;
1651221167Sgnn
1652221167Sgnn		}
1653221167Sgnn
1654221167Sgnn	}
1655221167Sgnnexit:
1656221167Sgnn	vxge_hal_trace_log_device_irq(
1657221167Sgnn	    "<==Error in  %s:%s:%d result = 0x%x general_int_status= 0x%llx",
1658221167Sgnn	    __FILE__, __func__, __LINE__, ret, val64);
1659221167Sgnn	return (ret);
1660221167Sgnn}
1661221167Sgnn
1662221167Sgnn/*
1663221167Sgnn * vxge_hal_device_continue_irq - Continue handling IRQ:	process	all
1664221167Sgnn *				completed descriptors.
1665221167Sgnn * @devh: HAL device handle.
1666221167Sgnn *
1667221167Sgnn * Process completed descriptors and unmask the	device interrupts.
1668221167Sgnn *
1669221167Sgnn * The vxge_hal_device_continue_irq() walks all open virtual paths
1670221167Sgnn * and calls upper-layer driver	(ULD) via supplied completion
1671221167Sgnn * callback.
1672221167Sgnn *
1673221167Sgnn * Note	that the vxge_hal_device_continue_irq is	part of	the _fast_ path.
1674221167Sgnn * To optimize the processing, the function does _not_ check for
1675221167Sgnn * errors and alarms.
1676221167Sgnn *
1677221167Sgnn * Returns: VXGE_HAL_OK.
1678221167Sgnn *
1679221167Sgnn * See also: vxge_hal_device_handle_irq()
1680221167Sgnn * vxge_hal_ring_rxd_next_completed(),
1681221167Sgnn * vxge_hal_fifo_txdl_next_completed(), vxge_hal_ring_callback_f {},
1682221167Sgnn * vxge_hal_fifo_callback_f {}.
1683221167Sgnn */
1684221167Sgnnvxge_hal_status_e
1685221167Sgnnvxge_hal_device_continue_irq(
1686221167Sgnn    vxge_hal_device_h devh)
1687221167Sgnn{
1688221167Sgnn	u32 i;
1689221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1690221167Sgnn
1691221167Sgnn	vxge_assert(hldev);
1692221167Sgnn
1693221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__,
1694221167Sgnn	    __func__, __LINE__);
1695221167Sgnn
1696221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
1697221167Sgnn	    (ptr_t) devh);
1698221167Sgnn
1699221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1700221167Sgnn
1701221167Sgnn		if (!(hldev->vpaths_deployed & mBIT(i)))
1702221167Sgnn			continue;
1703221167Sgnn
1704221167Sgnn		(void) vxge_hal_vpath_continue_irq(
1705221167Sgnn		    VXGE_HAL_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i]));
1706221167Sgnn
1707221167Sgnn	}
1708221167Sgnn
1709221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1710221167Sgnn	    __FILE__, __func__, __LINE__);
1711221167Sgnn	return (VXGE_HAL_OK);
1712221167Sgnn}
1713221167Sgnn
1714221167Sgnn/*
1715221167Sgnn * vxge_hal_device_handle_irq - Handle device IRQ.
1716221167Sgnn * @devh: HAL device handle.
1717221167Sgnn * @skip_alarms: Do not clear the alarms
1718221167Sgnn *
1719221167Sgnn * Perform the complete	handling of the	line interrupt.	The function
1720221167Sgnn * performs two	calls.
1721221167Sgnn * First it uses vxge_hal_device_begin_irq() to check the reason for
1722221167Sgnn * the interrupt and mask the device interrupts.
1723221167Sgnn * Second, it calls	vxge_hal_device_continue_irq() to process all
1724221167Sgnn * completed descriptors and re-enable the interrupts.
1725221167Sgnn *
1726221167Sgnn * Returns: VXGE_HAL_OK - success;
1727221167Sgnn * VXGE_HAL_ERR_WRONG_IRQ - (shared) IRQ produced by other device.
1728221167Sgnn *
1729221167Sgnn * See also: vxge_hal_device_begin_irq(), vxge_hal_device_continue_irq().
1730221167Sgnn */
1731221167Sgnnvxge_hal_status_e
1732221167Sgnnvxge_hal_device_handle_irq(
1733221167Sgnn    vxge_hal_device_h devh,
1734221167Sgnn    u32 skip_alarms)
1735221167Sgnn{
1736221167Sgnn	u64 reason;
1737221167Sgnn	vxge_hal_status_e status;
1738221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1739221167Sgnn
1740221167Sgnn	vxge_assert(devh != NULL);
1741221167Sgnn
1742221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1743221167Sgnn	    __FILE__, __func__, __LINE__);
1744221167Sgnn
1745221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT", \
1746221167Sgnn	    skip_alarms = %d",
1747221167Sgnn	    (ptr_t) devh, skip_alarms);
1748221167Sgnn
1749221167Sgnn	vxge_hal_device_mask_all(hldev);
1750221167Sgnn
1751221167Sgnn	status = vxge_hal_device_begin_irq(hldev, skip_alarms, &reason);
1752221167Sgnn	if (vxge_os_unlikely(status == VXGE_HAL_ERR_WRONG_IRQ)) {
1753221167Sgnn		vxge_hal_device_unmask_all(hldev);
1754221167Sgnn		goto exit;
1755221167Sgnn	}
1756221167Sgnn	if (status == VXGE_HAL_TRAFFIC_INTERRUPT) {
1757221167Sgnn
1758221167Sgnn		vxge_hal_device_clear_rx(hldev);
1759221167Sgnn
1760221167Sgnn		status = vxge_hal_device_continue_irq(hldev);
1761221167Sgnn
1762221167Sgnn		vxge_hal_device_clear_tx(hldev);
1763221167Sgnn
1764221167Sgnn	}
1765221167Sgnn
1766221167Sgnn	if (vxge_os_unlikely((status == VXGE_HAL_ERR_CRITICAL) && skip_alarms))
1767221167Sgnn		/* ULD needs to unmask explicitely */
1768221167Sgnn		goto exit;
1769221167Sgnn
1770221167Sgnn	vxge_hal_device_unmask_all(hldev);
1771221167Sgnn
1772221167Sgnnexit:
1773221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = %d",
1774221167Sgnn	    __FILE__, __func__, __LINE__, status);
1775221167Sgnn	return (status);
1776221167Sgnn}
1777221167Sgnn
1778221167Sgnn/*
1779221167Sgnn * __hal_device_handle_link_up_ind
1780221167Sgnn * @hldev: HAL device handle.
1781221167Sgnn *
1782221167Sgnn * Link up indication handler. The function is invoked by HAL when
1783221167Sgnn * X3100 indicates that the link is up for programmable amount of time.
1784221167Sgnn */
1785221167Sgnnvxge_hal_status_e
1786221167Sgnn__hal_device_handle_link_up_ind(__hal_device_t *hldev)
1787221167Sgnn{
1788221167Sgnn	vxge_assert(hldev);
1789221167Sgnn
1790221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1791221167Sgnn	    __FILE__, __func__, __LINE__);
1792221167Sgnn
1793221167Sgnn	vxge_hal_trace_log_device_irq("hldev = 0x"VXGE_OS_STXFMT,
1794221167Sgnn	    (ptr_t) hldev);
1795221167Sgnn
1796221167Sgnn	/*
1797221167Sgnn	 * If the previous link state is not down, return.
1798221167Sgnn	 */
1799221167Sgnn	if (hldev->header.link_state == VXGE_HAL_LINK_UP) {
1800221167Sgnn		vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1801221167Sgnn		    __FILE__, __func__, __LINE__);
1802221167Sgnn		return (VXGE_HAL_OK);
1803221167Sgnn	}
1804221167Sgnn
1805221167Sgnn	hldev->header.link_state = VXGE_HAL_LINK_UP;
1806221167Sgnn
1807221167Sgnn	/* notify ULD */
1808221167Sgnn	if (g_vxge_hal_driver->uld_callbacks.link_up) {
1809221167Sgnn		g_vxge_hal_driver->uld_callbacks.link_up(
1810221167Sgnn		    hldev,
1811221167Sgnn		    hldev->header.upper_layer_data);
1812221167Sgnn	}
1813221167Sgnn
1814221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1815221167Sgnn	    __FILE__, __func__, __LINE__);
1816221167Sgnn	return (VXGE_HAL_OK);
1817221167Sgnn}
1818221167Sgnn
1819221167Sgnn/*
1820221167Sgnn * __hal_device_handle_link_down_ind
1821221167Sgnn * @hldev: HAL device handle.
1822221167Sgnn *
1823221167Sgnn * Link down indication handler. The function is invoked by HAL when
1824221167Sgnn * X3100 indicates that the link is down.
1825221167Sgnn */
1826221167Sgnnvxge_hal_status_e
1827221167Sgnn__hal_device_handle_link_down_ind(__hal_device_t *hldev)
1828221167Sgnn{
1829221167Sgnn	vxge_assert(hldev);
1830221167Sgnn
1831221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
1832221167Sgnn	    __FILE__, __func__, __LINE__);
1833221167Sgnn
1834221167Sgnn	vxge_hal_trace_log_device_irq("hldev = 0x"VXGE_OS_STXFMT,
1835221167Sgnn	    (ptr_t) hldev);
1836221167Sgnn
1837221167Sgnn	/*
1838221167Sgnn	 * If the previous link state is not down, return.
1839221167Sgnn	 */
1840221167Sgnn	if (hldev->header.link_state == VXGE_HAL_LINK_DOWN) {
1841221167Sgnn		vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1842221167Sgnn		    __FILE__, __func__, __LINE__);
1843221167Sgnn		return (VXGE_HAL_OK);
1844221167Sgnn	}
1845221167Sgnn
1846221167Sgnn	hldev->header.link_state = VXGE_HAL_LINK_DOWN;
1847221167Sgnn
1848221167Sgnn	/* notify ULD */
1849221167Sgnn	if (g_vxge_hal_driver->uld_callbacks.link_down) {
1850221167Sgnn		g_vxge_hal_driver->uld_callbacks.link_down(
1851221167Sgnn		    hldev,
1852221167Sgnn		    hldev->header.upper_layer_data);
1853221167Sgnn	}
1854221167Sgnn
1855221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
1856221167Sgnn	    __FILE__, __func__, __LINE__);
1857221167Sgnn	return (VXGE_HAL_OK);
1858221167Sgnn}
1859221167Sgnn
1860221167Sgnn/*
1861221167Sgnn * vxge_hal_device_link_state_test - Test the link state.
1862221167Sgnn * @devh: HAL device handle.
1863221167Sgnn *
1864221167Sgnn * Test link state.
1865221167Sgnn * Returns: link state.
1866221167Sgnn */
1867221167Sgnnvxge_hal_device_link_state_e
1868221167Sgnnvxge_hal_device_link_state_test(
1869221167Sgnn    vxge_hal_device_h devh)
1870221167Sgnn{
1871221167Sgnn	u32 i;
1872221167Sgnn	vxge_hal_device_link_state_e status = VXGE_HAL_LINK_NONE;
1873221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1874221167Sgnn
1875221167Sgnn	vxge_assert(hldev);
1876221167Sgnn
1877221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
1878221167Sgnn	    __FILE__, __func__, __LINE__);
1879221167Sgnn
1880221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1881221167Sgnn	    (ptr_t) devh);
1882221167Sgnn
1883221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1884221167Sgnn
1885221167Sgnn		if (!(hldev->vpath_assignments & mBIT(i)))
1886221167Sgnn			continue;
1887221167Sgnn
1888221167Sgnn		status =
1889221167Sgnn		    __hal_vpath_link_state_test(&hldev->virtual_paths[i]);
1890221167Sgnn
1891221167Sgnn		break;
1892221167Sgnn
1893221167Sgnn	}
1894221167Sgnn
1895221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1896221167Sgnn	    __FILE__, __func__, __LINE__, status);
1897221167Sgnn	return (status);
1898221167Sgnn}
1899221167Sgnn
1900221167Sgnn/*
1901221167Sgnn * vxge_hal_device_link_state_poll - Poll for the link state.
1902221167Sgnn * @devh: HAL device handle.
1903221167Sgnn *
1904221167Sgnn * Get link state.
1905221167Sgnn * Returns: link state.
1906221167Sgnn */
1907221167Sgnnvxge_hal_device_link_state_e
1908221167Sgnnvxge_hal_device_link_state_poll(
1909221167Sgnn    vxge_hal_device_h devh)
1910221167Sgnn{
1911221167Sgnn	u32 i;
1912221167Sgnn	vxge_hal_device_link_state_e link_state = VXGE_HAL_LINK_NONE;
1913221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1914221167Sgnn
1915221167Sgnn	vxge_assert(devh);
1916221167Sgnn
1917221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
1918221167Sgnn	    __FILE__, __func__, __LINE__);
1919221167Sgnn
1920221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1921221167Sgnn	    (ptr_t) devh);
1922221167Sgnn
1923221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1924221167Sgnn
1925221167Sgnn		if (!(hldev->vpath_assignments & mBIT(i)))
1926221167Sgnn			continue;
1927221167Sgnn
1928221167Sgnn		hldev->header.link_state = VXGE_HAL_LINK_NONE;
1929221167Sgnn
1930221167Sgnn		link_state =
1931221167Sgnn		    __hal_vpath_link_state_poll(&hldev->virtual_paths[i]);
1932221167Sgnn
1933221167Sgnn		break;
1934221167Sgnn
1935221167Sgnn	}
1936221167Sgnn
1937221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1938221167Sgnn	    __FILE__, __func__, __LINE__, link_state);
1939221167Sgnn	return (link_state);
1940221167Sgnn}
1941221167Sgnn
1942221167Sgnn/*
1943221167Sgnn * vxge_hal_device_data_rate_poll - Poll for the data rate.
1944221167Sgnn * @devh: HAL device handle.
1945221167Sgnn *
1946221167Sgnn * Get data rate.
1947221167Sgnn * Returns: data rate.
1948221167Sgnn */
1949221167Sgnnvxge_hal_device_data_rate_e
1950221167Sgnnvxge_hal_device_data_rate_poll(
1951221167Sgnn    vxge_hal_device_h devh)
1952221167Sgnn{
1953221167Sgnn	u32 i;
1954221167Sgnn	vxge_hal_device_data_rate_e data_rate = VXGE_HAL_DATA_RATE_UNKNOWN;
1955221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1956221167Sgnn
1957221167Sgnn	vxge_assert(devh);
1958221167Sgnn
1959221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
1960221167Sgnn	    __FILE__, __func__, __LINE__);
1961221167Sgnn
1962221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
1963221167Sgnn	    (ptr_t) devh);
1964221167Sgnn
1965221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
1966221167Sgnn
1967221167Sgnn		if (!(hldev->vpaths_deployed & mBIT(i)))
1968221167Sgnn			continue;
1969221167Sgnn
1970221167Sgnn		data_rate =
1971221167Sgnn		    __hal_vpath_data_rate_poll(&hldev->virtual_paths[i]);
1972221167Sgnn
1973221167Sgnn		break;
1974221167Sgnn
1975221167Sgnn	}
1976221167Sgnn
1977221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
1978221167Sgnn	    __FILE__, __func__, __LINE__, data_rate);
1979221167Sgnn	return (data_rate);
1980221167Sgnn}
1981221167Sgnn
1982221167Sgnn/*
1983221167Sgnn * vxge_hal_device_lag_mode_get - Get Current LAG Mode
1984221167Sgnn * @devh: HAL device handle.
1985221167Sgnn *
1986221167Sgnn * Get Current LAG Mode
1987221167Sgnn */
1988221167Sgnnvxge_hal_device_lag_mode_e
1989221167Sgnnvxge_hal_device_lag_mode_get(
1990221167Sgnn    vxge_hal_device_h devh)
1991221167Sgnn{
1992221167Sgnn	u32 i;
1993221167Sgnn	vxge_hal_device_lag_mode_e lag_mode = VXGE_HAL_DEVICE_LAG_MODE_UNKNOWN;
1994221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
1995221167Sgnn
1996221167Sgnn	vxge_assert(devh);
1997221167Sgnn
1998221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
1999221167Sgnn	    __FILE__, __func__, __LINE__);
2000221167Sgnn
2001221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
2002221167Sgnn	    (ptr_t) devh);
2003221167Sgnn
2004221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
2005221167Sgnn
2006221167Sgnn		if (!(hldev->vpaths_deployed & mBIT(i)))
2007221167Sgnn			continue;
2008221167Sgnn
2009221167Sgnn		lag_mode =
2010221167Sgnn		    __hal_vpath_lag_mode_get(&hldev->virtual_paths[i]);
2011221167Sgnn
2012221167Sgnn		break;
2013221167Sgnn
2014221167Sgnn	}
2015221167Sgnn
2016221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2017221167Sgnn	    __FILE__, __func__, __LINE__, lag_mode);
2018221167Sgnn	return (lag_mode);
2019221167Sgnn}
2020221167Sgnn
2021221167Sgnn
2022221167Sgnn/*
2023221167Sgnn * __hal_device_handle_error - Handle error
2024221167Sgnn * @hldev: HAL device
2025221167Sgnn * @vp_id: Vpath Id
2026221167Sgnn * @type: Error type. Please see vxge_hal_event_e {}
2027221167Sgnn *
2028221167Sgnn * Handle error.
2029221167Sgnn */
2030221167Sgnnvoid
2031221167Sgnn__hal_device_handle_error(
2032221167Sgnn    __hal_device_t *hldev,
2033221167Sgnn    u32 vp_id,
2034221167Sgnn    vxge_hal_event_e type)
2035221167Sgnn{
2036221167Sgnn	vxge_assert(hldev);
2037221167Sgnn
2038221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2039221167Sgnn	    __FILE__, __func__, __LINE__);
2040221167Sgnn
2041221167Sgnn	vxge_hal_trace_log_device_irq(
2042221167Sgnn	    "hldev = 0x"VXGE_OS_STXFMT", vp_id = %d, type = %d",
2043221167Sgnn	    (ptr_t) hldev, vp_id, type);
2044221167Sgnn
2045221167Sgnn	switch (type) {
2046221167Sgnn	default:
2047221167Sgnn		vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = %d",
2048221167Sgnn		    __FILE__, __func__, __LINE__,
2049221167Sgnn		    VXGE_HAL_ERR_INVALID_TYPE);
2050221167Sgnn		return;
2051221167Sgnn	case VXGE_HAL_EVENT_UNKNOWN:
2052221167Sgnn		if (hldev->header.config.dump_on_unknown) {
2053221167Sgnn			(void) vxge_hal_aux_device_dump(hldev);
2054221167Sgnn		}
2055221167Sgnn		break;
2056221167Sgnn	case VXGE_HAL_EVENT_SERR:
2057221167Sgnn		if (hldev->header.config.dump_on_serr) {
2058221167Sgnn			(void) vxge_hal_aux_device_dump(hldev);
2059221167Sgnn		}
2060221167Sgnn		break;
2061221167Sgnn	case VXGE_HAL_EVENT_CRITICAL:
2062221167Sgnn	case VXGE_HAL_EVENT_SRPCIM_CRITICAL:
2063221167Sgnn	case VXGE_HAL_EVENT_MRPCIM_CRITICAL:
2064221167Sgnn		if (hldev->header.config.dump_on_critical) {
2065221167Sgnn			(void) vxge_hal_aux_device_dump(hldev);
2066221167Sgnn		}
2067221167Sgnn		break;
2068221167Sgnn	case VXGE_HAL_EVENT_ECCERR:
2069221167Sgnn		if (hldev->header.config.dump_on_eccerr) {
2070221167Sgnn			(void) vxge_hal_aux_device_dump(hldev);
2071221167Sgnn		}
2072221167Sgnn		break;
2073221167Sgnn	case VXGE_HAL_EVENT_KDFCCTL:
2074221167Sgnn		break;
2075221167Sgnn	case VXGE_HAL_EVENT_DEVICE_RESET_START:
2076221167Sgnn		break;
2077221167Sgnn	case VXGE_HAL_EVENT_DEVICE_RESET_COMPLETE:
2078221167Sgnn		break;
2079221167Sgnn	case VXGE_HAL_EVENT_VPATH_RESET_START:
2080221167Sgnn		break;
2081221167Sgnn	case VXGE_HAL_EVENT_VPATH_RESET_COMPLETE:
2082221167Sgnn		break;
2083221167Sgnn	case VXGE_HAL_EVENT_SLOT_FREEZE:
2084221167Sgnn		break;
2085221167Sgnn	}
2086221167Sgnn
2087221167Sgnn
2088221167Sgnn	/* notify ULD */
2089221167Sgnn	if (g_vxge_hal_driver->uld_callbacks.crit_err) {
2090221167Sgnn		g_vxge_hal_driver->uld_callbacks.crit_err(
2091221167Sgnn		    (vxge_hal_device_h) hldev,
2092221167Sgnn		    hldev->header.upper_layer_data,
2093221167Sgnn		    type,
2094221167Sgnn		    vp_id);
2095221167Sgnn	}
2096221167Sgnn
2097221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2098221167Sgnn	    __FILE__, __func__, __LINE__);
2099221167Sgnn}
2100221167Sgnn
2101221167Sgnn/*
2102221167Sgnn * vxge_hal_device_mask_tx - Mask Tx interrupts.
2103221167Sgnn * @devh: HAL device.
2104221167Sgnn *
2105221167Sgnn * Mask	Tx device interrupts.
2106221167Sgnn *
2107221167Sgnn * See also: vxge_hal_device_unmask_tx(), vxge_hal_device_mask_rx(),
2108221167Sgnn * vxge_hal_device_clear_tx().
2109221167Sgnn */
2110221167Sgnnvoid
2111221167Sgnnvxge_hal_device_mask_tx(
2112221167Sgnn    vxge_hal_device_h devh)
2113221167Sgnn{
2114221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
2115221167Sgnn
2116221167Sgnn	vxge_assert(devh);
2117221167Sgnn
2118221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2119221167Sgnn	    __FILE__, __func__, __LINE__);
2120221167Sgnn
2121221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2122221167Sgnn	    (ptr_t) devh);
2123221167Sgnn
2124221167Sgnn	if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) {
2125221167Sgnn		vxge_os_pio_mem_write64(hldev->header.pdev,
2126221167Sgnn		    hldev->header.regh0,
2127221167Sgnn		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX],
2128221167Sgnn		    &hldev->common_reg->tim_int_mask0);
2129221167Sgnn	}
2130221167Sgnn
2131221167Sgnn	if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) {
2132221167Sgnn		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2133221167Sgnn		    hldev->header.regh0,
2134221167Sgnn		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX],
2135221167Sgnn		    &hldev->common_reg->tim_int_mask1);
2136221167Sgnn	}
2137221167Sgnn
2138221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2139221167Sgnn	    __FILE__, __func__, __LINE__);
2140221167Sgnn}
2141221167Sgnn
2142221167Sgnn/*
2143221167Sgnn * vxge_hal_device_clear_tx - Acknowledge (that is, clear) the
2144221167Sgnn * condition that has caused the TX	interrupt.
2145221167Sgnn * @devh: HAL device.
2146221167Sgnn *
2147221167Sgnn * Acknowledge (that is, clear)	the	condition that has caused
2148221167Sgnn * the Tx interrupt.
2149221167Sgnn * See also: vxge_hal_device_begin_irq(), vxge_hal_device_continue_irq(),
2150221167Sgnn * vxge_hal_device_clear_rx(), vxge_hal_device_mask_tx().
2151221167Sgnn */
2152221167Sgnnvoid
2153221167Sgnnvxge_hal_device_clear_tx(
2154221167Sgnn    vxge_hal_device_h devh)
2155221167Sgnn{
2156221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
2157221167Sgnn
2158221167Sgnn	vxge_assert(devh);
2159221167Sgnn
2160221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2161221167Sgnn	    __FILE__, __func__, __LINE__);
2162221167Sgnn
2163221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2164221167Sgnn	    (ptr_t) devh);
2165221167Sgnn
2166221167Sgnn	if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) {
2167221167Sgnn		vxge_os_pio_mem_write64(hldev->header.pdev,
2168221167Sgnn		    hldev->header.regh0,
2169221167Sgnn		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX],
2170221167Sgnn		    &hldev->common_reg->tim_int_status0);
2171221167Sgnn	}
2172221167Sgnn
2173221167Sgnn	if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) {
2174221167Sgnn		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2175221167Sgnn		    hldev->header.regh0,
2176221167Sgnn		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX],
2177221167Sgnn		    &hldev->common_reg->tim_int_status1);
2178221167Sgnn	}
2179221167Sgnn
2180221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2181221167Sgnn	    __FILE__, __func__, __LINE__);
2182221167Sgnn}
2183221167Sgnn
2184221167Sgnn/*
2185221167Sgnn * vxge_hal_device_unmask_tx - Unmask Tx	interrupts.
2186221167Sgnn * @devh: HAL device.
2187221167Sgnn *
2188221167Sgnn * Unmask Tx device interrupts.
2189221167Sgnn *
2190221167Sgnn * See also: vxge_hal_device_mask_tx(), vxge_hal_device_clear_tx().
2191221167Sgnn */
2192221167Sgnnvoid
2193221167Sgnnvxge_hal_device_unmask_tx(
2194221167Sgnn    vxge_hal_device_h devh)
2195221167Sgnn{
2196221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
2197221167Sgnn
2198221167Sgnn	vxge_assert(devh);
2199221167Sgnn
2200221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2201221167Sgnn	    __FILE__, __func__, __LINE__);
2202221167Sgnn
2203221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2204221167Sgnn	    (ptr_t) devh);
2205221167Sgnn
2206221167Sgnn	if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) {
2207221167Sgnn		vxge_os_pio_mem_write64(hldev->header.pdev,
2208221167Sgnn		    hldev->header.regh0,
2209221167Sgnn		    ~(hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX]),
2210221167Sgnn		    &hldev->common_reg->tim_int_mask0);
2211221167Sgnn	}
2212221167Sgnn
2213221167Sgnn	if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) {
2214221167Sgnn		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2215221167Sgnn		    hldev->header.regh0,
2216221167Sgnn		    ~(hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX]),
2217221167Sgnn		    &hldev->common_reg->tim_int_mask1);
2218221167Sgnn	}
2219221167Sgnn
2220221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2221221167Sgnn	    __FILE__, __func__, __LINE__);
2222221167Sgnn}
2223221167Sgnn
2224221167Sgnn/*
2225221167Sgnn * vxge_hal_device_mask_rx - Mask Rx	interrupts.
2226221167Sgnn * @devh: HAL device.
2227221167Sgnn *
2228221167Sgnn * Mask	Rx device interrupts.
2229221167Sgnn *
2230221167Sgnn * See also: vxge_hal_device_unmask_rx(), vxge_hal_device_mask_tx(),
2231221167Sgnn * vxge_hal_device_clear_rx().
2232221167Sgnn */
2233221167Sgnnvoid
2234221167Sgnnvxge_hal_device_mask_rx(
2235221167Sgnn    vxge_hal_device_h devh)
2236221167Sgnn{
2237221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
2238221167Sgnn
2239221167Sgnn	vxge_assert(devh);
2240221167Sgnn
2241221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2242221167Sgnn	    __FILE__, __func__, __LINE__);
2243221167Sgnn
2244221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2245221167Sgnn	    (ptr_t) devh);
2246221167Sgnn
2247221167Sgnn	if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0) {
2248221167Sgnn		vxge_os_pio_mem_write64(hldev->header.pdev,
2249221167Sgnn		    hldev->header.regh0,
2250221167Sgnn		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX],
2251221167Sgnn		    &hldev->common_reg->tim_int_mask0);
2252221167Sgnn	}
2253221167Sgnn
2254221167Sgnn	if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0) {
2255221167Sgnn		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2256221167Sgnn		    hldev->header.regh0,
2257221167Sgnn		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX],
2258221167Sgnn		    &hldev->common_reg->tim_int_mask1);
2259221167Sgnn	}
2260221167Sgnn
2261221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2262221167Sgnn	    __FILE__, __func__, __LINE__);
2263221167Sgnn}
2264221167Sgnn
2265221167Sgnn/*
2266221167Sgnn * vxge_hal_device_clear_rx - Acknowledge (that is, clear) the
2267221167Sgnn * condition that has caused the RX	interrupt.
2268221167Sgnn * @devh: HAL device.
2269221167Sgnn *
2270221167Sgnn * Acknowledge (that is, clear)	the	condition that has caused
2271221167Sgnn * the Rx interrupt.
2272221167Sgnn * See also: vxge_hal_device_begin_irq(), vxge_hal_device_continue_irq(),
2273221167Sgnn * vxge_hal_device_clear_tx(), vxge_hal_device_mask_rx().
2274221167Sgnn */
2275221167Sgnnvoid
2276221167Sgnnvxge_hal_device_clear_rx(
2277221167Sgnn    vxge_hal_device_h devh)
2278221167Sgnn{
2279221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
2280221167Sgnn
2281221167Sgnn	vxge_assert(devh);
2282221167Sgnn
2283221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2284221167Sgnn	    __FILE__, __func__, __LINE__);
2285221167Sgnn
2286221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2287221167Sgnn	    (ptr_t) devh);
2288221167Sgnn
2289221167Sgnn	if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0) {
2290221167Sgnn		vxge_os_pio_mem_write64(hldev->header.pdev,
2291221167Sgnn		    hldev->header.regh0,
2292221167Sgnn		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX],
2293221167Sgnn		    &hldev->common_reg->tim_int_status0);
2294221167Sgnn	}
2295221167Sgnn
2296221167Sgnn	if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0) {
2297221167Sgnn		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2298221167Sgnn		    hldev->header.regh0,
2299221167Sgnn		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX],
2300221167Sgnn		    &hldev->common_reg->tim_int_status1);
2301221167Sgnn	}
2302221167Sgnn
2303221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2304221167Sgnn	    __FILE__, __func__, __LINE__);
2305221167Sgnn}
2306221167Sgnn
2307221167Sgnn/*
2308221167Sgnn * vxge_hal_device_unmask_rx - Unmask Rx	interrupts.
2309221167Sgnn * @devh: HAL device.
2310221167Sgnn *
2311221167Sgnn * Unmask Rx device interrupts.
2312221167Sgnn *
2313221167Sgnn * See also: vxge_hal_device_mask_rx(), vxge_hal_device_clear_rx().
2314221167Sgnn */
2315221167Sgnnvoid
2316221167Sgnnvxge_hal_device_unmask_rx(
2317221167Sgnn    vxge_hal_device_h devh)
2318221167Sgnn{
2319221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
2320221167Sgnn
2321221167Sgnn	vxge_assert(devh);
2322221167Sgnn
2323221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2324221167Sgnn	    __FILE__, __func__, __LINE__);
2325221167Sgnn
2326221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2327221167Sgnn	    (ptr_t) devh);
2328221167Sgnn
2329221167Sgnn	if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0) {
2330221167Sgnn		vxge_os_pio_mem_write64(hldev->header.pdev,
2331221167Sgnn		    hldev->header.regh0,
2332221167Sgnn		    ~(hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX]),
2333221167Sgnn		    &hldev->common_reg->tim_int_mask0);
2334221167Sgnn	}
2335221167Sgnn
2336221167Sgnn	if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0) {
2337221167Sgnn		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2338221167Sgnn		    hldev->header.regh0,
2339221167Sgnn		    ~(hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX]),
2340221167Sgnn		    &hldev->common_reg->tim_int_mask1);
2341221167Sgnn	}
2342221167Sgnn
2343221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2344221167Sgnn	    __FILE__, __func__, __LINE__);
2345221167Sgnn}
2346221167Sgnn
2347221167Sgnn/*
2348221167Sgnn * vxge_hal_device_mask_tx_rx - Mask Tx and Rx interrupts.
2349221167Sgnn * @devh: HAL device.
2350221167Sgnn *
2351221167Sgnn * Mask Tx and Rx device interrupts.
2352221167Sgnn *
2353221167Sgnn * See also: vxge_hal_device_unmask_tx_rx(), vxge_hal_device_clear_tx_rx().
2354221167Sgnn */
2355221167Sgnnvoid
2356221167Sgnnvxge_hal_device_mask_tx_rx(
2357221167Sgnn    vxge_hal_device_h devh)
2358221167Sgnn{
2359221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
2360221167Sgnn
2361221167Sgnn	vxge_assert(devh);
2362221167Sgnn
2363221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2364221167Sgnn	    __FILE__, __func__, __LINE__);
2365221167Sgnn
2366221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2367221167Sgnn	    (ptr_t) devh);
2368221167Sgnn
2369221167Sgnn	if ((hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) ||
2370221167Sgnn	    (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0)) {
2371221167Sgnn		vxge_os_pio_mem_write64(hldev->header.pdev,
2372221167Sgnn		    hldev->header.regh0,
2373221167Sgnn		    (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] |
2374221167Sgnn		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX]),
2375221167Sgnn		    &hldev->common_reg->tim_int_mask0);
2376221167Sgnn	}
2377221167Sgnn
2378221167Sgnn	if ((hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) ||
2379221167Sgnn	    (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0)) {
2380221167Sgnn		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2381221167Sgnn		    hldev->header.regh0,
2382221167Sgnn		    (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] |
2383221167Sgnn		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX]),
2384221167Sgnn		    &hldev->common_reg->tim_int_mask1);
2385221167Sgnn	}
2386221167Sgnn
2387221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2388221167Sgnn	    __FILE__, __func__, __LINE__);
2389221167Sgnn}
2390221167Sgnn
2391221167Sgnn/*
2392221167Sgnn * vxge_hal_device_clear_tx_rx - Acknowledge (that is, clear) the
2393221167Sgnn * condition that has caused the Tx and RX interrupt.
2394221167Sgnn * @devh: HAL device.
2395221167Sgnn *
2396221167Sgnn * Acknowledge (that is, clear)	the	condition that has caused
2397221167Sgnn * the Tx and Rx interrupt.
2398221167Sgnn * See also: vxge_hal_device_begin_irq(), vxge_hal_device_continue_irq(),
2399221167Sgnn * vxge_hal_device_mask_tx_rx(), vxge_hal_device_unmask_tx_rx().
2400221167Sgnn */
2401221167Sgnnvoid
2402221167Sgnnvxge_hal_device_clear_tx_rx(
2403221167Sgnn    vxge_hal_device_h devh)
2404221167Sgnn{
2405221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
2406221167Sgnn
2407221167Sgnn	vxge_assert(devh);
2408221167Sgnn
2409221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2410221167Sgnn	    __FILE__, __func__, __LINE__);
2411221167Sgnn
2412221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2413221167Sgnn	    (ptr_t) devh);
2414221167Sgnn
2415221167Sgnn	if ((hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) ||
2416221167Sgnn	    (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0)) {
2417221167Sgnn		vxge_os_pio_mem_write64(hldev->header.pdev,
2418221167Sgnn		    hldev->header.regh0,
2419221167Sgnn		    (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] |
2420221167Sgnn		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX]),
2421221167Sgnn		    &hldev->common_reg->tim_int_status0);
2422221167Sgnn	}
2423221167Sgnn
2424221167Sgnn	if ((hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) ||
2425221167Sgnn	    (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0)) {
2426221167Sgnn		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2427221167Sgnn		    hldev->header.regh0,
2428221167Sgnn		    (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] |
2429221167Sgnn		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX]),
2430221167Sgnn		    &hldev->common_reg->tim_int_status1);
2431221167Sgnn	}
2432221167Sgnn
2433221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2434221167Sgnn	    __FILE__, __func__, __LINE__);
2435221167Sgnn}
2436221167Sgnn
2437221167Sgnn/*
2438221167Sgnn * vxge_hal_device_unmask_tx_rx - Unmask Tx and Rx interrupts.
2439221167Sgnn * @devh: HAL device.
2440221167Sgnn *
2441221167Sgnn * Unmask Rx device interrupts.
2442221167Sgnn *
2443221167Sgnn * See also: vxge_hal_device_mask_tx_rx(), vxge_hal_device_clear_tx_rx().
2444221167Sgnn */
2445221167Sgnnvoid
2446221167Sgnnvxge_hal_device_unmask_tx_rx(
2447221167Sgnn    vxge_hal_device_h devh)
2448221167Sgnn{
2449221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
2450221167Sgnn
2451221167Sgnn	vxge_assert(devh);
2452221167Sgnn
2453221167Sgnn	vxge_hal_trace_log_device_irq("==> %s:%s:%d",
2454221167Sgnn	    __FILE__, __func__, __LINE__);
2455221167Sgnn
2456221167Sgnn	vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT,
2457221167Sgnn	    (ptr_t) devh);
2458221167Sgnn
2459221167Sgnn	if ((hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) ||
2460221167Sgnn	    (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0)) {
2461221167Sgnn		vxge_os_pio_mem_write64(hldev->header.pdev,
2462221167Sgnn		    hldev->header.regh0,
2463221167Sgnn		    ~(hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] |
2464221167Sgnn		    hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX]),
2465221167Sgnn		    &hldev->common_reg->tim_int_mask0);
2466221167Sgnn	}
2467221167Sgnn
2468221167Sgnn	if ((hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) ||
2469221167Sgnn	    (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0)) {
2470221167Sgnn		vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
2471221167Sgnn		    hldev->header.regh0,
2472221167Sgnn		    ~(hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] |
2473221167Sgnn		    hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX]),
2474221167Sgnn		    &hldev->common_reg->tim_int_mask1);
2475221167Sgnn	}
2476221167Sgnn
2477221167Sgnn	vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0",
2478221167Sgnn	    __FILE__, __func__, __LINE__);
2479221167Sgnn}
2480221167Sgnn
2481221167Sgnn/*
2482221167Sgnn * vxge_hal_device_hw_info_get - Get the hw information
2483221167Sgnn * @pdev: PCI device object.
2484221167Sgnn * @regh0: BAR0 mapped memory handle (Solaris), or simply PCI device @pdev
2485221167Sgnn *	(Linux and the rest.)
2486221167Sgnn * @bar0: Address of BAR0 in PCI config
2487221167Sgnn * @hw_info: Buffer to return vxge_hal_device_hw_info_t {} structure
2488221167Sgnn *
2489221167Sgnn * Returns the vpath mask that has the bits set for each vpath allocated
2490221167Sgnn * for the driver, FW version information and the first mac addresse for
2491221167Sgnn * each vpath
2492221167Sgnn */
2493221167Sgnnvxge_hal_status_e
2494221167Sgnnvxge_hal_device_hw_info_get(
2495221167Sgnn    pci_dev_h pdev,
2496221167Sgnn    pci_reg_h regh0,
2497221167Sgnn    u8 *bar0,
2498221167Sgnn    vxge_hal_device_hw_info_t *hw_info)
2499221167Sgnn{
2500221167Sgnn	u32 i;
2501221167Sgnn	u64 val64;
2502221167Sgnn	vxge_hal_legacy_reg_t *legacy_reg;
2503221167Sgnn	vxge_hal_toc_reg_t *toc_reg;
2504221167Sgnn	vxge_hal_mrpcim_reg_t *mrpcim_reg;
2505221167Sgnn	vxge_hal_common_reg_t *common_reg;
2506221167Sgnn	vxge_hal_vpath_reg_t *vpath_reg;
2507221167Sgnn	vxge_hal_vpmgmt_reg_t *vpmgmt_reg;
2508221167Sgnn	vxge_hal_status_e status;
2509221167Sgnn
2510221167Sgnn	vxge_hal_trace_log_driver("==> %s:%s:%d",
2511221167Sgnn	    __FILE__, __func__, __LINE__);
2512221167Sgnn
2513221167Sgnn	vxge_hal_trace_log_driver(
2514221167Sgnn	    "pdev = 0x"VXGE_OS_STXFMT", regh0 = 0x"VXGE_OS_STXFMT", "
2515221167Sgnn	    "bar0 = 0x"VXGE_OS_STXFMT", hw_info = 0x"VXGE_OS_STXFMT,
2516221167Sgnn	    (ptr_t) pdev, (ptr_t) regh0, (ptr_t) bar0, (ptr_t) hw_info);
2517221167Sgnn
2518221167Sgnn	vxge_assert((bar0 != NULL) && (hw_info != NULL));
2519221167Sgnn
2520221167Sgnn	vxge_os_memzero(hw_info, sizeof(vxge_hal_device_hw_info_t));
2521221167Sgnn
2522221167Sgnn	legacy_reg = (vxge_hal_legacy_reg_t *)
2523221167Sgnn	    vxge_hal_device_get_legacy_reg(pdev, regh0, bar0);
2524221167Sgnn
2525221167Sgnn	status = __hal_legacy_swapper_set(pdev, regh0, legacy_reg);
2526221167Sgnn
2527221167Sgnn	if (status != VXGE_HAL_OK) {
2528221167Sgnn		vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
2529221167Sgnn		    __FILE__, __func__, __LINE__, status);
2530221167Sgnn		return (status);
2531221167Sgnn	}
2532221167Sgnn
2533221167Sgnn	val64 = vxge_os_pio_mem_read64(pdev, regh0,
2534221167Sgnn	    &legacy_reg->toc_first_pointer);
2535221167Sgnn
2536221167Sgnn	toc_reg = (vxge_hal_toc_reg_t *) ((void *) (bar0 + val64));
2537221167Sgnn
2538221167Sgnn	val64 =
2539221167Sgnn	    vxge_os_pio_mem_read64(pdev, regh0, &toc_reg->toc_common_pointer);
2540221167Sgnn
2541221167Sgnn	common_reg = (vxge_hal_common_reg_t *) ((void *) (bar0 + val64));
2542221167Sgnn
2543221167Sgnn	status = vxge_hal_device_register_poll(pdev, regh0,
2544221167Sgnn	    &common_reg->vpath_rst_in_prog, 0,
2545221167Sgnn	    VXGE_HAL_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(0x1ffff),
2546221167Sgnn	    VXGE_HAL_DEF_DEVICE_POLL_MILLIS);
2547221167Sgnn
2548221167Sgnn	if (status != VXGE_HAL_OK) {
2549221167Sgnn
2550221167Sgnn		vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
2551221167Sgnn		    __FILE__, __func__, __LINE__, status);
2552221167Sgnn		return (status);
2553221167Sgnn	}
2554221167Sgnn
2555221167Sgnn	hw_info->vpath_mask = vxge_os_pio_mem_read64(pdev, regh0,
2556221167Sgnn	    &common_reg->vpath_assignments);
2557221167Sgnn
2558221167Sgnn	val64 = vxge_os_pio_mem_read64(pdev, regh0,
2559221167Sgnn	    &common_reg->host_type_assignments);
2560221167Sgnn
2561221167Sgnn	hw_info->host_type = (u32)
2562221167Sgnn	    VXGE_HAL_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
2563221167Sgnn
2564221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
2565221167Sgnn
2566221167Sgnn		if (!((hw_info->vpath_mask) & mBIT(i)))
2567221167Sgnn			continue;
2568221167Sgnn
2569221167Sgnn		val64 = vxge_os_pio_mem_read64(pdev, regh0,
2570221167Sgnn		    &toc_reg->toc_vpmgmt_pointer[i]);
2571221167Sgnn
2572221167Sgnn		vpmgmt_reg = (vxge_hal_vpmgmt_reg_t *)
2573221167Sgnn		    ((void *) (bar0 + val64));
2574221167Sgnn
2575221167Sgnn		val64 = vxge_os_pio_mem_read64(pdev, regh0,
2576221167Sgnn		    &vpmgmt_reg->vpath_to_func_map_cfg1);
2577221167Sgnn		hw_info->func_id = (u32)
2578221167Sgnn		    VXGE_HAL_VPATH_TO_FUNC_MAP_CFG1_GET_CFG1(
2579221167Sgnn		    val64);
2580221167Sgnn
2581221167Sgnn		if (__hal_device_access_rights_get(hw_info->host_type,
2582221167Sgnn		    hw_info->func_id) & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM) {
2583221167Sgnn
2584221167Sgnn			val64 = vxge_os_pio_mem_read64(pdev, regh0,
2585221167Sgnn			    &toc_reg->toc_mrpcim_pointer);
2586221167Sgnn
2587221167Sgnn			mrpcim_reg = (vxge_hal_mrpcim_reg_t *)
2588221167Sgnn			    ((void *) (bar0 + val64));
2589221167Sgnn
2590221167Sgnn			vxge_os_pio_mem_write64(pdev, regh0,
2591221167Sgnn			    0,
2592221167Sgnn			    &mrpcim_reg->xgmac_gen_fw_memo_mask);
2593221167Sgnn			vxge_os_wmb();
2594221167Sgnn		}
2595221167Sgnn
2596221167Sgnn		val64 = vxge_os_pio_mem_read64(pdev, regh0,
2597221167Sgnn		    &toc_reg->toc_vpath_pointer[i]);
2598221167Sgnn
2599221167Sgnn		vpath_reg = (vxge_hal_vpath_reg_t *) ((void *) (bar0 + val64));
2600221167Sgnn
2601221167Sgnn		(void) __hal_vpath_fw_flash_ver_get(pdev, regh0, i, vpath_reg,
2602221167Sgnn		    &hw_info->fw_version,
2603221167Sgnn		    &hw_info->fw_date,
2604221167Sgnn		    &hw_info->flash_version,
2605221167Sgnn		    &hw_info->flash_date);
2606221167Sgnn
2607221167Sgnn		(void) __hal_vpath_card_info_get(pdev, regh0, i, vpath_reg,
2608221167Sgnn		    hw_info->serial_number,
2609221167Sgnn		    hw_info->part_number,
2610221167Sgnn		    hw_info->product_description);
2611221167Sgnn
2612221167Sgnn		(void) __hal_vpath_pmd_info_get(pdev, regh0, i, vpath_reg,
2613221167Sgnn		    &hw_info->ports,
2614221167Sgnn		    &hw_info->pmd_port0,
2615221167Sgnn		    &hw_info->pmd_port1);
2616221167Sgnn
2617221167Sgnn		hw_info->function_mode =
2618221167Sgnn		    __hal_vpath_pci_func_mode_get(pdev, regh0, i, vpath_reg);
2619221167Sgnn
2620221167Sgnn		break;
2621221167Sgnn	}
2622221167Sgnn
2623221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
2624221167Sgnn
2625221167Sgnn		if (!((hw_info->vpath_mask) & mBIT(i)))
2626221167Sgnn			continue;
2627221167Sgnn
2628221167Sgnn		val64 = vxge_os_pio_mem_read64(pdev, regh0,
2629221167Sgnn		    &toc_reg->toc_vpath_pointer[i]);
2630221167Sgnn
2631221167Sgnn		vpath_reg = (vxge_hal_vpath_reg_t *) ((void *) (bar0 + val64));
2632221167Sgnn
2633221167Sgnn		status = __hal_vpath_hw_addr_get(pdev, regh0, i, vpath_reg,
2634221167Sgnn		    hw_info->mac_addrs[i], hw_info->mac_addr_masks[i]);
2635221167Sgnn
2636221167Sgnn		if (status != VXGE_HAL_OK) {
2637221167Sgnn
2638221167Sgnn			vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
2639221167Sgnn			    __FILE__, __func__, __LINE__, status);
2640221167Sgnn			return (status);
2641221167Sgnn
2642221167Sgnn		}
2643221167Sgnn
2644221167Sgnn	}
2645221167Sgnn
2646221167Sgnn	vxge_hal_trace_log_driver("<== %s:%s:%d Result = 0",
2647221167Sgnn	    __FILE__, __func__, __LINE__);
2648221167Sgnn
2649221167Sgnn	return (VXGE_HAL_OK);
2650221167Sgnn}
2651221167Sgnn
2652221167Sgnn/*
2653221167Sgnn * vxge_hal_device_initialize - Initialize X3100 device.
2654221167Sgnn * @hldev: HAL device handle.
2655221167Sgnn * @attr: pointer to vxge_hal_device_attr_t structure
2656221167Sgnn * @device_config: Configuration to be _applied_ to the device,
2657221167Sgnn *		For the X3100 configuration "knobs" please
2658221167Sgnn *		refer to vxge_hal_device_config_t and X3100
2659221167Sgnn *		User Guide.
2660221167Sgnn *
2661221167Sgnn * Initialize X3100 device. Note that all the arguments of this public API
2662221167Sgnn * are 'IN', including @hldev. Upper-layer driver (ULD) cooperates with
2663221167Sgnn * OS to find new X3100 device, locate its PCI and memory spaces.
2664221167Sgnn *
2665221167Sgnn * When done, the ULD allocates sizeof(__hal_device_t) bytes for HAL
2666221167Sgnn * to enable the latter to perform X3100 hardware initialization.
2667221167Sgnn *
2668221167Sgnn * Returns: VXGE_HAL_OK - success.
2669221167Sgnn * VXGE_HAL_ERR_DRIVER_NOT_INITIALIZED - Driver is not initialized.
2670221167Sgnn * VXGE_HAL_ERR_BAD_DEVICE_CONFIG - Device configuration params are not
2671221167Sgnn * valid.
2672221167Sgnn * VXGE_HAL_ERR_OUT_OF_MEMORY - Memory allocation failed.
2673221167Sgnn * VXGE_HAL_ERR_BAD_SUBSYSTEM_ID - Device subsystem id is invalid.
2674221167Sgnn * VXGE_HAL_ERR_INVALID_MAC_ADDRESS - Device mac address in not valid.
2675221167Sgnn * VXGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to retrieve the mac
2676221167Sgnn * address within the time(timeout) or TTI/RTI initialization failed.
2677221167Sgnn * VXGE_HAL_ERR_SWAPPER_CTRL - Failed to configure swapper control.
2678221167Sgnn *
2679221167Sgnn * See also: __hal_device_terminate(), vxge_hal_status_e {}
2680221167Sgnn * vxge_hal_device_attr_t {}.
2681221167Sgnn */
2682221167Sgnnvxge_hal_status_e
2683221167Sgnnvxge_hal_device_initialize(
2684221167Sgnn    vxge_hal_device_h *devh,
2685221167Sgnn    vxge_hal_device_attr_t *attr,
2686221167Sgnn    vxge_hal_device_config_t *device_config)
2687221167Sgnn{
2688221167Sgnn	u32 i;
2689221167Sgnn	u32 nblocks = 0;
2690221167Sgnn	__hal_device_t *hldev;
2691221167Sgnn	vxge_hal_status_e status;
2692221167Sgnn
2693221167Sgnn	vxge_assert((devh != NULL) &&
2694221167Sgnn	    (attr != NULL) && (device_config != NULL));
2695221167Sgnn
2696221167Sgnn	vxge_hal_trace_log_driver("==> %s:%s:%d",
2697221167Sgnn	    __FILE__, __func__, __LINE__);
2698221167Sgnn
2699221167Sgnn	vxge_hal_trace_log_driver(
2700221167Sgnn	    "devh = 0x"VXGE_OS_STXFMT", attr = 0x"VXGE_OS_STXFMT", "
2701221167Sgnn	    "device_config = 0x"VXGE_OS_STXFMT, (ptr_t) devh, (ptr_t) attr,
2702221167Sgnn	    (ptr_t) device_config);
2703221167Sgnn
2704221167Sgnn	/* sanity check */
2705221167Sgnn	if (g_vxge_hal_driver == NULL ||
2706221167Sgnn	    !g_vxge_hal_driver->is_initialized) {
2707221167Sgnn		vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
2708221167Sgnn		    __FILE__, __func__, __LINE__,
2709221167Sgnn		    VXGE_HAL_ERR_DRIVER_NOT_INITIALIZED);
2710221167Sgnn		return (VXGE_HAL_ERR_DRIVER_NOT_INITIALIZED);
2711221167Sgnn	}
2712221167Sgnn
2713221167Sgnn	status = __hal_device_config_check(device_config);
2714221167Sgnn
2715221167Sgnn	if (status != VXGE_HAL_OK) {
2716221167Sgnn		vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
2717221167Sgnn		    __FILE__, __func__, __LINE__, status);
2718221167Sgnn		return (status);
2719221167Sgnn	}
2720221167Sgnn
2721221167Sgnn	hldev = (__hal_device_t *) vxge_os_malloc(attr->pdev,
2722221167Sgnn	    sizeof(__hal_device_t));
2723221167Sgnn
2724221167Sgnn	if (hldev == NULL) {
2725221167Sgnn		vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d",
2726221167Sgnn		    __FILE__, __func__, __LINE__,
2727221167Sgnn		    VXGE_HAL_ERR_OUT_OF_MEMORY);
2728221167Sgnn		return (VXGE_HAL_ERR_OUT_OF_MEMORY);
2729221167Sgnn	}
2730221167Sgnn
2731221167Sgnn	vxge_os_memzero(hldev, sizeof(__hal_device_t));
2732221167Sgnn
2733221167Sgnn	hldev->header.magic = VXGE_HAL_DEVICE_MAGIC;
2734221167Sgnn
2735221167Sgnn	__hal_channel_init_pending_list(hldev);
2736221167Sgnn
2737221167Sgnn	vxge_hal_device_debug_set(hldev,
2738221167Sgnn	    device_config->debug_level,
2739221167Sgnn	    device_config->debug_mask);
2740221167Sgnn
2741221167Sgnn#if defined(VXGE_TRACE_INTO_CIRCULAR_ARR)
2742221167Sgnn	hldev->trace_buf.size = device_config->tracebuf_size;
2743221167Sgnn	hldev->trace_buf.data =
2744221167Sgnn	    (u8 *) vxge_os_malloc(attr->pdev, hldev->trace_buf.size);
2745221167Sgnn	if (hldev->trace_buf.data == NULL) {
2746221167Sgnn		vxge_os_printf("cannot allocate trace buffer!\n");
2747221167Sgnn		return (VXGE_HAL_ERR_OUT_OF_MEMORY);
2748221167Sgnn	}
2749221167Sgnn	hldev->trace_buf.offset = 0;
2750221167Sgnn	hldev->trace_buf.wrapped_count = 0;
2751221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
2752221167Sgnn	    __FILE__, __func__, __LINE__);
2753221167Sgnn#endif
2754221167Sgnn
2755221167Sgnn	vxge_hal_info_log_device("device 0x"VXGE_OS_STXFMT" is initializing",
2756221167Sgnn	    (ptr_t) hldev);
2757221167Sgnn
2758221167Sgnn	/* apply config */
2759221167Sgnn	vxge_os_memcpy(&hldev->header.config, device_config,
2760221167Sgnn	    sizeof(vxge_hal_device_config_t));
2761221167Sgnn
2762221167Sgnn	hldev->header.regh0 = attr->regh0;
2763221167Sgnn	hldev->header.regh1 = attr->regh1;
2764221167Sgnn	hldev->header.regh2 = attr->regh2;
2765221167Sgnn	hldev->header.bar0 = attr->bar0;
2766221167Sgnn	hldev->header.bar1 = attr->bar1;
2767221167Sgnn	hldev->header.bar2 = attr->bar2;
2768221167Sgnn	hldev->header.pdev = attr->pdev;
2769221167Sgnn	hldev->header.irqh = attr->irqh;
2770221167Sgnn	hldev->header.cfgh = attr->cfgh;
2771221167Sgnn
2772221167Sgnn	if ((status = __hal_device_reg_addr_get(hldev)) != VXGE_HAL_OK) {
2773221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2774221167Sgnn		    __FILE__, __func__, __LINE__, status);
2775221167Sgnn		vxge_hal_device_terminate(hldev);
2776221167Sgnn		return (status);
2777221167Sgnn	}
2778221167Sgnn
2779221167Sgnn	__hal_device_id_get(hldev);
2780221167Sgnn
2781221167Sgnn	__hal_device_host_info_get(hldev);
2782221167Sgnn
2783221167Sgnn
2784221167Sgnn	nblocks += 1;		/* For MRPCIM stats */
2785221167Sgnn
2786221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
2787221167Sgnn
2788221167Sgnn		if (!(hldev->vpath_assignments & mBIT(i)))
2789221167Sgnn			continue;
2790221167Sgnn
2791221167Sgnn		if (device_config->vp_config[i].ring.enable ==
2792221167Sgnn		    VXGE_HAL_RING_ENABLE) {
2793221167Sgnn			nblocks +=
2794221167Sgnn			    (device_config->vp_config[i].ring.ring_length +
2795221167Sgnn			    vxge_hal_ring_rxds_per_block_get(
2796221167Sgnn			    device_config->vp_config[i].ring.buffer_mode) - 1) /
2797221167Sgnn			    vxge_hal_ring_rxds_per_block_get(
2798221167Sgnn			    device_config->vp_config[i].ring.buffer_mode);
2799221167Sgnn		}
2800221167Sgnn
2801221167Sgnn		if ((device_config->vp_config[i].fifo.enable ==
2802221167Sgnn		    VXGE_HAL_FIFO_ENABLE) &&
2803221167Sgnn		    ((device_config->vp_config[i].fifo.max_frags *
2804221167Sgnn		    sizeof(vxge_hal_fifo_txd_t)) <=
2805221167Sgnn		    VXGE_OS_HOST_PAGE_SIZE)) {
2806221167Sgnn			nblocks +=
2807221167Sgnn			    ((device_config->vp_config[i].fifo.fifo_length *
2808221167Sgnn			    sizeof(vxge_hal_fifo_txd_t) *
2809221167Sgnn			    device_config->vp_config[i].fifo.max_frags) +
2810221167Sgnn			    VXGE_OS_HOST_PAGE_SIZE - 1) /
2811221167Sgnn			    VXGE_OS_HOST_PAGE_SIZE;
2812221167Sgnn		}
2813221167Sgnn
2814221167Sgnn
2815221167Sgnn		nblocks += 1;	/* For vpath stats */
2816221167Sgnn
2817221167Sgnn	}
2818221167Sgnn
2819221167Sgnn	if (__hal_blockpool_create(hldev,
2820221167Sgnn	    &hldev->block_pool,
2821221167Sgnn	    device_config->dma_blockpool_initial + nblocks,
2822221167Sgnn	    device_config->dma_blockpool_incr,
2823221167Sgnn	    device_config->dma_blockpool_min,
2824221167Sgnn	    device_config->dma_blockpool_max + nblocks) != VXGE_HAL_OK) {
2825221167Sgnn		vxge_hal_info_log_device("%s:__hal_blockpool_create failed",
2826221167Sgnn		    __func__);
2827221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2828221167Sgnn		    __FILE__, __func__, __LINE__,
2829221167Sgnn		    VXGE_HAL_ERR_OUT_OF_MEMORY);
2830221167Sgnn		vxge_hal_device_terminate(hldev);
2831221167Sgnn		return (VXGE_HAL_ERR_OUT_OF_MEMORY);
2832221167Sgnn	}
2833221167Sgnn
2834221167Sgnn
2835221167Sgnn	status = __hal_device_hw_initialize(hldev);
2836221167Sgnn
2837221167Sgnn	if (status != VXGE_HAL_OK) {
2838221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2839221167Sgnn		    __FILE__, __func__, __LINE__, status);
2840221167Sgnn		vxge_hal_device_terminate(hldev);
2841221167Sgnn		return (status);
2842221167Sgnn	}
2843221167Sgnn
2844221167Sgnn	hldev->dump_buf = (char *) vxge_os_malloc(hldev->header.pdev,
2845221167Sgnn	    VXGE_HAL_DUMP_BUF_SIZE);
2846221167Sgnn	if (hldev->dump_buf == NULL) {
2847221167Sgnn		vxge_hal_info_log_device("%s:vxge_os_malloc failed ",
2848221167Sgnn		    __func__);
2849221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2850221167Sgnn		    __FILE__, __func__, __LINE__,
2851221167Sgnn		    VXGE_HAL_ERR_OUT_OF_MEMORY);
2852221167Sgnn		vxge_hal_device_terminate(hldev);
2853221167Sgnn		return (VXGE_HAL_ERR_OUT_OF_MEMORY);
2854221167Sgnn	}
2855221167Sgnn
2856221167Sgnn	hldev->header.is_initialized = 1;
2857221167Sgnn
2858221167Sgnn	*devh = hldev;
2859221167Sgnn
2860221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = 0",
2861221167Sgnn	    __FILE__, __func__, __LINE__);
2862221167Sgnn	return (VXGE_HAL_OK);
2863221167Sgnn}
2864221167Sgnn
2865221167Sgnn/*
2866221167Sgnn * vxge_hal_device_terminate - Terminate X3100 device.
2867221167Sgnn * @devh: HAL device handle.
2868221167Sgnn *
2869221167Sgnn * Terminate HAL device.
2870221167Sgnn *
2871221167Sgnn * See also: vxge_hal_device_initialize().
2872221167Sgnn */
2873221167Sgnnvoid
2874221167Sgnnvxge_hal_device_terminate(vxge_hal_device_h devh)
2875221167Sgnn{
2876221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
2877221167Sgnn
2878221167Sgnn	vxge_assert(g_vxge_hal_driver != NULL);
2879221167Sgnn	vxge_assert(hldev != NULL);
2880221167Sgnn	vxge_assert(hldev->header.magic == VXGE_HAL_DEVICE_MAGIC);
2881221167Sgnn
2882221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
2883221167Sgnn	    __FILE__, __func__, __LINE__);
2884221167Sgnn
2885221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
2886221167Sgnn	    (ptr_t) devh);
2887221167Sgnn
2888221167Sgnn	hldev->header.terminating = 1;
2889221167Sgnn	hldev->header.is_initialized = 0;
2890221167Sgnn	hldev->in_poll = 0;
2891221167Sgnn	hldev->header.magic = VXGE_HAL_DEVICE_DEAD;
2892221167Sgnn
2893221167Sgnn	if (hldev->dump_buf) {
2894221167Sgnn		vxge_os_free(hldev->header.pdev, hldev->dump_buf,
2895221167Sgnn		    VXGE_HAL_DUMP_BUF_SIZE);
2896221167Sgnn		hldev->dump_buf = NULL;
2897221167Sgnn	}
2898221167Sgnn
2899221167Sgnn	if (hldev->srpcim != NULL)
2900221167Sgnn		(void) __hal_srpcim_terminate(hldev);
2901221167Sgnn
2902221167Sgnn	if (hldev->mrpcim != NULL)
2903221167Sgnn		(void) __hal_mrpcim_terminate(hldev);
2904221167Sgnn
2905221167Sgnn	__hal_channel_destroy_pending_list(hldev);
2906221167Sgnn
2907221167Sgnn
2908221167Sgnn	__hal_blockpool_destroy(&hldev->block_pool);
2909221167Sgnn
2910221167Sgnn#if defined(VXGE_TRACE_INTO_CIRCULAR_ARR)
2911221167Sgnn	if (hldev->trace_buf.size) {
2912221167Sgnn		vxge_os_free(NULL,
2913221167Sgnn		    hldev->trace_buf.data,
2914221167Sgnn		    hldev->trace_buf.size);
2915221167Sgnn	}
2916221167Sgnn#endif
2917221167Sgnn
2918221167Sgnn	vxge_os_free(hldev->header.pdev, hldev, sizeof(__hal_device_t));
2919221167Sgnn
2920221167Sgnn	vxge_hal_trace_log_driver("<== %s:%s:%d Result = 0",
2921221167Sgnn	    __FILE__, __func__, __LINE__);
2922221167Sgnn}
2923221167Sgnn
2924221167Sgnn/*
2925221167Sgnn * vxge_hal_device_enable - Enable device.
2926221167Sgnn * @devh: HAL device handle.
2927221167Sgnn *
2928221167Sgnn * Enable the specified device: bring up the link/interface.
2929221167Sgnn *
2930221167Sgnn */
2931221167Sgnnvxge_hal_status_e
2932221167Sgnnvxge_hal_device_enable(
2933221167Sgnn    vxge_hal_device_h devh)
2934221167Sgnn{
2935221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
2936221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
2937221167Sgnn
2938221167Sgnn	vxge_assert(devh != NULL);
2939221167Sgnn
2940221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
2941221167Sgnn	    __FILE__, __func__, __LINE__);
2942221167Sgnn
2943221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
2944221167Sgnn	    (ptr_t) devh);
2945221167Sgnn
2946221167Sgnn	if (!hldev->hw_is_initialized) {
2947221167Sgnn
2948221167Sgnn		status = __hal_device_hw_initialize(hldev);
2949221167Sgnn		if (status != VXGE_HAL_OK) {
2950221167Sgnn			vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2951221167Sgnn			    __FILE__, __func__, __LINE__, status);
2952221167Sgnn			return (status);
2953221167Sgnn		}
2954221167Sgnn	}
2955221167Sgnn
2956221167Sgnn	__hal_device_bus_master_enable(hldev);
2957221167Sgnn
2958221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
2959221167Sgnn	    __FILE__, __func__, __LINE__, status);
2960221167Sgnn	return (status);
2961221167Sgnn}
2962221167Sgnn
2963221167Sgnn/*
2964221167Sgnn * vxge_hal_device_disable - Disable X3100 adapter.
2965221167Sgnn * @devh: HAL device handle.
2966221167Sgnn *
2967221167Sgnn * Disable this device. To gracefully reset the adapter, the host should:
2968221167Sgnn *
2969221167Sgnn *	- call vxge_hal_device_disable();
2970221167Sgnn *
2971221167Sgnn *	- call vxge_hal_device_intr_disable();
2972221167Sgnn *
2973221167Sgnn *	- do some work (error recovery, change mtu, reset, etc);
2974221167Sgnn *
2975221167Sgnn *	- call vxge_hal_device_enable();
2976221167Sgnn *
2977221167Sgnn *	- call vxge_hal_device_intr_enable().
2978221167Sgnn *
2979221167Sgnn * Note: Disabling the device does _not_ include disabling of interrupts.
2980221167Sgnn * After disabling the device stops receiving new frames but those frames
2981221167Sgnn * that were already in the pipe will keep coming for some few milliseconds.
2982221167Sgnn *
2983221167Sgnn *
2984221167Sgnn */
2985221167Sgnnvxge_hal_status_e
2986221167Sgnnvxge_hal_device_disable(
2987221167Sgnn    vxge_hal_device_h devh)
2988221167Sgnn{
2989221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
2990221167Sgnn
2991221167Sgnn	vxge_assert(devh != NULL);
2992221167Sgnn
2993221167Sgnn#if (VXGE_COMPONENT_HAL_DEVICE & VXGE_DEBUG_MODULE_MASK)
2994221167Sgnn
2995221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
2996221167Sgnn
2997221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
2998221167Sgnn	    __FILE__, __func__, __LINE__);
2999221167Sgnn
3000221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT,
3001221167Sgnn	    (ptr_t) devh);
3002221167Sgnn
3003221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d Result = %d",
3004221167Sgnn	    __FILE__, __func__, __LINE__, status);
3005221167Sgnn#endif
3006221167Sgnn
3007221167Sgnn	return (status);
3008221167Sgnn}
3009221167Sgnn
3010221167Sgnn/*
3011221167Sgnn * vxge_hal_device_hw_stats_enable - Enable device h/w statistics.
3012221167Sgnn * @devh: HAL Device.
3013221167Sgnn *
3014221167Sgnn * Enable the DMA vpath statistics for the device. The function is to be called
3015221167Sgnn * to re-enable the adapter to update stats into the host memory
3016221167Sgnn *
3017221167Sgnn * See also: vxge_hal_device_hw_stats_disable()
3018221167Sgnn */
3019221167Sgnnvxge_hal_status_e
3020221167Sgnnvxge_hal_device_hw_stats_enable(
3021221167Sgnn    vxge_hal_device_h devh)
3022221167Sgnn{
3023221167Sgnn	u32 i;
3024221167Sgnn	u64 val64;
3025221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
3026221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
3027221167Sgnn
3028221167Sgnn	vxge_assert(devh != NULL);
3029221167Sgnn
3030221167Sgnn	vxge_hal_trace_log_stats("==> %s:%s:%d",
3031221167Sgnn	    __FILE__, __func__, __LINE__);
3032221167Sgnn
3033221167Sgnn	vxge_hal_trace_log_stats("devh = 0x"VXGE_OS_STXFMT,
3034221167Sgnn	    (ptr_t) devh);
3035221167Sgnn
3036221167Sgnn	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
3037221167Sgnn	    hldev->header.regh0,
3038221167Sgnn	    &hldev->common_reg->stats_cfg0);
3039221167Sgnn
3040221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
3041221167Sgnn
3042221167Sgnn		if (!(hldev->vpaths_deployed & mBIT(i)))
3043221167Sgnn			continue;
3044221167Sgnn
3045221167Sgnn		vxge_os_memcpy(hldev->virtual_paths[i].hw_stats_sav,
3046221167Sgnn		    hldev->virtual_paths[i].hw_stats,
3047221167Sgnn		    sizeof(vxge_hal_vpath_stats_hw_info_t));
3048221167Sgnn		if (hldev->header.config.stats_read_method ==
3049221167Sgnn		    VXGE_HAL_STATS_READ_METHOD_DMA) {
3050221167Sgnn			val64 |=
3051221167Sgnn			    VXGE_HAL_STATS_CFG0_STATS_ENABLE((1 << (16 - i)));
3052221167Sgnn		} else {
3053221167Sgnn			status = __hal_vpath_hw_stats_get(
3054221167Sgnn			    &hldev->virtual_paths[i],
3055221167Sgnn			    hldev->virtual_paths[i].hw_stats);
3056221167Sgnn		}
3057221167Sgnn
3058221167Sgnn	}
3059221167Sgnn
3060221167Sgnn	vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
3061221167Sgnn	    hldev->header.regh0,
3062221167Sgnn	    (u32) bVAL32(val64, 0),
3063221167Sgnn	    &hldev->common_reg->stats_cfg0);
3064221167Sgnn
3065221167Sgnn	vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3066221167Sgnn	    __FILE__, __func__, __LINE__, status);
3067221167Sgnn	return (status);
3068221167Sgnn}
3069221167Sgnn
3070221167Sgnn/*
3071221167Sgnn * vxge_hal_device_hw_stats_disable - Disable device h/w statistics.
3072221167Sgnn * @devh: HAL Device.
3073221167Sgnn *
3074221167Sgnn * Enable the DMA vpath statistics for the device. The function is to be called
3075221167Sgnn * to disable the adapter to update stats into the host memory. This function
3076221167Sgnn * is not needed to be called, normally.
3077221167Sgnn *
3078221167Sgnn * See also: vxge_hal_device_hw_stats_enable()
3079221167Sgnn */
3080221167Sgnnvxge_hal_status_e
3081221167Sgnnvxge_hal_device_hw_stats_disable(
3082221167Sgnn    vxge_hal_device_h devh)
3083221167Sgnn{
3084221167Sgnn	u32 i;
3085221167Sgnn	u64 val64;
3086221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
3087221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
3088221167Sgnn
3089221167Sgnn	vxge_assert(devh != NULL);
3090221167Sgnn
3091221167Sgnn	vxge_hal_trace_log_stats("==> %s:%s:%d",
3092221167Sgnn	    __FILE__, __func__, __LINE__);
3093221167Sgnn
3094221167Sgnn	vxge_hal_trace_log_stats("devh = 0x"VXGE_OS_STXFMT,
3095221167Sgnn	    (ptr_t) devh);
3096221167Sgnn
3097221167Sgnn	val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
3098221167Sgnn	    hldev->header.regh0,
3099221167Sgnn	    &hldev->common_reg->stats_cfg0);
3100221167Sgnn
3101221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
3102221167Sgnn
3103221167Sgnn		if (!(hldev->vpaths_deployed & mBIT(i)))
3104221167Sgnn			continue;
3105221167Sgnn
3106221167Sgnn		val64 &= ~VXGE_HAL_STATS_CFG0_STATS_ENABLE((1 << (16 - i)));
3107221167Sgnn
3108221167Sgnn	}
3109221167Sgnn
3110221167Sgnn	vxge_hal_pio_mem_write32_upper(hldev->header.pdev,
3111221167Sgnn	    hldev->header.regh0,
3112221167Sgnn	    (u32) bVAL32(val64, 0),
3113221167Sgnn	    &hldev->common_reg->stats_cfg0);
3114221167Sgnn
3115221167Sgnn	vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3116221167Sgnn	    __FILE__, __func__, __LINE__, status);
3117221167Sgnn	return (status);
3118221167Sgnn}
3119221167Sgnn
3120221167Sgnn/*
3121221167Sgnn * vxge_hal_device_hw_stats_get - Get the device hw statistics.
3122221167Sgnn * @devh: HAL Device.
3123221167Sgnn * @hw_stats: Hardware stats
3124221167Sgnn *
3125221167Sgnn * Returns the vpath h/w stats for the device.
3126221167Sgnn *
3127221167Sgnn * See also: vxge_hal_device_hw_stats_enable(),
3128221167Sgnn * vxge_hal_device_hw_stats_disable()
3129221167Sgnn */
3130221167Sgnnvxge_hal_status_e
3131221167Sgnnvxge_hal_device_hw_stats_get(
3132221167Sgnn    vxge_hal_device_h devh,
3133221167Sgnn    vxge_hal_device_stats_hw_info_t *hw_stats)
3134221167Sgnn{
3135221167Sgnn	u32 i;
3136221167Sgnn	u64 val64 = 0;
3137221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
3138221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
3139221167Sgnn
3140221167Sgnn	vxge_assert((devh != NULL) && (hw_stats != NULL));
3141221167Sgnn
3142221167Sgnn	vxge_hal_trace_log_stats("==> %s:%s:%d",
3143221167Sgnn	    __FILE__, __func__, __LINE__);
3144221167Sgnn
3145221167Sgnn	vxge_hal_trace_log_stats(
3146221167Sgnn	    "devh = 0x"VXGE_OS_STXFMT", hw_stats = 0x"VXGE_OS_STXFMT,
3147221167Sgnn	    (ptr_t) devh, (ptr_t) hw_stats);
3148221167Sgnn
3149221167Sgnn	if (hldev->header.config.stats_read_method ==
3150221167Sgnn	    VXGE_HAL_STATS_READ_METHOD_DMA) {
3151221167Sgnn
3152221167Sgnn		for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
3153221167Sgnn
3154221167Sgnn			if (!(hldev->vpaths_deployed & mBIT(i)))
3155221167Sgnn				continue;
3156221167Sgnn
3157221167Sgnn			val64 |=
3158221167Sgnn			    VXGE_HAL_STATS_CFG0_STATS_ENABLE((1 << (16 - i)));
3159221167Sgnn
3160221167Sgnn		}
3161221167Sgnn
3162221167Sgnn		status = vxge_hal_device_register_poll(hldev->header.pdev,
3163221167Sgnn		    hldev->header.regh0,
3164221167Sgnn		    &hldev->common_reg->stats_cfg0,
3165221167Sgnn		    0,
3166221167Sgnn		    val64,
3167221167Sgnn		    hldev->header.config.device_poll_millis);
3168221167Sgnn
3169221167Sgnn	}
3170221167Sgnn
3171221167Sgnn	if (status == VXGE_HAL_OK) {
3172221167Sgnn		vxge_os_memcpy(hw_stats,
3173221167Sgnn		    &hldev->stats.hw_dev_info_stats,
3174221167Sgnn		    sizeof(vxge_hal_device_stats_hw_info_t));
3175221167Sgnn	}
3176221167Sgnn
3177221167Sgnn	vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3178221167Sgnn	    __FILE__, __func__, __LINE__, status);
3179221167Sgnn	return (status);
3180221167Sgnn}
3181221167Sgnn
3182221167Sgnn/*
3183221167Sgnn * vxge_hal_device_sw_stats_get - Get the device sw statistics.
3184221167Sgnn * @devh: HAL Device.
3185221167Sgnn * @sw_stats: Software stats
3186221167Sgnn *
3187221167Sgnn * Returns the vpath s/w stats for the device.
3188221167Sgnn *
3189221167Sgnn * See also: vxge_hal_device_hw_stats_get()
3190221167Sgnn */
3191221167Sgnnvxge_hal_status_e
3192221167Sgnnvxge_hal_device_sw_stats_get(
3193221167Sgnn    vxge_hal_device_h devh,
3194221167Sgnn    vxge_hal_device_stats_sw_info_t *sw_stats)
3195221167Sgnn{
3196221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
3197221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
3198221167Sgnn
3199221167Sgnn	vxge_assert((hldev != NULL) && (sw_stats != NULL));
3200221167Sgnn
3201221167Sgnn	vxge_hal_trace_log_stats("==> %s:%s:%d",
3202221167Sgnn	    __FILE__, __func__, __LINE__);
3203221167Sgnn
3204221167Sgnn	vxge_hal_trace_log_stats(
3205221167Sgnn	    "devh = 0x"VXGE_OS_STXFMT", sw_stats = 0x"VXGE_OS_STXFMT,
3206221167Sgnn	    (ptr_t) devh, (ptr_t) sw_stats);
3207221167Sgnn
3208221167Sgnn	vxge_os_memcpy(sw_stats,
3209221167Sgnn	    &hldev->stats.sw_dev_info_stats,
3210221167Sgnn	    sizeof(vxge_hal_device_stats_sw_info_t));
3211221167Sgnn
3212221167Sgnn	vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3213221167Sgnn	    __FILE__, __func__, __LINE__, status);
3214221167Sgnn	return (status);
3215221167Sgnn}
3216221167Sgnn
3217221167Sgnn/*
3218221167Sgnn * vxge_hal_device_stats_get - Get the device statistics.
3219221167Sgnn * @devh: HAL Device.
3220221167Sgnn * @stats: Device stats
3221221167Sgnn *
3222221167Sgnn * Returns the device stats for the device.
3223221167Sgnn *
3224221167Sgnn * See also: vxge_hal_device_hw_stats_get(), vxge_hal_device_sw_stats_get()
3225221167Sgnn */
3226221167Sgnnvxge_hal_status_e
3227221167Sgnnvxge_hal_device_stats_get(
3228221167Sgnn    vxge_hal_device_h devh,
3229221167Sgnn    vxge_hal_device_stats_t *stats)
3230221167Sgnn{
3231221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
3232221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
3233221167Sgnn
3234221167Sgnn	vxge_assert((hldev != NULL) && (stats != NULL));
3235221167Sgnn
3236221167Sgnn	vxge_hal_trace_log_stats("==> %s:%s:%d",
3237221167Sgnn	    __FILE__, __func__, __LINE__);
3238221167Sgnn
3239221167Sgnn	vxge_hal_trace_log_stats(
3240221167Sgnn	    "devh = 0x"VXGE_OS_STXFMT", stats = 0x"VXGE_OS_STXFMT,
3241221167Sgnn	    (ptr_t) devh, (ptr_t) stats);
3242221167Sgnn
3243221167Sgnn	vxge_os_memcpy(stats,
3244221167Sgnn	    &hldev->stats,
3245221167Sgnn	    sizeof(vxge_hal_device_stats_t));
3246221167Sgnn
3247221167Sgnn	vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3248221167Sgnn	    __FILE__, __func__, __LINE__, status);
3249221167Sgnn	return (status);
3250221167Sgnn}
3251221167Sgnn
3252221167Sgnn/*
3253221167Sgnn * vxge_hal_device_xmac_stats_get - Get the Device XMAC Statistics
3254221167Sgnn * @devh: HAL device handle.
3255221167Sgnn * @xmac_stats: Buffer to return XMAC Statistics.
3256221167Sgnn *
3257221167Sgnn * Get the XMAC Statistics
3258221167Sgnn *
3259221167Sgnn */
3260221167Sgnnvxge_hal_status_e
3261221167Sgnnvxge_hal_device_xmac_stats_get(vxge_hal_device_h devh,
3262221167Sgnn    vxge_hal_device_xmac_stats_t *xmac_stats)
3263221167Sgnn{
3264221167Sgnn	vxge_hal_status_e status = VXGE_HAL_OK;
3265221167Sgnn	u32 i;
3266221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
3267221167Sgnn
3268221167Sgnn	vxge_assert((hldev != NULL) && (xmac_stats != NULL));
3269221167Sgnn
3270221167Sgnn	vxge_hal_trace_log_stats("==> %s:%s:%d",
3271221167Sgnn	    __FILE__, __func__, __LINE__);
3272221167Sgnn
3273221167Sgnn	vxge_hal_trace_log_stats(
3274221167Sgnn	    "devh = 0x"VXGE_OS_STXFMT", xmac_stats = 0x"VXGE_OS_STXFMT,
3275221167Sgnn	    (ptr_t) devh, (ptr_t) xmac_stats);
3276221167Sgnn
3277221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
3278221167Sgnn
3279221167Sgnn
3280221167Sgnn		if (!(hldev->vpaths_deployed & mBIT(i)))
3281221167Sgnn			continue;
3282221167Sgnn
3283221167Sgnn		status = __hal_vpath_xmac_tx_stats_get(&hldev->virtual_paths[i],
3284221167Sgnn		    &xmac_stats->vpath_tx_stats[i]);
3285221167Sgnn
3286221167Sgnn		if (status != VXGE_HAL_OK) {
3287221167Sgnn			vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3288221167Sgnn			    __FILE__, __func__, __LINE__, status);
3289221167Sgnn			return (status);
3290221167Sgnn		}
3291221167Sgnn
3292221167Sgnn		status = __hal_vpath_xmac_rx_stats_get(&hldev->virtual_paths[i],
3293221167Sgnn		    &xmac_stats->vpath_rx_stats[i]);
3294221167Sgnn
3295221167Sgnn		if (status != VXGE_HAL_OK) {
3296221167Sgnn			vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3297221167Sgnn			    __FILE__, __func__, __LINE__, status);
3298221167Sgnn			return (status);
3299221167Sgnn		}
3300221167Sgnn
3301221167Sgnn	}
3302221167Sgnn
3303221167Sgnn	vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d",
3304221167Sgnn	    __FILE__, __func__, __LINE__, status);
3305221167Sgnn	return (status);
3306221167Sgnn}
3307221167Sgnn
3308221167Sgnn#if defined(VXGE_TRACE_INTO_CIRCULAR_ARR)
3309221167Sgnn
3310221167Sgnn/*
3311221167Sgnn * vxge_hal_device_trace_write - Write the trace from the given buffer into
3312221167Sgnn *				 circular trace buffer
3313221167Sgnn * @devh: HAL device handle.
3314221167Sgnn * @trace_buf: Buffer containing the trace.
3315221167Sgnn * @trace_len: Length of the trace in the buffer
3316221167Sgnn *
3317221167Sgnn * Writes the trace from the given buffer into the circular trace buffer
3318221167Sgnn *
3319221167Sgnn */
3320221167Sgnnvoid
3321221167Sgnnvxge_hal_device_trace_write(vxge_hal_device_h devh,
3322221167Sgnn    u8 *trace_buf,
3323221167Sgnn    u32 trace_len)
3324221167Sgnn{
3325221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
3326221167Sgnn	u32 offset;
3327221167Sgnn
3328221167Sgnn	if (hldev == NULL)
3329221167Sgnn		return;
3330221167Sgnn
3331221167Sgnn	offset = hldev->trace_buf.offset;
3332221167Sgnn
3333221167Sgnn	if (trace_len > 1) {
3334221167Sgnn
3335221167Sgnn		u32 leftsize = hldev->trace_buf.size - offset;
3336221167Sgnn
3337221167Sgnn		if (trace_len > leftsize) {
3338221167Sgnn			vxge_os_memzero(hldev->trace_buf.data + offset,
3339221167Sgnn			    leftsize);
3340221167Sgnn			offset = 0;
3341221167Sgnn			hldev->trace_buf.wrapped_count++;
3342221167Sgnn		}
3343221167Sgnn
3344221167Sgnn		vxge_os_memcpy(hldev->trace_buf.data + offset,
3345221167Sgnn		    trace_buf, trace_len);
3346221167Sgnn		offset += trace_len;
3347221167Sgnn		hldev->trace_buf.offset = offset;
3348221167Sgnn
3349221167Sgnn	}
3350221167Sgnn}
3351221167Sgnn
3352221167Sgnn/*
3353221167Sgnn * vxge_hal_device_trace_dump - Dump the trace buffer.
3354221167Sgnn * @devh: HAL device handle.
3355221167Sgnn *
3356221167Sgnn * Dump the trace buffer contents.
3357221167Sgnn */
3358221167Sgnnvoid
3359221167Sgnnvxge_hal_device_trace_dump(vxge_hal_device_h devh)
3360221167Sgnn{
3361221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
3362221167Sgnn	u32 offset, i = 0;
3363221167Sgnn
3364221167Sgnn	if (hldev == NULL)
3365221167Sgnn		return;
3366221167Sgnn
3367221167Sgnn	offset = hldev->trace_buf.offset;
3368221167Sgnn
3369221167Sgnn	vxge_os_printf("################ Trace dump Begin ###############\n");
3370221167Sgnn
3371221167Sgnn	if (hldev->trace_buf.wrapped_count) {
3372221167Sgnn		for (i = hldev->trace_buf.offset;
3373221167Sgnn		    i < hldev->trace_buf.size; i += offset) {
3374221167Sgnn			if (*(hldev->trace_buf.data + i))
3375221167Sgnn				vxge_os_printf(hldev->trace_buf.data + i);
3376221167Sgnn			offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1;
3377221167Sgnn		}
3378221167Sgnn	}
3379221167Sgnn
3380221167Sgnn	for (i = 0; i < hldev->trace_buf.offset; i += offset) {
3381221167Sgnn		if (*(hldev->trace_buf.data + i))
3382221167Sgnn			vxge_os_printf(hldev->trace_buf.data + i);
3383221167Sgnn		offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1;
3384221167Sgnn	}
3385221167Sgnn
3386221167Sgnn	vxge_os_printf("################ Trace dump End ###############\n");
3387221167Sgnn
3388221167Sgnn}
3389221167Sgnn
3390221167Sgnn/*
3391221167Sgnn * vxge_hal_device_trace_read - Read trace buffer contents.
3392221167Sgnn * @devh: HAL device handle.
3393221167Sgnn * @buffer: Buffer to store the trace buffer contents.
3394221167Sgnn * @buf_size: Size of the buffer.
3395221167Sgnn * @read_length: Size of the valid data in the buffer.
3396221167Sgnn *
3397221167Sgnn * Read  HAL trace buffer contents starting from the offset
3398221167Sgnn * upto the size of the buffer or till EOF is reached.
3399221167Sgnn *
3400221167Sgnn * Returns: VXGE_HAL_OK - success.
3401221167Sgnn * VXGE_HAL_EOF_TRACE_BUF - No more data in the trace buffer.
3402221167Sgnn *
3403221167Sgnn */
3404221167Sgnnvxge_hal_status_e
3405221167Sgnnvxge_hal_device_trace_read(vxge_hal_device_h devh,
3406221167Sgnn    char *buffer,
3407221167Sgnn    unsigned buf_size,
3408221167Sgnn    unsigned *read_length)
3409221167Sgnn{
3410221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
3411221167Sgnn	u32 offset, i = 0, buf_off = 0;
3412221167Sgnn
3413221167Sgnn	*read_length = 0;
3414221167Sgnn	*buffer = 0;
3415221167Sgnn
3416221167Sgnn	if (hldev == NULL)
3417221167Sgnn		return (VXGE_HAL_FAIL);
3418221167Sgnn
3419221167Sgnn	offset = hldev->trace_buf.offset;
3420221167Sgnn
3421221167Sgnn	if (hldev->trace_buf.wrapped_count) {
3422221167Sgnn		for (i = hldev->trace_buf.offset;
3423221167Sgnn		    i < hldev->trace_buf.size; i += offset) {
3424221167Sgnn			if (*(hldev->trace_buf.data + i)) {
3425221167Sgnn				vxge_os_sprintf(buffer + buf_off, "%s\n",
3426221167Sgnn				    hldev->trace_buf.data + i);
3427221167Sgnn				buf_off += vxge_os_strlen(
3428221167Sgnn				    hldev->trace_buf.data + i) + 1;
3429221167Sgnn				if (buf_off > buf_size)
3430221167Sgnn					return (VXGE_HAL_ERR_OUT_OF_MEMORY);
3431221167Sgnn			}
3432221167Sgnn			offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1;
3433221167Sgnn		}
3434221167Sgnn	}
3435221167Sgnn
3436221167Sgnn	for (i = 0; i < hldev->trace_buf.offset; i += offset) {
3437221167Sgnn		if (*(hldev->trace_buf.data + i)) {
3438221167Sgnn			vxge_os_sprintf(buffer + buf_off, "%s\n",
3439221167Sgnn			    hldev->trace_buf.data + i);
3440221167Sgnn			buf_off += vxge_os_strlen(
3441221167Sgnn			    hldev->trace_buf.data + i) + 1;
3442221167Sgnn			if (buf_off > buf_size)
3443221167Sgnn				return (VXGE_HAL_ERR_OUT_OF_MEMORY);
3444221167Sgnn		}
3445221167Sgnn		offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1;
3446221167Sgnn	}
3447221167Sgnn
3448221167Sgnn	*read_length = buf_off;
3449221167Sgnn	*(buffer + buf_off + 1) = 0;
3450221167Sgnn
3451221167Sgnn	return (VXGE_HAL_OK);
3452221167Sgnn}
3453221167Sgnn
3454221167Sgnn#endif
3455221167Sgnn
3456221167Sgnn/*
3457221167Sgnn * vxge_hal_device_debug_set - Set the debug module, level and timestamp
3458221167Sgnn * @devh: Hal device object
3459221167Sgnn * @level: Debug level as defined in enum vxge_debug_level_e
3460221167Sgnn * @module masks: An or value of component masks as defined in vxge_debug.h
3461221167Sgnn *
3462221167Sgnn * This routine is used to dynamically change the debug output
3463221167Sgnn */
3464221167Sgnnvoid
3465221167Sgnnvxge_hal_device_debug_set(
3466221167Sgnn    vxge_hal_device_h devh,
3467221167Sgnn    vxge_debug_level_e level,
3468221167Sgnn    u32 mask)
3469221167Sgnn{
3470221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
3471221167Sgnn
3472221167Sgnn	hldev->header.debug_module_mask = mask;
3473221167Sgnn	hldev->header.debug_level = level;
3474221167Sgnn
3475221167Sgnn	hldev->d_trace_mask = 0;
3476221167Sgnn	hldev->d_info_mask = 0;
3477221167Sgnn	hldev->d_err_mask = 0;
3478221167Sgnn
3479221167Sgnn	switch (level) {
3480221167Sgnn	case VXGE_TRACE:
3481221167Sgnn		hldev->d_trace_mask = mask;
3482221167Sgnn		/* FALLTHROUGH */
3483221167Sgnn
3484221167Sgnn	case VXGE_INFO:
3485221167Sgnn		hldev->d_info_mask = mask;
3486221167Sgnn		/* FALLTHROUGH */
3487221167Sgnn
3488221167Sgnn	case VXGE_ERR:
3489221167Sgnn		hldev->d_err_mask = mask;
3490221167Sgnn		/* FALLTHROUGH */
3491221167Sgnn
3492221167Sgnn	default:
3493221167Sgnn		break;
3494221167Sgnn	}
3495221167Sgnn}
3496221167Sgnn
3497221167Sgnn/*
3498221167Sgnn * vxge_hal_device_flick_link_led - Flick (blink) link LED.
3499221167Sgnn * @devh: HAL device handle.
3500221167Sgnn * @port : Port number 0, or 1
3501221167Sgnn * @on_off: TRUE if flickering to be on, FALSE to be off
3502221167Sgnn *
3503221167Sgnn * Flicker the link LED.
3504221167Sgnn */
3505221167Sgnnvxge_hal_status_e
3506221167Sgnnvxge_hal_device_flick_link_led(vxge_hal_device_h devh, u32 port, u32 on_off)
3507221167Sgnn{
3508221167Sgnn	vxge_hal_status_e status;
3509221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
3510221167Sgnn
3511221167Sgnn	vxge_assert(devh != NULL);
3512221167Sgnn
3513221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
3514221167Sgnn	    __FILE__, __func__, __LINE__);
3515221167Sgnn
3516221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT
3517221167Sgnn	    ", port = %d, on_off = %d", (ptr_t) devh, port, on_off);
3518221167Sgnn
3519221167Sgnn	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
3520221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
3521221167Sgnn		    __FILE__, __func__, __LINE__,
3522221167Sgnn		    VXGE_HAL_ERR_INVALID_DEVICE);
3523221167Sgnn
3524221167Sgnn		return (VXGE_HAL_ERR_INVALID_DEVICE);
3525221167Sgnn	}
3526221167Sgnn
3527221167Sgnn	status = __hal_vpath_flick_link_led(hldev,
3528221167Sgnn	    hldev->first_vp_id, port, on_off);
3529221167Sgnn
3530221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
3531221167Sgnn	    __FILE__, __func__, __LINE__, status);
3532221167Sgnn
3533221167Sgnn	return (status);
3534221167Sgnn}
3535221167Sgnn
3536221167Sgnn/*
3537221167Sgnn * vxge_hal_device_getpause_data -Pause frame frame generation and reception.
3538221167Sgnn * @devh: HAL device handle.
3539221167Sgnn * @port : Port number 0, 1, or 2
3540221167Sgnn * @tx : A field to return the pause generation capability of the NIC.
3541221167Sgnn * @rx : A field to return the pause reception capability of the NIC.
3542221167Sgnn *
3543221167Sgnn * Returns the Pause frame generation and reception capability of the NIC.
3544221167Sgnn * Return value:
3545221167Sgnn * status
3546221167Sgnn */
3547221167Sgnnvxge_hal_status_e
3548221167Sgnnvxge_hal_device_getpause_data(
3549221167Sgnn    vxge_hal_device_h devh,
3550221167Sgnn    u32 port,
3551221167Sgnn    u32 *tx,
3552221167Sgnn    u32 *rx)
3553221167Sgnn{
3554221167Sgnn	u32 i;
3555221167Sgnn	u64 val64;
3556221167Sgnn	vxge_hal_status_e status = VXGE_HAL_ERR_VPATH_NOT_AVAILABLE;
3557221167Sgnn	__hal_device_t *hldev = (__hal_device_t *) devh;
3558221167Sgnn
3559221167Sgnn	vxge_assert(devh != NULL);
3560221167Sgnn
3561221167Sgnn	vxge_hal_trace_log_device("==> %s:%s:%d",
3562221167Sgnn	    __FILE__, __func__, __LINE__);
3563221167Sgnn
3564221167Sgnn	vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT", "
3565221167Sgnn	    "port = %d, tx = 0x"VXGE_OS_STXFMT", "
3566221167Sgnn	    "rx = 0x"VXGE_OS_STXFMT, (ptr_t) devh, port, (ptr_t) tx,
3567221167Sgnn	    (ptr_t) rx);
3568221167Sgnn
3569221167Sgnn	if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
3570221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
3571221167Sgnn		    __FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_DEVICE);
3572221167Sgnn		return (VXGE_HAL_ERR_INVALID_DEVICE);
3573221167Sgnn	}
3574221167Sgnn
3575221167Sgnn	if (port >= VXGE_HAL_MAC_MAX_PORTS) {
3576221167Sgnn		vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
3577221167Sgnn		    __FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_PORT);
3578221167Sgnn		return (VXGE_HAL_ERR_INVALID_PORT);
3579221167Sgnn	}
3580221167Sgnn
3581221167Sgnn	for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
3582221167Sgnn
3583221167Sgnn		if (!(hldev->vpath_assignments & mBIT(i)))
3584221167Sgnn			continue;
3585221167Sgnn
3586221167Sgnn		val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
3587221167Sgnn		    hldev->header.regh0,
3588221167Sgnn		    &hldev->vpmgmt_reg[i]->
3589221167Sgnn		    rxmac_pause_cfg_port_vpmgmt_clone[port]);
3590221167Sgnn
3591221167Sgnn		if (val64 & VXGE_HAL_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_GEN_EN)
3592221167Sgnn			*tx = 1;
3593221167Sgnn
3594221167Sgnn		if (val64 & VXGE_HAL_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_RCV_EN)
3595221167Sgnn			*rx = 1;
3596221167Sgnn
3597221167Sgnn		status = VXGE_HAL_OK;
3598221167Sgnn
3599221167Sgnn		break;
3600221167Sgnn	}
3601221167Sgnn
3602221167Sgnn	vxge_hal_trace_log_device("<== %s:%s:%d  Result: %d",
3603221167Sgnn	    __FILE__, __func__, __LINE__, status);
3604221167Sgnn
3605221167Sgnn	return (status);
3606221167Sgnn}
3607221167Sgnn
3608221167Sgnnvxge_hal_status_e
3609221167Sgnnvxge_hal_device_is_privileged(u32 host_type, u32 func_id)
3610221167Sgnn{
3611221167Sgnn	u32 access_rights;
3612221167Sgnn	vxge_hal_status_e status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
3613221167Sgnn
3614221167Sgnn	access_rights = __hal_device_access_rights_get(host_type, func_id);
3615221167Sgnn
3616221167Sgnn	if (access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)
3617221167Sgnn		status = VXGE_HAL_OK;
3618221167Sgnn
3619221167Sgnn	return (status);
3620221167Sgnn}
3621