/*- * Copyright(c) 2002-2011 Exar Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification are permitted provided the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Exar Corporation nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /*$FreeBSD$*/ #include /* * vxge_hal_pio_mem_write32_upper * * Endiann-aware implementation of vxge_os_pio_mem_write32(). * Since X3100 has 64bit registers, we differintiate uppper and lower * parts. */ void vxge_hal_pio_mem_write32_upper(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr) { #if defined(VXGE_OS_HOST_BIG_ENDIAN) && !defined(VXGE_OS_PIO_LITTLE_ENDIAN) vxge_os_pio_mem_write32(pdev, regh, val, addr); #else vxge_os_pio_mem_write32(pdev, regh, val, (void *) ((char *) addr + 4)); #endif } /* * vxge_hal_pio_mem_write32_lower * * Endiann-aware implementation of vxge_os_pio_mem_write32(). * Since X3100 has 64bit registers, we differintiate uppper and lower * parts. */ void vxge_hal_pio_mem_write32_lower(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr) { #if defined(VXGE_OS_HOST_BIG_ENDIAN) && !defined(VXGE_OS_PIO_LITTLE_ENDIAN) vxge_os_pio_mem_write32(pdev, regh, val, (void *) ((char *) addr + 4)); #else vxge_os_pio_mem_write32(pdev, regh, val, addr); #endif } /* * vxge_hal_device_pciconfig_get - Read the content of given address * in pci config space. * @devh: Device handle. * @offset: Configuration address(offset)to read from * @length: Length of the data (1, 2 or 4 bytes) * @val: Pointer to a buffer to return the content of the address * * Read from the pci config space. * */ vxge_hal_status_e vxge_hal_device_pciconfig_get( vxge_hal_device_h devh, u32 offset, u32 length, void *val) { u32 i; vxge_hal_status_e status = VXGE_HAL_OK; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert((devh != NULL) && (val != NULL)); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpath_assignments & mBIT(i))) continue; status = __hal_vpath_pci_read(hldev, i, offset, length, val); if (status == VXGE_HAL_OK) break; } vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * __hal_device_pci_caps_list_process * @hldev: HAL device handle. * * Process PCI capabilities and initialize the offsets */ void __hal_device_pci_caps_list_process(__hal_device_t *hldev) { u8 cap_id; u16 ext_cap_id; u16 next_ptr; u32 *ptr_32; vxge_hal_pci_config_t *pci_config = &hldev->pci_config_space_bios; vxge_assert(hldev != NULL); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT, (ptr_t) hldev); next_ptr = pci_config->capabilities_pointer; while (next_ptr != 0) { cap_id = VXGE_HAL_PCI_CAP_ID((((u8 *) pci_config) + next_ptr)); switch (cap_id) { case VXGE_HAL_PCI_CAP_ID_PM: hldev->pci_caps.pm_cap_offset = next_ptr; break; case VXGE_HAL_PCI_CAP_ID_VPD: hldev->pci_caps.vpd_cap_offset = next_ptr; break; case VXGE_HAL_PCI_CAP_ID_SLOTID: hldev->pci_caps.sid_cap_offset = next_ptr; break; case VXGE_HAL_PCI_CAP_ID_MSI: hldev->pci_caps.msi_cap_offset = next_ptr; break; case VXGE_HAL_PCI_CAP_ID_VS: hldev->pci_caps.vs_cap_offset = next_ptr; break; case VXGE_HAL_PCI_CAP_ID_SHPC: hldev->pci_caps.shpc_cap_offset = next_ptr; break; case VXGE_HAL_PCI_CAP_ID_PCIE: hldev->pci_e_caps = next_ptr; break; case VXGE_HAL_PCI_CAP_ID_MSIX: hldev->pci_caps.msix_cap_offset = next_ptr; break; case VXGE_HAL_PCI_CAP_ID_AGP: case VXGE_HAL_PCI_CAP_ID_CHSWP: case VXGE_HAL_PCI_CAP_ID_PCIX: case VXGE_HAL_PCI_CAP_ID_HT: case VXGE_HAL_PCI_CAP_ID_DBGPORT: case VXGE_HAL_PCI_CAP_ID_CPCICSR: case VXGE_HAL_PCI_CAP_ID_PCIBSVID: case VXGE_HAL_PCI_CAP_ID_AGP8X: case VXGE_HAL_PCI_CAP_ID_SECDEV: vxge_hal_info_log_device("Unexpected Capability = %d", cap_id); break; default: vxge_hal_info_log_device("Unknown capability = %d", cap_id); break; } next_ptr = VXGE_HAL_PCI_CAP_NEXT((((u8 *) pci_config) + next_ptr)); } /* CONSTCOND */ if (VXGE_HAL_PCI_CONFIG_SPACE_SIZE <= 0x100) { vxge_hal_trace_log_device("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); return; } next_ptr = 0x100; while (next_ptr != 0) { ptr_32 = (u32 *) ((void *) (((u8 *) pci_config) + next_ptr)); ext_cap_id = (u16) (VXGE_HAL_PCI_EXT_CAP_ID(*ptr_32)); switch (ext_cap_id) { case VXGE_HAL_PCI_EXT_CAP_ID_ERR: hldev->pci_e_ext_caps.err_cap_offset = next_ptr; break; case VXGE_HAL_PCI_EXT_CAP_ID_VC: hldev->pci_e_ext_caps.vc_cap_offset = next_ptr; break; case VXGE_HAL_PCI_EXT_CAP_ID_DSN: hldev->pci_e_ext_caps.dsn_cap_offset = next_ptr; break; case VXGE_HAL_PCI_EXT_CAP_ID_PWR: hldev->pci_e_ext_caps.pwr_budget_cap_offset = next_ptr; break; default: vxge_hal_info_log_device("Unknown capability = %d", ext_cap_id); break; } next_ptr = (u16) VXGE_HAL_PCI_EXT_CAP_NEXT(*ptr_32); } vxge_hal_trace_log_device("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * __hal_device_pci_e_init * @hldev: HAL device handle. * * Initialize certain PCI/PCI-X configuration registers * with recommended values. Save config space for future hw resets. */ void __hal_device_pci_e_init(__hal_device_t *hldev) { int i; u16 cmd; u32 *ptr_32; vxge_assert(hldev != NULL); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT, (ptr_t) hldev); /* save original PCI config space to restore it on device_terminate() */ ptr_32 = (u32 *) ((void *) &hldev->pci_config_space_bios); for (i = 0; i < VXGE_HAL_PCI_CONFIG_SPACE_SIZE / 4; i++) { (void) __hal_vpath_pci_read(hldev, hldev->first_vp_id, i * 4, 4, ptr_32 + i); } __hal_device_pci_caps_list_process(hldev); /* Set the PErr Repconse bit and SERR in PCI command register. */ (void) __hal_vpath_pci_read(hldev, hldev->first_vp_id, vxge_offsetof(vxge_hal_pci_config_le_t, command), 2, &cmd); cmd |= 0x140; vxge_os_pci_write16(hldev->header.pdev, hldev->header.cfgh, vxge_offsetof(vxge_hal_pci_config_le_t, command), cmd); /* save PCI config space for future resets */ ptr_32 = (u32 *) ((void *) &hldev->pci_config_space); for (i = 0; i < VXGE_HAL_PCI_CONFIG_SPACE_SIZE / 4; i++) { (void) __hal_vpath_pci_read(hldev, hldev->first_vp_id, i * 4, 4, ptr_32 + i); } vxge_hal_trace_log_device("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * __hal_device_bus_master_enable * @hldev: HAL device handle. * * Enable bus mastership. */ static void __hal_device_bus_master_enable(__hal_device_t *hldev) { u16 cmd; u16 bus_master = 4; vxge_assert(hldev != NULL); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT, (ptr_t) hldev); (void) __hal_vpath_pci_read(hldev, hldev->first_vp_id, vxge_offsetof(vxge_hal_pci_config_le_t, command), 2, &cmd); /* already enabled? do nothing */ if (cmd & bus_master) return; cmd |= bus_master; vxge_os_pci_write16(hldev->header.pdev, hldev->header.cfgh, vxge_offsetof(vxge_hal_pci_config_le_t, command), cmd); vxge_hal_trace_log_device("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_register_poll * @pdev: PCI device object. * @regh: BAR mapped memory handle (Solaris), or simply PCI device @pdev * (Linux and the rest.) * @reg: register to poll for * @op: 0 - bit reset, 1 - bit set * @mask: mask for logical "and" condition based on %op * @max_millis: maximum time to try to poll in milliseconds * * Will poll certain register for specified amount of time. * Will poll until masked bit is not cleared. */ 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) { u64 val64; u32 i = 0; vxge_hal_status_e ret = VXGE_HAL_FAIL; vxge_os_udelay(10); do { val64 = vxge_os_pio_mem_read64(pdev, regh, reg); if (op == 0 && !(val64 & mask)) { return (VXGE_HAL_OK); } else if (op == 1 && (val64 & mask) == mask) return (VXGE_HAL_OK); vxge_os_udelay(100); } while (++i <= 9); do { val64 = vxge_os_pio_mem_read64(pdev, regh, reg); if (op == 0 && !(val64 & mask)) { return (VXGE_HAL_OK); } else if (op == 1 && (val64 & mask) == mask) { return (VXGE_HAL_OK); } vxge_os_udelay(1000); } while (++i < max_millis); return (ret); } /* * __hal_device_register_stall * @pdev: PCI device object. * @regh: BAR mapped memory handle (Solaris), or simply PCI device @pdev * (Linux and the rest.) * @reg: register to poll for * @op: 0 - bit reset, 1 - bit set * @mask: mask for logical "and" condition based on %op * @max_millis: maximum time to try to poll in milliseconds * * Will poll certain register for specified amount of time. * Will poll until masked bit is not cleared. */ 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) { u64 val64; u32 i = 0; vxge_hal_status_e ret = VXGE_HAL_FAIL; vxge_os_stall(10); do { val64 = vxge_os_pio_mem_read64(pdev, regh, reg); if (op == 0 && !(val64 & mask)) { return (VXGE_HAL_OK); } else if (op == 1 && (val64 & mask) == mask) return (VXGE_HAL_OK); vxge_os_stall(100); } while (++i <= 9); do { val64 = vxge_os_pio_mem_read64(pdev, regh, reg); if (op == 0 && !(val64 & mask)) { return (VXGE_HAL_OK); } else if (op == 1 && (val64 & mask) == mask) { return (VXGE_HAL_OK); } vxge_os_stall(1000); } while (++i < max_millis); return (ret); } void* vxge_hal_device_get_legacy_reg(pci_dev_h pdev, pci_reg_h regh, u8 *bar0) { vxge_hal_legacy_reg_t *legacy_reg = NULL; /* * If length of Bar0 is 16MB, then assume we are configured * in MF8P_VP2 mode and add 8MB to get legacy_reg offsets */ if (vxge_os_pci_res_len(pdev, regh) == 0x1000000) legacy_reg = (vxge_hal_legacy_reg_t *) ((void *) (bar0 + 0x800000)); else legacy_reg = (vxge_hal_legacy_reg_t *) ((void *) bar0); return (legacy_reg); } /* * __hal_device_reg_addr_get * @hldev: HAL Device object. * * This routine sets the swapper and reads the toc pointer and initializes the * register location pointers in the device object. It waits until the ric is * completed initializing registers. */ vxge_hal_status_e __hal_device_reg_addr_get(__hal_device_t *hldev) { u64 val64; u32 i; vxge_hal_status_e status = VXGE_HAL_OK; vxge_assert(hldev); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT, (ptr_t) hldev); hldev->legacy_reg = (vxge_hal_legacy_reg_t *) vxge_hal_device_get_legacy_reg(hldev->header.pdev, hldev->header.regh0, hldev->header.bar0); status = __hal_legacy_swapper_set(hldev->header.pdev, hldev->header.regh0, hldev->legacy_reg); if (status != VXGE_HAL_OK) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->legacy_reg->toc_first_pointer); hldev->toc_reg = (vxge_hal_toc_reg_t *) ((void *) (hldev->header.bar0 + val64)); val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->toc_reg->toc_common_pointer); hldev->common_reg = (vxge_hal_common_reg_t *) ((void *) (hldev->header.bar0 + val64)); vxge_hal_info_log_device("COMMON = 0x"VXGE_OS_STXFMT, (ptr_t) hldev->common_reg); val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->toc_reg->toc_memrepair_pointer); hldev->memrepair_reg = (vxge_hal_memrepair_reg_t *) ((void *) (hldev->header.bar0 + val64)); vxge_hal_info_log_device("MEM REPAIR = 0x"VXGE_OS_STXFMT, (ptr_t) hldev->memrepair_reg); for (i = 0; i < VXGE_HAL_TITAN_PCICFGMGMT_REG_SPACES; i++) { val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->toc_reg->toc_pcicfgmgmt_pointer[i]); hldev->pcicfgmgmt_reg[i] = (vxge_hal_pcicfgmgmt_reg_t *) ((void *) (hldev->header.bar0 + val64)); vxge_hal_info_log_device("PCICFG_MGMT[%d] = " "0x"VXGE_OS_STXFMT, i, (ptr_t) hldev->pcicfgmgmt_reg[i]); } val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->toc_reg->toc_mrpcim_pointer); hldev->mrpcim_reg = (vxge_hal_mrpcim_reg_t *) ((void *) (hldev->header.bar0 + val64)); vxge_hal_info_log_device("MEM REPAIR = 0x"VXGE_OS_STXFMT, (ptr_t) hldev->mrpcim_reg); for (i = 0; i < VXGE_HAL_TITAN_SRPCIM_REG_SPACES; i++) { val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->toc_reg->toc_srpcim_pointer[i]); hldev->srpcim_reg[i] = (vxge_hal_srpcim_reg_t *) ((void *) (hldev->header.bar0 + val64)); vxge_hal_info_log_device("SRPCIM[%d] =0x"VXGE_OS_STXFMT, i, (ptr_t) hldev->srpcim_reg[i]); } for (i = 0; i < VXGE_HAL_TITAN_VPMGMT_REG_SPACES; i++) { val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->toc_reg->toc_vpmgmt_pointer[i]); hldev->vpmgmt_reg[i] = (vxge_hal_vpmgmt_reg_t *) ((void *) (hldev->header.bar0 + val64)); vxge_hal_info_log_device("VPMGMT[%d] = 0x"VXGE_OS_STXFMT, i, (ptr_t) hldev->vpmgmt_reg[i]); } for (i = 0; i < VXGE_HAL_TITAN_VPATH_REG_SPACES; i++) { val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->toc_reg->toc_vpath_pointer[i]); hldev->vpath_reg[i] = (vxge_hal_vpath_reg_t *) ((void *) (hldev->header.bar0 + val64)); vxge_hal_info_log_device("VPATH[%d] = 0x"VXGE_OS_STXFMT, i, (ptr_t) hldev->vpath_reg[i]); } val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->toc_reg->toc_kdfc); switch (VXGE_HAL_TOC_GET_KDFC_INITIAL_BIR(val64)) { case 0: hldev->kdfc = hldev->header.bar0 + VXGE_HAL_TOC_GET_KDFC_INITIAL_OFFSET(val64); break; case 2: hldev->kdfc = hldev->header.bar1 + VXGE_HAL_TOC_GET_KDFC_INITIAL_OFFSET(val64); break; case 4: hldev->kdfc = hldev->header.bar2 + VXGE_HAL_TOC_GET_KDFC_INITIAL_OFFSET(val64); break; default: vxge_hal_info_log_device("Invalid BIR = 0x"VXGE_OS_STXFMT, (ptr_t) VXGE_HAL_TOC_GET_KDFC_INITIAL_BIR(val64)); break; } vxge_hal_info_log_device("KDFC = 0x"VXGE_OS_STXFMT, (ptr_t) hldev->kdfc); val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->toc_reg->toc_usdc); switch (VXGE_HAL_TOC_GET_USDC_INITIAL_BIR(val64)) { case 0: hldev->usdc = hldev->header.bar0 + VXGE_HAL_TOC_GET_USDC_INITIAL_OFFSET(val64); break; case 2: hldev->usdc = hldev->header.bar1 + VXGE_HAL_TOC_GET_USDC_INITIAL_OFFSET(val64); break; case 4: hldev->usdc = hldev->header.bar2 + VXGE_HAL_TOC_GET_USDC_INITIAL_OFFSET(val64); break; default: vxge_hal_info_log_device("Invalid BIR = 0x"VXGE_OS_STXFMT, (ptr_t) VXGE_HAL_TOC_GET_USDC_INITIAL_BIR(val64)); break; } vxge_hal_info_log_device("USDC = 0x"VXGE_OS_STXFMT, (ptr_t) hldev->usdc); status = vxge_hal_device_register_poll(hldev->header.pdev, hldev->header.regh0, &hldev->common_reg->vpath_rst_in_prog, 0, VXGE_HAL_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(0x1ffff), VXGE_HAL_DEF_DEVICE_POLL_MILLIS); if (status != VXGE_HAL_OK) { vxge_hal_err_log_device("%s:vpath_rst_in_prog is not cleared", __func__); } vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * __hal_device_id_get * @hldev: HAL Device object. * * This routine returns sets the device id and revision numbers into the device * structure */ void __hal_device_id_get(__hal_device_t *hldev) { vxge_assert(hldev); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT, (ptr_t) hldev); (void) __hal_vpath_pci_read(hldev, hldev->first_vp_id, vxge_offsetof(vxge_hal_pci_config_le_t, device_id), 2, &hldev->header.device_id); (void) __hal_vpath_pci_read(hldev, hldev->first_vp_id, vxge_offsetof(vxge_hal_pci_config_le_t, revision), 2, &hldev->header.revision); vxge_hal_trace_log_device("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * __hal_device_access_rights_get: Get Access Rights of the driver * @host_type: Host type. * @func_id: Function Id * * This routine returns the Access Rights of the driver */ u32 __hal_device_access_rights_get(u32 host_type, u32 func_id) { u32 access_rights = VXGE_HAL_DEVICE_ACCESS_RIGHT_VPATH; switch (host_type) { case VXGE_HAL_NO_MR_NO_SR_NORMAL_FUNCTION: if (func_id == 0) { access_rights |= VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM | VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM; } break; case VXGE_HAL_MR_NO_SR_VH0_BASE_FUNCTION: access_rights |= VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM | VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM; break; case VXGE_HAL_NO_MR_SR_VH0_FUNCTION0: access_rights |= VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM | VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM; break; case VXGE_HAL_NO_MR_SR_VH0_VIRTUAL_FUNCTION: case VXGE_HAL_SR_VH_VIRTUAL_FUNCTION: break; case VXGE_HAL_MR_SR_VH0_INVALID_CONFIG: break; case VXGE_HAL_SR_VH_FUNCTION0: case VXGE_HAL_VH_NORMAL_FUNCTION: access_rights |= VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM; break; } return (access_rights); } /* * __hal_device_host_info_get * @hldev: HAL Device object. * * This routine returns the host type assignments */ void __hal_device_host_info_get(__hal_device_t *hldev) { u64 val64; u32 i; vxge_assert(hldev); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT, (ptr_t) hldev); val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->common_reg->host_type_assignments); hldev->host_type = (u32) VXGE_HAL_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64); val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->common_reg->vplane_assignments); hldev->srpcim_id = (u32) VXGE_HAL_VPLANE_ASSIGNMENTS_GET_VPLANE_ASSIGNMENTS(val64); hldev->vpath_assignments = vxge_os_pio_mem_read64( hldev->header.pdev, hldev->header.regh0, &hldev->common_reg->vpath_assignments); for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpath_assignments & mBIT(i))) continue; val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->common_reg->debug_assignments); hldev->vh_id = (u32) VXGE_HAL_DEBUG_ASSIGNMENTS_GET_VHLABEL(val64); val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->vpmgmt_reg[i]->vpath_to_func_map_cfg1); hldev->func_id = (u32) VXGE_HAL_VPATH_TO_FUNC_MAP_CFG1_GET_CFG1(val64); hldev->access_rights = __hal_device_access_rights_get( hldev->host_type, hldev->func_id); if (hldev->access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM) { hldev->manager_up = TRUE; } else { val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->vpmgmt_reg[i]->srpcim_to_vpath_wmsg); hldev->manager_up = __hal_ifmsg_is_manager_up(val64); } hldev->first_vp_id = i; break; } vxge_hal_trace_log_device("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * __hal_device_pci_e_info_get - Get PCI_E bus informations such as link_width * and signalling rate * @hldev: HAL device. * @signalling_rate: pointer to a variable of enumerated type * vxge_hal_pci_e_signalling_rate_e {}. * @link_width: pointer to a variable of enumerated type * vxge_hal_pci_e_link_width_e {}. * * Get pci-e signalling rate and link width. * * Returns: one of the vxge_hal_status_e {} enumerated types. * VXGE_HAL_OK - for success. * VXGE_HAL_ERR_INVALID_PCI_INFO - for invalid PCI information from the card. * VXGE_HAL_ERR_BAD_DEVICE_ID - for invalid card. * */ 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) { vxge_hal_status_e status = VXGE_HAL_OK; vxge_hal_pci_e_capability_t *pci_e_caps; vxge_assert((hldev != NULL) && (signalling_rate != NULL) && (link_width != NULL)); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT ", signalling_rate = 0x"VXGE_OS_STXFMT", " "link_width = 0x"VXGE_OS_STXFMT, (ptr_t) hldev, (ptr_t) signalling_rate, (ptr_t) link_width); pci_e_caps = (vxge_hal_pci_e_capability_t *) (((u8 *) &hldev->pci_config_space_bios) + hldev->pci_e_caps); switch (pci_e_caps->pci_e_lnkcap & VXGE_HAL_PCI_EXP_LNKCAP_LNK_SPEED) { case VXGE_HAL_PCI_EXP_LNKCAP_LS_2_5: *signalling_rate = VXGE_HAL_PCI_E_SIGNALLING_RATE_2_5GB; break; case VXGE_HAL_PCI_EXP_LNKCAP_LS_5: *signalling_rate = VXGE_HAL_PCI_E_SIGNALLING_RATE_5GB; break; default: *signalling_rate = VXGE_HAL_PCI_E_SIGNALLING_RATE_UNKNOWN; break; } switch ((pci_e_caps->pci_e_lnksta & VXGE_HAL_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4) { case VXGE_HAL_PCI_EXP_LNKCAP_LW_X1: *link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X1; break; case VXGE_HAL_PCI_EXP_LNKCAP_LW_X2: *link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X2; break; case VXGE_HAL_PCI_EXP_LNKCAP_LW_X4: *link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X4; break; case VXGE_HAL_PCI_EXP_LNKCAP_LW_X8: *link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X8; break; case VXGE_HAL_PCI_EXP_LNKCAP_LW_X12: *link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X12; break; case VXGE_HAL_PCI_EXP_LNKCAP_LW_X16: *link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X16; break; case VXGE_HAL_PCI_EXP_LNKCAP_LW_X32: *link_width = VXGE_HAL_PCI_E_LINK_WIDTH_X32; break; case VXGE_HAL_PCI_EXP_LNKCAP_LW_RES: default: *link_width = VXGE_HAL_PCI_E_LINK_WIDTH_UNKNOWN; break; } vxge_hal_trace_log_device("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); return (status); } /* * __hal_device_hw_initialize * @hldev: HAL device handle. * * Initialize X3100-V hardware. */ vxge_hal_status_e __hal_device_hw_initialize(__hal_device_t *hldev) { vxge_hal_status_e status = VXGE_HAL_OK; vxge_assert(hldev); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("hldev = 0x"VXGE_OS_STXFMT, (ptr_t) hldev); __hal_device_pci_e_init(hldev); /* update the pci mode, frequency, and width */ if (__hal_device_pci_e_info_get(hldev, &hldev->header.signalling_rate, &hldev->header.link_width) != VXGE_HAL_OK) { hldev->header.signalling_rate = VXGE_HAL_PCI_E_SIGNALLING_RATE_UNKNOWN; hldev->header.link_width = VXGE_HAL_PCI_E_LINK_WIDTH_UNKNOWN; /* * FIXME: this cannot happen. * But if it happens we cannot continue just like that */ vxge_hal_err_log_device("unable to get pci info == > %s : %d", __func__, __LINE__); } if (hldev->access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_SRPCIM) { status = __hal_srpcim_initialize(hldev); } if (hldev->access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM) { status = __hal_mrpcim_initialize(hldev); } if (status == VXGE_HAL_OK) { hldev->hw_is_initialized = 1; hldev->header.terminating = 0; } vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * vxge_hal_device_reset - Reset device. * @devh: HAL device handle. * * Soft-reset the device, reset the device stats except reset_cnt. * * * Returns: VXGE_HAL_OK - success. * VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED - Device is not initialized. * VXGE_HAL_ERR_RESET_FAILED - Reset failed. * * See also: vxge_hal_status_e {}. */ vxge_hal_status_e vxge_hal_device_reset(vxge_hal_device_h devh) { u32 i; vxge_hal_status_e status = VXGE_HAL_OK; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if (!hldev->header.is_initialized) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED); return (VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED); } for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpaths_deployed & mBIT(i))) continue; status = vxge_hal_vpath_reset( VXGE_HAL_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i])); if (status != VXGE_HAL_OK) { vxge_hal_err_log_device("vpath %d Reset Failed", i); } } vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * vxge_hal_device_reset_poll - Poll the device for reset complete. * @devh: HAL device handle. * * Poll the device for reset complete * * Returns: VXGE_HAL_OK - success. * VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED - Device is not initialized. * VXGE_HAL_ERR_RESET_FAILED - Reset failed. * * See also: vxge_hal_status_e {}. */ vxge_hal_status_e vxge_hal_device_reset_poll(vxge_hal_device_h devh) { u32 i; vxge_hal_status_e status = VXGE_HAL_OK; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if (!hldev->header.is_initialized) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED); return (VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED); } for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpaths_deployed & mBIT(i))) continue; status = vxge_hal_vpath_reset_poll( VXGE_HAL_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i])); if (status != VXGE_HAL_OK) { vxge_hal_err_log_device("vpath %d Reset Poll Failed", i); } } vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * vxge_hal_device_mrpcim_reset_poll - Poll the device for mrpcim reset complete * @devh: HAL device handle. * * Poll the device for mrpcim reset complete * * Returns: VXGE_HAL_OK - success. * VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED - Device is not initialized. * VXGE_HAL_ERR_RESET_FAILED - Reset failed. * VXGE_HAL_ERR_MANAGER_NOT_FOUND - MRPCIM/SRPCIM manager not found * VXGE_HAL_ERR_TIME_OUT - Device Reset timed out * * See also: vxge_hal_status_e {}. */ vxge_hal_status_e vxge_hal_device_mrpcim_reset_poll(vxge_hal_device_h devh) { u32 i = 0; vxge_hal_status_e status = VXGE_HAL_OK; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if (!hldev->header.is_initialized) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED); return (VXGE_HAL_ERR_DEVICE_NOT_INITIALIZED); } if (!hldev->manager_up) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_MANAGER_NOT_FOUND); return (VXGE_HAL_ERR_MANAGER_NOT_FOUND); } status = __hal_ifmsg_device_reset_end_poll( hldev, hldev->first_vp_id); if (status != VXGE_HAL_OK) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_TIME_OUT); return (VXGE_HAL_ERR_TIME_OUT); } for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpaths_deployed & mBIT(i))) continue; status = vxge_hal_vpath_reset_poll( VXGE_HAL_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i])); if (status != VXGE_HAL_OK) { vxge_hal_err_log_device("vpath %d Reset Poll Failed", i); } } vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * vxge_hal_device_status - Check whether X3100 hardware is ready for * operation. * @devh: HAL device handle. * @hw_status: X3100 status register. Returned by HAL. * * Check whether X3100 hardware is ready for operation. * The checking includes TDMA, RDMA, PFC, PIC, MC_DRAM, and the rest * hardware functional blocks. * * Returns: VXGE_HAL_OK if the device is ready for operation. Otherwise * returns VXGE_HAL_FAIL. Also, fills in adapter status (in @hw_status). * * See also: vxge_hal_status_e {}. * Usage: See ex_open {}. */ vxge_hal_status_e vxge_hal_device_status(vxge_hal_device_h devh, u64 *hw_status) { __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert((hldev != NULL) && (hw_status != NULL)); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); *hw_status = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->common_reg->adapter_status); vxge_hal_trace_log_device("Adapter_Status = 0x"VXGE_OS_LLXFMT, *hw_status); if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_RTDMA_RTDMA_READY)) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_RTDMA_RTDMA_READY); return (VXGE_HAL_ERR_RTDMA_RTDMA_READY); } if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_WRDMA_WRDMA_READY)) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_WRDMA_WRDMA_READY); return (VXGE_HAL_ERR_WRDMA_WRDMA_READY); } if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_KDFC_KDFC_READY)) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_KDFC_KDFC_READY); return (VXGE_HAL_ERR_KDFC_KDFC_READY); } if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_TPA_TMAC_BUF_EMPTY)) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_TPA_TMAC_BUF_EMPTY); return (VXGE_HAL_ERR_TPA_TMAC_BUF_EMPTY); } if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_RDCTL_PIC_QUIESCENT)) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_RDCTL_PIC_QUIESCENT); return (VXGE_HAL_ERR_RDCTL_PIC_QUIESCENT); } if (*hw_status & VXGE_HAL_ADAPTER_STATUS_XGMAC_NETWORK_FAULT) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_XGMAC_NETWORK_FAULT); return (VXGE_HAL_ERR_XGMAC_NETWORK_FAULT); } if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_ROCRC_OFFLOAD_QUIESCENT)) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_ROCRC_OFFLOAD_QUIESCENT); return (VXGE_HAL_ERR_ROCRC_OFFLOAD_QUIESCENT); } if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_G3IF_FB_G3IF_FB_GDDR3_READY)) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_G3IF_FB_G3IF_FB_GDDR3_READY); return (VXGE_HAL_ERR_G3IF_FB_G3IF_FB_GDDR3_READY); } if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_G3IF_CM_G3IF_CM_GDDR3_READY)) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_G3IF_CM_G3IF_CM_GDDR3_READY); return (VXGE_HAL_ERR_G3IF_CM_G3IF_CM_GDDR3_READY); } #ifndef VXGE_HAL_TITAN_EMULATION if (*hw_status & VXGE_HAL_ADAPTER_STATUS_RIC_RIC_RUNNING) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_RIC_RIC_RUNNING); return (VXGE_HAL_ERR_RIC_RIC_RUNNING); } #endif if (*hw_status & VXGE_HAL_ADAPTER_STATUS_CMG_C_PLL_IN_LOCK) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_CMG_C_PLL_IN_LOCK); return (VXGE_HAL_ERR_CMG_C_PLL_IN_LOCK); } if (*hw_status & VXGE_HAL_ADAPTER_STATUS_XGMAC_X_PLL_IN_LOCK) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_XGMAC_X_PLL_IN_LOCK); return (VXGE_HAL_ERR_XGMAC_X_PLL_IN_LOCK); } if (*hw_status & VXGE_HAL_ADAPTER_STATUS_FBIF_M_PLL_IN_LOCK) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_FBIF_M_PLL_IN_LOCK); return (VXGE_HAL_ERR_FBIF_M_PLL_IN_LOCK); } if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_PCC_PCC_IDLE(0xFF))) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_PCC_PCC_IDLE); return (VXGE_HAL_ERR_PCC_PCC_IDLE); } if (!(*hw_status & VXGE_HAL_ADAPTER_STATUS_ROCRC_RC_PRC_QUIESCENT(0xFF))) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_ROCRC_RC_PRC_QUIESCENT); return (VXGE_HAL_ERR_ROCRC_RC_PRC_QUIESCENT); } vxge_hal_trace_log_device("<== %s:%s:%d Result = 0x"VXGE_OS_STXFMT, __FILE__, __func__, __LINE__, (ptr_t) *hw_status); return (VXGE_HAL_OK); } /* * vxge_hal_device_is_slot_freeze * @devh: the device * * Returns non-zero if the slot is freezed. * The determination is made based on the adapter_status * register which will never give all FFs, unless PCI read * cannot go through. */ int vxge_hal_device_is_slot_freeze(vxge_hal_device_h devh) { __hal_device_t *hldev = (__hal_device_t *) devh; u16 device_id; u64 adapter_status; vxge_assert(devh); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); adapter_status = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->common_reg->adapter_status); (void) __hal_vpath_pci_read(hldev, hldev->first_vp_id, vxge_offsetof(vxge_hal_pci_config_le_t, device_id), 2, &device_id); vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, (adapter_status == VXGE_HAL_ALL_FOXES) || (device_id == 0xffff)); return ((adapter_status == VXGE_HAL_ALL_FOXES) || (device_id == 0xffff)); } /* * vxge_hal_device_intr_enable - Enable interrupts. * @devh: HAL device handle. * @op: One of the vxge_hal_device_intr_e enumerated values specifying * the type(s) of interrupts to enable. * * Enable X3100 interrupts. The function is to be executed the last in * X3100 initialization sequence. * * See also: vxge_hal_device_intr_disable() */ void vxge_hal_device_intr_enable( vxge_hal_device_h devh) { u32 i; u64 val64; u32 val32; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(hldev); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); vxge_hal_device_mask_all(hldev); for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpaths_deployed & mBIT(i))) continue; (void) __hal_vpath_intr_enable(&hldev->virtual_paths[i]); } if ((hldev->header.config.intr_mode == VXGE_HAL_INTR_MODE_IRQLINE) || (hldev->header.config.intr_mode == VXGE_HAL_INTR_MODE_EMULATED_INTA)) { val64 = hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] | hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] | hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_BMAP]; if (val64 != 0) { vxge_os_pio_mem_write64(hldev->header.pdev, hldev->header.regh0, val64, &hldev->common_reg->tim_int_status0); vxge_os_pio_mem_write64(hldev->header.pdev, hldev->header.regh0, ~val64, &hldev->common_reg->tim_int_mask0); } val32 = hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] | hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] | hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_BMAP]; if (val32 != 0) { vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, val32, &hldev->common_reg->tim_int_status1); vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, ~val32, &hldev->common_reg->tim_int_mask1); } } vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->common_reg->titan_general_int_status); vxge_hal_device_unmask_all(hldev); vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_intr_disable - Disable X3100 interrupts. * @devh: HAL device handle. * @op: One of the vxge_hal_device_intr_e enumerated values specifying * the type(s) of interrupts to disable. * * Disable X3100 interrupts. * * See also: vxge_hal_device_intr_enable() */ void vxge_hal_device_intr_disable( vxge_hal_device_h devh) { u32 i; u64 val64; u32 val32; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(hldev); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); vxge_hal_device_mask_all(hldev); if ((hldev->header.config.intr_mode == VXGE_HAL_INTR_MODE_IRQLINE) || (hldev->header.config.intr_mode == VXGE_HAL_INTR_MODE_EMULATED_INTA)) { val64 = hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] | hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] | hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_BMAP]; if (val64 != 0) { vxge_os_pio_mem_write64(hldev->header.pdev, hldev->header.regh0, val64, &hldev->common_reg->tim_int_mask0); } val32 = hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] | hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] | hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_BMAP]; if (val32 != 0) { vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, val32, &hldev->common_reg->tim_int_mask1); } } for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpaths_deployed & mBIT(i))) continue; (void) __hal_vpath_intr_disable(&hldev->virtual_paths[i]); } vxge_hal_device_unmask_all(hldev); vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_mask_all - Mask all device interrupts. * @devh: HAL device handle. * * Mask all device interrupts. * * See also: vxge_hal_device_unmask_all() */ void vxge_hal_device_mask_all( vxge_hal_device_h devh) { u64 val64; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(hldev); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); val64 = VXGE_HAL_TITAN_MASK_ALL_INT_ALARM | VXGE_HAL_TITAN_MASK_ALL_INT_TRAFFIC; vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, (u32) bVAL32(val64, 0), &hldev->common_reg->titan_mask_all_int); vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_unmask_all - Unmask all device interrupts. * @devh: HAL device handle. * * Unmask all device interrupts. * * See also: vxge_hal_device_mask_all() */ void vxge_hal_device_unmask_all( vxge_hal_device_h devh) { u64 val64 = 0; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(hldev); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if (hldev->header.config.intr_mode == VXGE_HAL_INTR_MODE_IRQLINE) val64 = VXGE_HAL_TITAN_MASK_ALL_INT_TRAFFIC; vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, (u32) bVAL32(val64, 0), &hldev->common_reg->titan_mask_all_int); vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_begin_irq - Begin IRQ processing. * @devh: HAL device handle. * @skip_alarms: Do not clear the alarms * @reason: "Reason" for the interrupt, the value of X3100's * general_int_status register. * * The function performs two actions, It first checks whether (shared IRQ) the * interrupt was raised by the device. Next, it masks the device interrupts. * * Note: * vxge_hal_device_begin_irq() does not flush MMIO writes through the * bridge. Therefore, two back-to-back interrupts are potentially possible. * It is the responsibility of the ULD to make sure that only one * vxge_hal_device_continue_irq() runs at a time. * * Returns: 0, if the interrupt is not "ours" (note that in this case the * device remain enabled). * Otherwise, vxge_hal_device_begin_irq() returns 64bit general adapter * status. * See also: vxge_hal_device_handle_irq() */ vxge_hal_status_e vxge_hal_device_begin_irq( vxge_hal_device_h devh, u32 skip_alarms, u64 *reason) { u32 i; u64 val64; u64 adapter_status; u64 vpath_mask; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_hal_status_e ret = VXGE_HAL_ERR_WRONG_IRQ; vxge_hal_status_e status; vxge_assert((hldev != NULL) && (reason != NULL)); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq( "devh = 0x"VXGE_OS_STXFMT", skip_alarms = %d, " "reason = 0x"VXGE_OS_STXFMT, (ptr_t) devh, skip_alarms, (ptr_t) reason); val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->common_reg->titan_general_int_status); if (vxge_os_unlikely(!val64)) { /* not Titan interrupt */ *reason = 0; ret = VXGE_HAL_ERR_WRONG_IRQ; vxge_hal_info_log_device_irq("wrong_isr general_int_status = \ 0x%llx", val64); vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, ret); return (ret); } if (vxge_os_unlikely(val64 == VXGE_HAL_ALL_FOXES)) { adapter_status = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->common_reg->adapter_status); if (adapter_status == VXGE_HAL_ALL_FOXES) { vxge_hal_info_log_device_irq("%s:Slot is frozen", __func__); __hal_device_handle_error(hldev, NULL_VPID, VXGE_HAL_EVENT_SLOT_FREEZE); *reason = 0; ret = VXGE_HAL_ERR_SLOT_FREEZE; goto exit; } } *reason = val64; vpath_mask = hldev->vpaths_deployed >> (64 - VXGE_HAL_MAX_VIRTUAL_PATHS); if (val64 & VXGE_HAL_TITAN_GENERAL_INT_STATUS_VPATH_TRAFFIC_INT(vpath_mask)) { hldev->header.traffic_intr_cnt++; ret = VXGE_HAL_TRAFFIC_INTERRUPT; vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, ret); return (ret); } hldev->header.not_traffic_intr_cnt++; if (vxge_os_unlikely(val64 & VXGE_HAL_TITAN_GENERAL_INT_STATUS_VPATH_ALARM_INT)) { for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpaths_deployed & mBIT(i))) continue; status = __hal_vpath_alarm_process( &hldev->virtual_paths[i], skip_alarms); if (status != VXGE_HAL_ERR_WRONG_IRQ) ret = status; } } exit: vxge_hal_trace_log_device_irq( "<==Error in %s:%s:%d result = 0x%x general_int_status= 0x%llx", __FILE__, __func__, __LINE__, ret, val64); return (ret); } /* * vxge_hal_device_continue_irq - Continue handling IRQ: process all * completed descriptors. * @devh: HAL device handle. * * Process completed descriptors and unmask the device interrupts. * * The vxge_hal_device_continue_irq() walks all open virtual paths * and calls upper-layer driver (ULD) via supplied completion * callback. * * Note that the vxge_hal_device_continue_irq is part of the _fast_ path. * To optimize the processing, the function does _not_ check for * errors and alarms. * * Returns: VXGE_HAL_OK. * * See also: vxge_hal_device_handle_irq() * vxge_hal_ring_rxd_next_completed(), * vxge_hal_fifo_txdl_next_completed(), vxge_hal_ring_callback_f {}, * vxge_hal_fifo_callback_f {}. */ vxge_hal_status_e vxge_hal_device_continue_irq( vxge_hal_device_h devh) { u32 i; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(hldev); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpaths_deployed & mBIT(i))) continue; (void) vxge_hal_vpath_continue_irq( VXGE_HAL_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i])); } vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); return (VXGE_HAL_OK); } /* * vxge_hal_device_handle_irq - Handle device IRQ. * @devh: HAL device handle. * @skip_alarms: Do not clear the alarms * * Perform the complete handling of the line interrupt. The function * performs two calls. * First it uses vxge_hal_device_begin_irq() to check the reason for * the interrupt and mask the device interrupts. * Second, it calls vxge_hal_device_continue_irq() to process all * completed descriptors and re-enable the interrupts. * * Returns: VXGE_HAL_OK - success; * VXGE_HAL_ERR_WRONG_IRQ - (shared) IRQ produced by other device. * * See also: vxge_hal_device_begin_irq(), vxge_hal_device_continue_irq(). */ vxge_hal_status_e vxge_hal_device_handle_irq( vxge_hal_device_h devh, u32 skip_alarms) { u64 reason; vxge_hal_status_e status; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh != NULL); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT", \ skip_alarms = %d", (ptr_t) devh, skip_alarms); vxge_hal_device_mask_all(hldev); status = vxge_hal_device_begin_irq(hldev, skip_alarms, &reason); if (vxge_os_unlikely(status == VXGE_HAL_ERR_WRONG_IRQ)) { vxge_hal_device_unmask_all(hldev); goto exit; } if (status == VXGE_HAL_TRAFFIC_INTERRUPT) { vxge_hal_device_clear_rx(hldev); status = vxge_hal_device_continue_irq(hldev); vxge_hal_device_clear_tx(hldev); } if (vxge_os_unlikely((status == VXGE_HAL_ERR_CRITICAL) && skip_alarms)) /* ULD needs to unmask explicitely */ goto exit; vxge_hal_device_unmask_all(hldev); exit: vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * __hal_device_handle_link_up_ind * @hldev: HAL device handle. * * Link up indication handler. The function is invoked by HAL when * X3100 indicates that the link is up for programmable amount of time. */ vxge_hal_status_e __hal_device_handle_link_up_ind(__hal_device_t *hldev) { vxge_assert(hldev); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("hldev = 0x"VXGE_OS_STXFMT, (ptr_t) hldev); /* * If the previous link state is not down, return. */ if (hldev->header.link_state == VXGE_HAL_LINK_UP) { vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); return (VXGE_HAL_OK); } hldev->header.link_state = VXGE_HAL_LINK_UP; /* notify ULD */ if (g_vxge_hal_driver->uld_callbacks.link_up) { g_vxge_hal_driver->uld_callbacks.link_up( hldev, hldev->header.upper_layer_data); } vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); return (VXGE_HAL_OK); } /* * __hal_device_handle_link_down_ind * @hldev: HAL device handle. * * Link down indication handler. The function is invoked by HAL when * X3100 indicates that the link is down. */ vxge_hal_status_e __hal_device_handle_link_down_ind(__hal_device_t *hldev) { vxge_assert(hldev); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("hldev = 0x"VXGE_OS_STXFMT, (ptr_t) hldev); /* * If the previous link state is not down, return. */ if (hldev->header.link_state == VXGE_HAL_LINK_DOWN) { vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); return (VXGE_HAL_OK); } hldev->header.link_state = VXGE_HAL_LINK_DOWN; /* notify ULD */ if (g_vxge_hal_driver->uld_callbacks.link_down) { g_vxge_hal_driver->uld_callbacks.link_down( hldev, hldev->header.upper_layer_data); } vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); return (VXGE_HAL_OK); } /* * vxge_hal_device_link_state_test - Test the link state. * @devh: HAL device handle. * * Test link state. * Returns: link state. */ vxge_hal_device_link_state_e vxge_hal_device_link_state_test( vxge_hal_device_h devh) { u32 i; vxge_hal_device_link_state_e status = VXGE_HAL_LINK_NONE; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(hldev); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpath_assignments & mBIT(i))) continue; status = __hal_vpath_link_state_test(&hldev->virtual_paths[i]); break; } vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * vxge_hal_device_link_state_poll - Poll for the link state. * @devh: HAL device handle. * * Get link state. * Returns: link state. */ vxge_hal_device_link_state_e vxge_hal_device_link_state_poll( vxge_hal_device_h devh) { u32 i; vxge_hal_device_link_state_e link_state = VXGE_HAL_LINK_NONE; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpath_assignments & mBIT(i))) continue; hldev->header.link_state = VXGE_HAL_LINK_NONE; link_state = __hal_vpath_link_state_poll(&hldev->virtual_paths[i]); break; } vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, link_state); return (link_state); } /* * vxge_hal_device_data_rate_poll - Poll for the data rate. * @devh: HAL device handle. * * Get data rate. * Returns: data rate. */ vxge_hal_device_data_rate_e vxge_hal_device_data_rate_poll( vxge_hal_device_h devh) { u32 i; vxge_hal_device_data_rate_e data_rate = VXGE_HAL_DATA_RATE_UNKNOWN; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpaths_deployed & mBIT(i))) continue; data_rate = __hal_vpath_data_rate_poll(&hldev->virtual_paths[i]); break; } vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, data_rate); return (data_rate); } /* * vxge_hal_device_lag_mode_get - Get Current LAG Mode * @devh: HAL device handle. * * Get Current LAG Mode */ vxge_hal_device_lag_mode_e vxge_hal_device_lag_mode_get( vxge_hal_device_h devh) { u32 i; vxge_hal_device_lag_mode_e lag_mode = VXGE_HAL_DEVICE_LAG_MODE_UNKNOWN; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpaths_deployed & mBIT(i))) continue; lag_mode = __hal_vpath_lag_mode_get(&hldev->virtual_paths[i]); break; } vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, lag_mode); return (lag_mode); } /* * __hal_device_handle_error - Handle error * @hldev: HAL device * @vp_id: Vpath Id * @type: Error type. Please see vxge_hal_event_e {} * * Handle error. */ void __hal_device_handle_error( __hal_device_t *hldev, u32 vp_id, vxge_hal_event_e type) { vxge_assert(hldev); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq( "hldev = 0x"VXGE_OS_STXFMT", vp_id = %d, type = %d", (ptr_t) hldev, vp_id, type); switch (type) { default: vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_TYPE); return; case VXGE_HAL_EVENT_UNKNOWN: if (hldev->header.config.dump_on_unknown) { (void) vxge_hal_aux_device_dump(hldev); } break; case VXGE_HAL_EVENT_SERR: if (hldev->header.config.dump_on_serr) { (void) vxge_hal_aux_device_dump(hldev); } break; case VXGE_HAL_EVENT_CRITICAL: case VXGE_HAL_EVENT_SRPCIM_CRITICAL: case VXGE_HAL_EVENT_MRPCIM_CRITICAL: if (hldev->header.config.dump_on_critical) { (void) vxge_hal_aux_device_dump(hldev); } break; case VXGE_HAL_EVENT_ECCERR: if (hldev->header.config.dump_on_eccerr) { (void) vxge_hal_aux_device_dump(hldev); } break; case VXGE_HAL_EVENT_KDFCCTL: break; case VXGE_HAL_EVENT_DEVICE_RESET_START: break; case VXGE_HAL_EVENT_DEVICE_RESET_COMPLETE: break; case VXGE_HAL_EVENT_VPATH_RESET_START: break; case VXGE_HAL_EVENT_VPATH_RESET_COMPLETE: break; case VXGE_HAL_EVENT_SLOT_FREEZE: break; } /* notify ULD */ if (g_vxge_hal_driver->uld_callbacks.crit_err) { g_vxge_hal_driver->uld_callbacks.crit_err( (vxge_hal_device_h) hldev, hldev->header.upper_layer_data, type, vp_id); } vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_mask_tx - Mask Tx interrupts. * @devh: HAL device. * * Mask Tx device interrupts. * * See also: vxge_hal_device_unmask_tx(), vxge_hal_device_mask_rx(), * vxge_hal_device_clear_tx(). */ void vxge_hal_device_mask_tx( vxge_hal_device_h devh) { __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) { vxge_os_pio_mem_write64(hldev->header.pdev, hldev->header.regh0, hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX], &hldev->common_reg->tim_int_mask0); } if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) { vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX], &hldev->common_reg->tim_int_mask1); } vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_clear_tx - Acknowledge (that is, clear) the * condition that has caused the TX interrupt. * @devh: HAL device. * * Acknowledge (that is, clear) the condition that has caused * the Tx interrupt. * See also: vxge_hal_device_begin_irq(), vxge_hal_device_continue_irq(), * vxge_hal_device_clear_rx(), vxge_hal_device_mask_tx(). */ void vxge_hal_device_clear_tx( vxge_hal_device_h devh) { __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) { vxge_os_pio_mem_write64(hldev->header.pdev, hldev->header.regh0, hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX], &hldev->common_reg->tim_int_status0); } if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) { vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX], &hldev->common_reg->tim_int_status1); } vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_unmask_tx - Unmask Tx interrupts. * @devh: HAL device. * * Unmask Tx device interrupts. * * See also: vxge_hal_device_mask_tx(), vxge_hal_device_clear_tx(). */ void vxge_hal_device_unmask_tx( vxge_hal_device_h devh) { __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) { vxge_os_pio_mem_write64(hldev->header.pdev, hldev->header.regh0, ~(hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX]), &hldev->common_reg->tim_int_mask0); } if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) { vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, ~(hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX]), &hldev->common_reg->tim_int_mask1); } vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_mask_rx - Mask Rx interrupts. * @devh: HAL device. * * Mask Rx device interrupts. * * See also: vxge_hal_device_unmask_rx(), vxge_hal_device_mask_tx(), * vxge_hal_device_clear_rx(). */ void vxge_hal_device_mask_rx( vxge_hal_device_h devh) { __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0) { vxge_os_pio_mem_write64(hldev->header.pdev, hldev->header.regh0, hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX], &hldev->common_reg->tim_int_mask0); } if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0) { vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX], &hldev->common_reg->tim_int_mask1); } vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_clear_rx - Acknowledge (that is, clear) the * condition that has caused the RX interrupt. * @devh: HAL device. * * Acknowledge (that is, clear) the condition that has caused * the Rx interrupt. * See also: vxge_hal_device_begin_irq(), vxge_hal_device_continue_irq(), * vxge_hal_device_clear_tx(), vxge_hal_device_mask_rx(). */ void vxge_hal_device_clear_rx( vxge_hal_device_h devh) { __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0) { vxge_os_pio_mem_write64(hldev->header.pdev, hldev->header.regh0, hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX], &hldev->common_reg->tim_int_status0); } if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0) { vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX], &hldev->common_reg->tim_int_status1); } vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_unmask_rx - Unmask Rx interrupts. * @devh: HAL device. * * Unmask Rx device interrupts. * * See also: vxge_hal_device_mask_rx(), vxge_hal_device_clear_rx(). */ void vxge_hal_device_unmask_rx( vxge_hal_device_h devh) { __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0) { vxge_os_pio_mem_write64(hldev->header.pdev, hldev->header.regh0, ~(hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX]), &hldev->common_reg->tim_int_mask0); } if (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0) { vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, ~(hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX]), &hldev->common_reg->tim_int_mask1); } vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_mask_tx_rx - Mask Tx and Rx interrupts. * @devh: HAL device. * * Mask Tx and Rx device interrupts. * * See also: vxge_hal_device_unmask_tx_rx(), vxge_hal_device_clear_tx_rx(). */ void vxge_hal_device_mask_tx_rx( vxge_hal_device_h devh) { __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if ((hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) || (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0)) { vxge_os_pio_mem_write64(hldev->header.pdev, hldev->header.regh0, (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] | hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX]), &hldev->common_reg->tim_int_mask0); } if ((hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) || (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0)) { vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] | hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX]), &hldev->common_reg->tim_int_mask1); } vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_clear_tx_rx - Acknowledge (that is, clear) the * condition that has caused the Tx and RX interrupt. * @devh: HAL device. * * Acknowledge (that is, clear) the condition that has caused * the Tx and Rx interrupt. * See also: vxge_hal_device_begin_irq(), vxge_hal_device_continue_irq(), * vxge_hal_device_mask_tx_rx(), vxge_hal_device_unmask_tx_rx(). */ void vxge_hal_device_clear_tx_rx( vxge_hal_device_h devh) { __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if ((hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) || (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0)) { vxge_os_pio_mem_write64(hldev->header.pdev, hldev->header.regh0, (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] | hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX]), &hldev->common_reg->tim_int_status0); } if ((hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) || (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0)) { vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] | hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX]), &hldev->common_reg->tim_int_status1); } vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_unmask_tx_rx - Unmask Tx and Rx interrupts. * @devh: HAL device. * * Unmask Rx device interrupts. * * See also: vxge_hal_device_mask_tx_rx(), vxge_hal_device_clear_tx_rx(). */ void vxge_hal_device_unmask_tx_rx( vxge_hal_device_h devh) { __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh); vxge_hal_trace_log_device_irq("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device_irq("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if ((hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] != 0) || (hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX] != 0)) { vxge_os_pio_mem_write64(hldev->header.pdev, hldev->header.regh0, ~(hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_TX] | hldev->tim_int_mask0[VXGE_HAL_VPATH_INTR_RX]), &hldev->common_reg->tim_int_mask0); } if ((hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] != 0) || (hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX] != 0)) { vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, ~(hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_TX] | hldev->tim_int_mask1[VXGE_HAL_VPATH_INTR_RX]), &hldev->common_reg->tim_int_mask1); } vxge_hal_trace_log_device_irq("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_hw_info_get - Get the hw information * @pdev: PCI device object. * @regh0: BAR0 mapped memory handle (Solaris), or simply PCI device @pdev * (Linux and the rest.) * @bar0: Address of BAR0 in PCI config * @hw_info: Buffer to return vxge_hal_device_hw_info_t {} structure * * Returns the vpath mask that has the bits set for each vpath allocated * for the driver, FW version information and the first mac addresse for * each vpath */ 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) { u32 i; u64 val64; vxge_hal_legacy_reg_t *legacy_reg; vxge_hal_toc_reg_t *toc_reg; vxge_hal_mrpcim_reg_t *mrpcim_reg; vxge_hal_common_reg_t *common_reg; vxge_hal_vpath_reg_t *vpath_reg; vxge_hal_vpmgmt_reg_t *vpmgmt_reg; vxge_hal_status_e status; vxge_hal_trace_log_driver("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_driver( "pdev = 0x"VXGE_OS_STXFMT", regh0 = 0x"VXGE_OS_STXFMT", " "bar0 = 0x"VXGE_OS_STXFMT", hw_info = 0x"VXGE_OS_STXFMT, (ptr_t) pdev, (ptr_t) regh0, (ptr_t) bar0, (ptr_t) hw_info); vxge_assert((bar0 != NULL) && (hw_info != NULL)); vxge_os_memzero(hw_info, sizeof(vxge_hal_device_hw_info_t)); legacy_reg = (vxge_hal_legacy_reg_t *) vxge_hal_device_get_legacy_reg(pdev, regh0, bar0); status = __hal_legacy_swapper_set(pdev, regh0, legacy_reg); if (status != VXGE_HAL_OK) { vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } val64 = vxge_os_pio_mem_read64(pdev, regh0, &legacy_reg->toc_first_pointer); toc_reg = (vxge_hal_toc_reg_t *) ((void *) (bar0 + val64)); val64 = vxge_os_pio_mem_read64(pdev, regh0, &toc_reg->toc_common_pointer); common_reg = (vxge_hal_common_reg_t *) ((void *) (bar0 + val64)); status = vxge_hal_device_register_poll(pdev, regh0, &common_reg->vpath_rst_in_prog, 0, VXGE_HAL_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(0x1ffff), VXGE_HAL_DEF_DEVICE_POLL_MILLIS); if (status != VXGE_HAL_OK) { vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } hw_info->vpath_mask = vxge_os_pio_mem_read64(pdev, regh0, &common_reg->vpath_assignments); val64 = vxge_os_pio_mem_read64(pdev, regh0, &common_reg->host_type_assignments); hw_info->host_type = (u32) VXGE_HAL_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64); for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!((hw_info->vpath_mask) & mBIT(i))) continue; val64 = vxge_os_pio_mem_read64(pdev, regh0, &toc_reg->toc_vpmgmt_pointer[i]); vpmgmt_reg = (vxge_hal_vpmgmt_reg_t *) ((void *) (bar0 + val64)); val64 = vxge_os_pio_mem_read64(pdev, regh0, &vpmgmt_reg->vpath_to_func_map_cfg1); hw_info->func_id = (u32) VXGE_HAL_VPATH_TO_FUNC_MAP_CFG1_GET_CFG1( val64); if (__hal_device_access_rights_get(hw_info->host_type, hw_info->func_id) & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM) { val64 = vxge_os_pio_mem_read64(pdev, regh0, &toc_reg->toc_mrpcim_pointer); mrpcim_reg = (vxge_hal_mrpcim_reg_t *) ((void *) (bar0 + val64)); vxge_os_pio_mem_write64(pdev, regh0, 0, &mrpcim_reg->xgmac_gen_fw_memo_mask); vxge_os_wmb(); } val64 = vxge_os_pio_mem_read64(pdev, regh0, &toc_reg->toc_vpath_pointer[i]); vpath_reg = (vxge_hal_vpath_reg_t *) ((void *) (bar0 + val64)); (void) __hal_vpath_fw_flash_ver_get(pdev, regh0, i, vpath_reg, &hw_info->fw_version, &hw_info->fw_date, &hw_info->flash_version, &hw_info->flash_date); (void) __hal_vpath_card_info_get(pdev, regh0, i, vpath_reg, hw_info->serial_number, hw_info->part_number, hw_info->product_description); (void) __hal_vpath_pmd_info_get(pdev, regh0, i, vpath_reg, &hw_info->ports, &hw_info->pmd_port0, &hw_info->pmd_port1); hw_info->function_mode = __hal_vpath_pci_func_mode_get(pdev, regh0, i, vpath_reg); break; } for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!((hw_info->vpath_mask) & mBIT(i))) continue; val64 = vxge_os_pio_mem_read64(pdev, regh0, &toc_reg->toc_vpath_pointer[i]); vpath_reg = (vxge_hal_vpath_reg_t *) ((void *) (bar0 + val64)); status = __hal_vpath_hw_addr_get(pdev, regh0, i, vpath_reg, hw_info->mac_addrs[i], hw_info->mac_addr_masks[i]); if (status != VXGE_HAL_OK) { vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } } vxge_hal_trace_log_driver("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); return (VXGE_HAL_OK); } /* * vxge_hal_device_initialize - Initialize X3100 device. * @hldev: HAL device handle. * @attr: pointer to vxge_hal_device_attr_t structure * @device_config: Configuration to be _applied_ to the device, * For the X3100 configuration "knobs" please * refer to vxge_hal_device_config_t and X3100 * User Guide. * * Initialize X3100 device. Note that all the arguments of this public API * are 'IN', including @hldev. Upper-layer driver (ULD) cooperates with * OS to find new X3100 device, locate its PCI and memory spaces. * * When done, the ULD allocates sizeof(__hal_device_t) bytes for HAL * to enable the latter to perform X3100 hardware initialization. * * Returns: VXGE_HAL_OK - success. * VXGE_HAL_ERR_DRIVER_NOT_INITIALIZED - Driver is not initialized. * VXGE_HAL_ERR_BAD_DEVICE_CONFIG - Device configuration params are not * valid. * VXGE_HAL_ERR_OUT_OF_MEMORY - Memory allocation failed. * VXGE_HAL_ERR_BAD_SUBSYSTEM_ID - Device subsystem id is invalid. * VXGE_HAL_ERR_INVALID_MAC_ADDRESS - Device mac address in not valid. * VXGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to retrieve the mac * address within the time(timeout) or TTI/RTI initialization failed. * VXGE_HAL_ERR_SWAPPER_CTRL - Failed to configure swapper control. * * See also: __hal_device_terminate(), vxge_hal_status_e {} * vxge_hal_device_attr_t {}. */ 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) { u32 i; u32 nblocks = 0; __hal_device_t *hldev; vxge_hal_status_e status; vxge_assert((devh != NULL) && (attr != NULL) && (device_config != NULL)); vxge_hal_trace_log_driver("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_driver( "devh = 0x"VXGE_OS_STXFMT", attr = 0x"VXGE_OS_STXFMT", " "device_config = 0x"VXGE_OS_STXFMT, (ptr_t) devh, (ptr_t) attr, (ptr_t) device_config); /* sanity check */ if (g_vxge_hal_driver == NULL || !g_vxge_hal_driver->is_initialized) { vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_DRIVER_NOT_INITIALIZED); return (VXGE_HAL_ERR_DRIVER_NOT_INITIALIZED); } status = __hal_device_config_check(device_config); if (status != VXGE_HAL_OK) { vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } hldev = (__hal_device_t *) vxge_os_malloc(attr->pdev, sizeof(__hal_device_t)); if (hldev == NULL) { vxge_hal_trace_log_driver("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_OUT_OF_MEMORY); return (VXGE_HAL_ERR_OUT_OF_MEMORY); } vxge_os_memzero(hldev, sizeof(__hal_device_t)); hldev->header.magic = VXGE_HAL_DEVICE_MAGIC; __hal_channel_init_pending_list(hldev); vxge_hal_device_debug_set(hldev, device_config->debug_level, device_config->debug_mask); #if defined(VXGE_TRACE_INTO_CIRCULAR_ARR) hldev->trace_buf.size = device_config->tracebuf_size; hldev->trace_buf.data = (u8 *) vxge_os_malloc(attr->pdev, hldev->trace_buf.size); if (hldev->trace_buf.data == NULL) { vxge_os_printf("cannot allocate trace buffer!\n"); return (VXGE_HAL_ERR_OUT_OF_MEMORY); } hldev->trace_buf.offset = 0; hldev->trace_buf.wrapped_count = 0; vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); #endif vxge_hal_info_log_device("device 0x"VXGE_OS_STXFMT" is initializing", (ptr_t) hldev); /* apply config */ vxge_os_memcpy(&hldev->header.config, device_config, sizeof(vxge_hal_device_config_t)); hldev->header.regh0 = attr->regh0; hldev->header.regh1 = attr->regh1; hldev->header.regh2 = attr->regh2; hldev->header.bar0 = attr->bar0; hldev->header.bar1 = attr->bar1; hldev->header.bar2 = attr->bar2; hldev->header.pdev = attr->pdev; hldev->header.irqh = attr->irqh; hldev->header.cfgh = attr->cfgh; if ((status = __hal_device_reg_addr_get(hldev)) != VXGE_HAL_OK) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); vxge_hal_device_terminate(hldev); return (status); } __hal_device_id_get(hldev); __hal_device_host_info_get(hldev); nblocks += 1; /* For MRPCIM stats */ for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpath_assignments & mBIT(i))) continue; if (device_config->vp_config[i].ring.enable == VXGE_HAL_RING_ENABLE) { nblocks += (device_config->vp_config[i].ring.ring_length + vxge_hal_ring_rxds_per_block_get( device_config->vp_config[i].ring.buffer_mode) - 1) / vxge_hal_ring_rxds_per_block_get( device_config->vp_config[i].ring.buffer_mode); } if ((device_config->vp_config[i].fifo.enable == VXGE_HAL_FIFO_ENABLE) && ((device_config->vp_config[i].fifo.max_frags * sizeof(vxge_hal_fifo_txd_t)) <= VXGE_OS_HOST_PAGE_SIZE)) { nblocks += ((device_config->vp_config[i].fifo.fifo_length * sizeof(vxge_hal_fifo_txd_t) * device_config->vp_config[i].fifo.max_frags) + VXGE_OS_HOST_PAGE_SIZE - 1) / VXGE_OS_HOST_PAGE_SIZE; } nblocks += 1; /* For vpath stats */ } if (__hal_blockpool_create(hldev, &hldev->block_pool, device_config->dma_blockpool_initial + nblocks, device_config->dma_blockpool_incr, device_config->dma_blockpool_min, device_config->dma_blockpool_max + nblocks) != VXGE_HAL_OK) { vxge_hal_info_log_device("%s:__hal_blockpool_create failed", __func__); vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_OUT_OF_MEMORY); vxge_hal_device_terminate(hldev); return (VXGE_HAL_ERR_OUT_OF_MEMORY); } status = __hal_device_hw_initialize(hldev); if (status != VXGE_HAL_OK) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); vxge_hal_device_terminate(hldev); return (status); } hldev->dump_buf = (char *) vxge_os_malloc(hldev->header.pdev, VXGE_HAL_DUMP_BUF_SIZE); if (hldev->dump_buf == NULL) { vxge_hal_info_log_device("%s:vxge_os_malloc failed ", __func__); vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_OUT_OF_MEMORY); vxge_hal_device_terminate(hldev); return (VXGE_HAL_ERR_OUT_OF_MEMORY); } hldev->header.is_initialized = 1; *devh = hldev; vxge_hal_trace_log_device("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); return (VXGE_HAL_OK); } /* * vxge_hal_device_terminate - Terminate X3100 device. * @devh: HAL device handle. * * Terminate HAL device. * * See also: vxge_hal_device_initialize(). */ void vxge_hal_device_terminate(vxge_hal_device_h devh) { __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(g_vxge_hal_driver != NULL); vxge_assert(hldev != NULL); vxge_assert(hldev->header.magic == VXGE_HAL_DEVICE_MAGIC); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); hldev->header.terminating = 1; hldev->header.is_initialized = 0; hldev->in_poll = 0; hldev->header.magic = VXGE_HAL_DEVICE_DEAD; if (hldev->dump_buf) { vxge_os_free(hldev->header.pdev, hldev->dump_buf, VXGE_HAL_DUMP_BUF_SIZE); hldev->dump_buf = NULL; } if (hldev->srpcim != NULL) (void) __hal_srpcim_terminate(hldev); if (hldev->mrpcim != NULL) (void) __hal_mrpcim_terminate(hldev); __hal_channel_destroy_pending_list(hldev); __hal_blockpool_destroy(&hldev->block_pool); #if defined(VXGE_TRACE_INTO_CIRCULAR_ARR) if (hldev->trace_buf.size) { vxge_os_free(NULL, hldev->trace_buf.data, hldev->trace_buf.size); } #endif vxge_os_free(hldev->header.pdev, hldev, sizeof(__hal_device_t)); vxge_hal_trace_log_driver("<== %s:%s:%d Result = 0", __FILE__, __func__, __LINE__); } /* * vxge_hal_device_enable - Enable device. * @devh: HAL device handle. * * Enable the specified device: bring up the link/interface. * */ vxge_hal_status_e vxge_hal_device_enable( vxge_hal_device_h devh) { vxge_hal_status_e status = VXGE_HAL_OK; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh != NULL); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); if (!hldev->hw_is_initialized) { status = __hal_device_hw_initialize(hldev); if (status != VXGE_HAL_OK) { vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } } __hal_device_bus_master_enable(hldev); vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * vxge_hal_device_disable - Disable X3100 adapter. * @devh: HAL device handle. * * Disable this device. To gracefully reset the adapter, the host should: * * - call vxge_hal_device_disable(); * * - call vxge_hal_device_intr_disable(); * * - do some work (error recovery, change mtu, reset, etc); * * - call vxge_hal_device_enable(); * * - call vxge_hal_device_intr_enable(). * * Note: Disabling the device does _not_ include disabling of interrupts. * After disabling the device stops receiving new frames but those frames * that were already in the pipe will keep coming for some few milliseconds. * * */ vxge_hal_status_e vxge_hal_device_disable( vxge_hal_device_h devh) { vxge_hal_status_e status = VXGE_HAL_OK; vxge_assert(devh != NULL); #if (VXGE_COMPONENT_HAL_DEVICE & VXGE_DEBUG_MODULE_MASK) __hal_device_t *hldev = (__hal_device_t *) devh; vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); vxge_hal_trace_log_device("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); #endif return (status); } /* * vxge_hal_device_hw_stats_enable - Enable device h/w statistics. * @devh: HAL Device. * * Enable the DMA vpath statistics for the device. The function is to be called * to re-enable the adapter to update stats into the host memory * * See also: vxge_hal_device_hw_stats_disable() */ vxge_hal_status_e vxge_hal_device_hw_stats_enable( vxge_hal_device_h devh) { u32 i; u64 val64; vxge_hal_status_e status = VXGE_HAL_OK; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh != NULL); vxge_hal_trace_log_stats("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_stats("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->common_reg->stats_cfg0); for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpaths_deployed & mBIT(i))) continue; vxge_os_memcpy(hldev->virtual_paths[i].hw_stats_sav, hldev->virtual_paths[i].hw_stats, sizeof(vxge_hal_vpath_stats_hw_info_t)); if (hldev->header.config.stats_read_method == VXGE_HAL_STATS_READ_METHOD_DMA) { val64 |= VXGE_HAL_STATS_CFG0_STATS_ENABLE((1 << (16 - i))); } else { status = __hal_vpath_hw_stats_get( &hldev->virtual_paths[i], hldev->virtual_paths[i].hw_stats); } } vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, (u32) bVAL32(val64, 0), &hldev->common_reg->stats_cfg0); vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * vxge_hal_device_hw_stats_disable - Disable device h/w statistics. * @devh: HAL Device. * * Enable the DMA vpath statistics for the device. The function is to be called * to disable the adapter to update stats into the host memory. This function * is not needed to be called, normally. * * See also: vxge_hal_device_hw_stats_enable() */ vxge_hal_status_e vxge_hal_device_hw_stats_disable( vxge_hal_device_h devh) { u32 i; u64 val64; vxge_hal_status_e status = VXGE_HAL_OK; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh != NULL); vxge_hal_trace_log_stats("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_stats("devh = 0x"VXGE_OS_STXFMT, (ptr_t) devh); val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->common_reg->stats_cfg0); for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpaths_deployed & mBIT(i))) continue; val64 &= ~VXGE_HAL_STATS_CFG0_STATS_ENABLE((1 << (16 - i))); } vxge_hal_pio_mem_write32_upper(hldev->header.pdev, hldev->header.regh0, (u32) bVAL32(val64, 0), &hldev->common_reg->stats_cfg0); vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * vxge_hal_device_hw_stats_get - Get the device hw statistics. * @devh: HAL Device. * @hw_stats: Hardware stats * * Returns the vpath h/w stats for the device. * * See also: vxge_hal_device_hw_stats_enable(), * vxge_hal_device_hw_stats_disable() */ vxge_hal_status_e vxge_hal_device_hw_stats_get( vxge_hal_device_h devh, vxge_hal_device_stats_hw_info_t *hw_stats) { u32 i; u64 val64 = 0; vxge_hal_status_e status = VXGE_HAL_OK; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert((devh != NULL) && (hw_stats != NULL)); vxge_hal_trace_log_stats("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_stats( "devh = 0x"VXGE_OS_STXFMT", hw_stats = 0x"VXGE_OS_STXFMT, (ptr_t) devh, (ptr_t) hw_stats); if (hldev->header.config.stats_read_method == VXGE_HAL_STATS_READ_METHOD_DMA) { for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpaths_deployed & mBIT(i))) continue; val64 |= VXGE_HAL_STATS_CFG0_STATS_ENABLE((1 << (16 - i))); } status = vxge_hal_device_register_poll(hldev->header.pdev, hldev->header.regh0, &hldev->common_reg->stats_cfg0, 0, val64, hldev->header.config.device_poll_millis); } if (status == VXGE_HAL_OK) { vxge_os_memcpy(hw_stats, &hldev->stats.hw_dev_info_stats, sizeof(vxge_hal_device_stats_hw_info_t)); } vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * vxge_hal_device_sw_stats_get - Get the device sw statistics. * @devh: HAL Device. * @sw_stats: Software stats * * Returns the vpath s/w stats for the device. * * See also: vxge_hal_device_hw_stats_get() */ vxge_hal_status_e vxge_hal_device_sw_stats_get( vxge_hal_device_h devh, vxge_hal_device_stats_sw_info_t *sw_stats) { vxge_hal_status_e status = VXGE_HAL_OK; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert((hldev != NULL) && (sw_stats != NULL)); vxge_hal_trace_log_stats("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_stats( "devh = 0x"VXGE_OS_STXFMT", sw_stats = 0x"VXGE_OS_STXFMT, (ptr_t) devh, (ptr_t) sw_stats); vxge_os_memcpy(sw_stats, &hldev->stats.sw_dev_info_stats, sizeof(vxge_hal_device_stats_sw_info_t)); vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * vxge_hal_device_stats_get - Get the device statistics. * @devh: HAL Device. * @stats: Device stats * * Returns the device stats for the device. * * See also: vxge_hal_device_hw_stats_get(), vxge_hal_device_sw_stats_get() */ vxge_hal_status_e vxge_hal_device_stats_get( vxge_hal_device_h devh, vxge_hal_device_stats_t *stats) { vxge_hal_status_e status = VXGE_HAL_OK; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert((hldev != NULL) && (stats != NULL)); vxge_hal_trace_log_stats("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_stats( "devh = 0x"VXGE_OS_STXFMT", stats = 0x"VXGE_OS_STXFMT, (ptr_t) devh, (ptr_t) stats); vxge_os_memcpy(stats, &hldev->stats, sizeof(vxge_hal_device_stats_t)); vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } /* * vxge_hal_device_xmac_stats_get - Get the Device XMAC Statistics * @devh: HAL device handle. * @xmac_stats: Buffer to return XMAC Statistics. * * Get the XMAC Statistics * */ vxge_hal_status_e vxge_hal_device_xmac_stats_get(vxge_hal_device_h devh, vxge_hal_device_xmac_stats_t *xmac_stats) { vxge_hal_status_e status = VXGE_HAL_OK; u32 i; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert((hldev != NULL) && (xmac_stats != NULL)); vxge_hal_trace_log_stats("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_stats( "devh = 0x"VXGE_OS_STXFMT", xmac_stats = 0x"VXGE_OS_STXFMT, (ptr_t) devh, (ptr_t) xmac_stats); for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpaths_deployed & mBIT(i))) continue; status = __hal_vpath_xmac_tx_stats_get(&hldev->virtual_paths[i], &xmac_stats->vpath_tx_stats[i]); if (status != VXGE_HAL_OK) { vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } status = __hal_vpath_xmac_rx_stats_get(&hldev->virtual_paths[i], &xmac_stats->vpath_rx_stats[i]); if (status != VXGE_HAL_OK) { vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } } vxge_hal_trace_log_stats("<== %s:%s:%d Result = %d", __FILE__, __func__, __LINE__, status); return (status); } #if defined(VXGE_TRACE_INTO_CIRCULAR_ARR) /* * vxge_hal_device_trace_write - Write the trace from the given buffer into * circular trace buffer * @devh: HAL device handle. * @trace_buf: Buffer containing the trace. * @trace_len: Length of the trace in the buffer * * Writes the trace from the given buffer into the circular trace buffer * */ void vxge_hal_device_trace_write(vxge_hal_device_h devh, u8 *trace_buf, u32 trace_len) { __hal_device_t *hldev = (__hal_device_t *) devh; u32 offset; if (hldev == NULL) return; offset = hldev->trace_buf.offset; if (trace_len > 1) { u32 leftsize = hldev->trace_buf.size - offset; if (trace_len > leftsize) { vxge_os_memzero(hldev->trace_buf.data + offset, leftsize); offset = 0; hldev->trace_buf.wrapped_count++; } vxge_os_memcpy(hldev->trace_buf.data + offset, trace_buf, trace_len); offset += trace_len; hldev->trace_buf.offset = offset; } } /* * vxge_hal_device_trace_dump - Dump the trace buffer. * @devh: HAL device handle. * * Dump the trace buffer contents. */ void vxge_hal_device_trace_dump(vxge_hal_device_h devh) { __hal_device_t *hldev = (__hal_device_t *) devh; u32 offset, i = 0; if (hldev == NULL) return; offset = hldev->trace_buf.offset; vxge_os_printf("################ Trace dump Begin ###############\n"); if (hldev->trace_buf.wrapped_count) { for (i = hldev->trace_buf.offset; i < hldev->trace_buf.size; i += offset) { if (*(hldev->trace_buf.data + i)) vxge_os_printf(hldev->trace_buf.data + i); offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1; } } for (i = 0; i < hldev->trace_buf.offset; i += offset) { if (*(hldev->trace_buf.data + i)) vxge_os_printf(hldev->trace_buf.data + i); offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1; } vxge_os_printf("################ Trace dump End ###############\n"); } /* * vxge_hal_device_trace_read - Read trace buffer contents. * @devh: HAL device handle. * @buffer: Buffer to store the trace buffer contents. * @buf_size: Size of the buffer. * @read_length: Size of the valid data in the buffer. * * Read HAL trace buffer contents starting from the offset * upto the size of the buffer or till EOF is reached. * * Returns: VXGE_HAL_OK - success. * VXGE_HAL_EOF_TRACE_BUF - No more data in the trace buffer. * */ vxge_hal_status_e vxge_hal_device_trace_read(vxge_hal_device_h devh, char *buffer, unsigned buf_size, unsigned *read_length) { __hal_device_t *hldev = (__hal_device_t *) devh; u32 offset, i = 0, buf_off = 0; *read_length = 0; *buffer = 0; if (hldev == NULL) return (VXGE_HAL_FAIL); offset = hldev->trace_buf.offset; if (hldev->trace_buf.wrapped_count) { for (i = hldev->trace_buf.offset; i < hldev->trace_buf.size; i += offset) { if (*(hldev->trace_buf.data + i)) { vxge_os_sprintf(buffer + buf_off, "%s\n", hldev->trace_buf.data + i); buf_off += vxge_os_strlen( hldev->trace_buf.data + i) + 1; if (buf_off > buf_size) return (VXGE_HAL_ERR_OUT_OF_MEMORY); } offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1; } } for (i = 0; i < hldev->trace_buf.offset; i += offset) { if (*(hldev->trace_buf.data + i)) { vxge_os_sprintf(buffer + buf_off, "%s\n", hldev->trace_buf.data + i); buf_off += vxge_os_strlen( hldev->trace_buf.data + i) + 1; if (buf_off > buf_size) return (VXGE_HAL_ERR_OUT_OF_MEMORY); } offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1; } *read_length = buf_off; *(buffer + buf_off + 1) = 0; return (VXGE_HAL_OK); } #endif /* * vxge_hal_device_debug_set - Set the debug module, level and timestamp * @devh: Hal device object * @level: Debug level as defined in enum vxge_debug_level_e * @module masks: An or value of component masks as defined in vxge_debug.h * * This routine is used to dynamically change the debug output */ void vxge_hal_device_debug_set( vxge_hal_device_h devh, vxge_debug_level_e level, u32 mask) { __hal_device_t *hldev = (__hal_device_t *) devh; hldev->header.debug_module_mask = mask; hldev->header.debug_level = level; hldev->d_trace_mask = 0; hldev->d_info_mask = 0; hldev->d_err_mask = 0; switch (level) { case VXGE_TRACE: hldev->d_trace_mask = mask; /* FALLTHROUGH */ case VXGE_INFO: hldev->d_info_mask = mask; /* FALLTHROUGH */ case VXGE_ERR: hldev->d_err_mask = mask; /* FALLTHROUGH */ default: break; } } /* * vxge_hal_device_flick_link_led - Flick (blink) link LED. * @devh: HAL device handle. * @port : Port number 0, or 1 * @on_off: TRUE if flickering to be on, FALSE to be off * * Flicker the link LED. */ vxge_hal_status_e vxge_hal_device_flick_link_led(vxge_hal_device_h devh, u32 port, u32 on_off) { vxge_hal_status_e status; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh != NULL); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT ", port = %d, on_off = %d", (ptr_t) devh, port, on_off); if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) { vxge_hal_trace_log_device("<== %s:%s:%d Result: %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_DEVICE); return (VXGE_HAL_ERR_INVALID_DEVICE); } status = __hal_vpath_flick_link_led(hldev, hldev->first_vp_id, port, on_off); vxge_hal_trace_log_device("<== %s:%s:%d Result: %d", __FILE__, __func__, __LINE__, status); return (status); } /* * vxge_hal_device_getpause_data -Pause frame frame generation and reception. * @devh: HAL device handle. * @port : Port number 0, 1, or 2 * @tx : A field to return the pause generation capability of the NIC. * @rx : A field to return the pause reception capability of the NIC. * * Returns the Pause frame generation and reception capability of the NIC. * Return value: * status */ vxge_hal_status_e vxge_hal_device_getpause_data( vxge_hal_device_h devh, u32 port, u32 *tx, u32 *rx) { u32 i; u64 val64; vxge_hal_status_e status = VXGE_HAL_ERR_VPATH_NOT_AVAILABLE; __hal_device_t *hldev = (__hal_device_t *) devh; vxge_assert(devh != NULL); vxge_hal_trace_log_device("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT", " "port = %d, tx = 0x"VXGE_OS_STXFMT", " "rx = 0x"VXGE_OS_STXFMT, (ptr_t) devh, port, (ptr_t) tx, (ptr_t) rx); if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) { vxge_hal_trace_log_device("<== %s:%s:%d Result: %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_DEVICE); return (VXGE_HAL_ERR_INVALID_DEVICE); } if (port >= VXGE_HAL_MAC_MAX_PORTS) { vxge_hal_trace_log_device("<== %s:%s:%d Result: %d", __FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_PORT); return (VXGE_HAL_ERR_INVALID_PORT); } for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { if (!(hldev->vpath_assignments & mBIT(i))) continue; val64 = vxge_os_pio_mem_read64(hldev->header.pdev, hldev->header.regh0, &hldev->vpmgmt_reg[i]-> rxmac_pause_cfg_port_vpmgmt_clone[port]); if (val64 & VXGE_HAL_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_GEN_EN) *tx = 1; if (val64 & VXGE_HAL_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_RCV_EN) *rx = 1; status = VXGE_HAL_OK; break; } vxge_hal_trace_log_device("<== %s:%s:%d Result: %d", __FILE__, __func__, __LINE__, status); return (status); } vxge_hal_status_e vxge_hal_device_is_privileged(u32 host_type, u32 func_id) { u32 access_rights; vxge_hal_status_e status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION; access_rights = __hal_device_access_rights_get(host_type, func_id); if (access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM) status = VXGE_HAL_OK; return (status); }