mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Mainly focus on files that use BSD 3-Clause license. The Software Package Data Exchange (SPDX) group provides a specification to make it easier for automated tools to detect and summarize well known opensource licenses. We are gradually adopting the specification, noting that the tags are considered only advisory and do not, in any way, superceed or replace the license texts. Special thanks to Wind River for providing access to "The Duke of Highlander" tool: an older (2014) run over FreeBSD tree was useful as a starting point.
3622 lines
95 KiB
C
3622 lines
95 KiB
C
/*-
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*
|
|
* 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 <dev/vxge/vxgehal/vxgehal.h>
|
|
|
|
/*
|
|
* 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
|
|
* up to 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);
|
|
}
|