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