548d35fd69
Features: Jumbo frames (up to 9600), LRO (Large Receive Offload), TSO (TCP segmentation offload), RTH (Receive Traffic Hash). Submitted by: Sriram Rapuru at Exar MFC after: 2 weeks
3621 lines
95 KiB
C
3621 lines
95 KiB
C
/*-
|
|
* 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
|
|
* upto the size of the buffer or till EOF is reached.
|
|
*
|
|
* Returns: VXGE_HAL_OK - success.
|
|
* VXGE_HAL_EOF_TRACE_BUF - No more data in the trace buffer.
|
|
*
|
|
*/
|
|
vxge_hal_status_e
|
|
vxge_hal_device_trace_read(vxge_hal_device_h devh,
|
|
char *buffer,
|
|
unsigned buf_size,
|
|
unsigned *read_length)
|
|
{
|
|
__hal_device_t *hldev = (__hal_device_t *) devh;
|
|
u32 offset, i = 0, buf_off = 0;
|
|
|
|
*read_length = 0;
|
|
*buffer = 0;
|
|
|
|
if (hldev == NULL)
|
|
return (VXGE_HAL_FAIL);
|
|
|
|
offset = hldev->trace_buf.offset;
|
|
|
|
if (hldev->trace_buf.wrapped_count) {
|
|
for (i = hldev->trace_buf.offset;
|
|
i < hldev->trace_buf.size; i += offset) {
|
|
if (*(hldev->trace_buf.data + i)) {
|
|
vxge_os_sprintf(buffer + buf_off, "%s\n",
|
|
hldev->trace_buf.data + i);
|
|
buf_off += vxge_os_strlen(
|
|
hldev->trace_buf.data + i) + 1;
|
|
if (buf_off > buf_size)
|
|
return (VXGE_HAL_ERR_OUT_OF_MEMORY);
|
|
}
|
|
offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < hldev->trace_buf.offset; i += offset) {
|
|
if (*(hldev->trace_buf.data + i)) {
|
|
vxge_os_sprintf(buffer + buf_off, "%s\n",
|
|
hldev->trace_buf.data + i);
|
|
buf_off += vxge_os_strlen(
|
|
hldev->trace_buf.data + i) + 1;
|
|
if (buf_off > buf_size)
|
|
return (VXGE_HAL_ERR_OUT_OF_MEMORY);
|
|
}
|
|
offset = vxge_os_strlen(hldev->trace_buf.data + i) + 1;
|
|
}
|
|
|
|
*read_length = buf_off;
|
|
*(buffer + buf_off + 1) = 0;
|
|
|
|
return (VXGE_HAL_OK);
|
|
}
|
|
|
|
#endif
|
|
|
|
/*
|
|
* vxge_hal_device_debug_set - Set the debug module, level and timestamp
|
|
* @devh: Hal device object
|
|
* @level: Debug level as defined in enum vxge_debug_level_e
|
|
* @module masks: An or value of component masks as defined in vxge_debug.h
|
|
*
|
|
* This routine is used to dynamically change the debug output
|
|
*/
|
|
void
|
|
vxge_hal_device_debug_set(
|
|
vxge_hal_device_h devh,
|
|
vxge_debug_level_e level,
|
|
u32 mask)
|
|
{
|
|
__hal_device_t *hldev = (__hal_device_t *) devh;
|
|
|
|
hldev->header.debug_module_mask = mask;
|
|
hldev->header.debug_level = level;
|
|
|
|
hldev->d_trace_mask = 0;
|
|
hldev->d_info_mask = 0;
|
|
hldev->d_err_mask = 0;
|
|
|
|
switch (level) {
|
|
case VXGE_TRACE:
|
|
hldev->d_trace_mask = mask;
|
|
/* FALLTHROUGH */
|
|
|
|
case VXGE_INFO:
|
|
hldev->d_info_mask = mask;
|
|
/* FALLTHROUGH */
|
|
|
|
case VXGE_ERR:
|
|
hldev->d_err_mask = mask;
|
|
/* FALLTHROUGH */
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* vxge_hal_device_flick_link_led - Flick (blink) link LED.
|
|
* @devh: HAL device handle.
|
|
* @port : Port number 0, or 1
|
|
* @on_off: TRUE if flickering to be on, FALSE to be off
|
|
*
|
|
* Flicker the link LED.
|
|
*/
|
|
vxge_hal_status_e
|
|
vxge_hal_device_flick_link_led(vxge_hal_device_h devh, u32 port, u32 on_off)
|
|
{
|
|
vxge_hal_status_e status;
|
|
__hal_device_t *hldev = (__hal_device_t *) devh;
|
|
|
|
vxge_assert(devh != NULL);
|
|
|
|
vxge_hal_trace_log_device("==> %s:%s:%d",
|
|
__FILE__, __func__, __LINE__);
|
|
|
|
vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT
|
|
", port = %d, on_off = %d", (ptr_t) devh, port, on_off);
|
|
|
|
if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
|
|
vxge_hal_trace_log_device("<== %s:%s:%d Result: %d",
|
|
__FILE__, __func__, __LINE__,
|
|
VXGE_HAL_ERR_INVALID_DEVICE);
|
|
|
|
return (VXGE_HAL_ERR_INVALID_DEVICE);
|
|
}
|
|
|
|
status = __hal_vpath_flick_link_led(hldev,
|
|
hldev->first_vp_id, port, on_off);
|
|
|
|
vxge_hal_trace_log_device("<== %s:%s:%d Result: %d",
|
|
__FILE__, __func__, __LINE__, status);
|
|
|
|
return (status);
|
|
}
|
|
|
|
/*
|
|
* vxge_hal_device_getpause_data -Pause frame frame generation and reception.
|
|
* @devh: HAL device handle.
|
|
* @port : Port number 0, 1, or 2
|
|
* @tx : A field to return the pause generation capability of the NIC.
|
|
* @rx : A field to return the pause reception capability of the NIC.
|
|
*
|
|
* Returns the Pause frame generation and reception capability of the NIC.
|
|
* Return value:
|
|
* status
|
|
*/
|
|
vxge_hal_status_e
|
|
vxge_hal_device_getpause_data(
|
|
vxge_hal_device_h devh,
|
|
u32 port,
|
|
u32 *tx,
|
|
u32 *rx)
|
|
{
|
|
u32 i;
|
|
u64 val64;
|
|
vxge_hal_status_e status = VXGE_HAL_ERR_VPATH_NOT_AVAILABLE;
|
|
__hal_device_t *hldev = (__hal_device_t *) devh;
|
|
|
|
vxge_assert(devh != NULL);
|
|
|
|
vxge_hal_trace_log_device("==> %s:%s:%d",
|
|
__FILE__, __func__, __LINE__);
|
|
|
|
vxge_hal_trace_log_device("devh = 0x"VXGE_OS_STXFMT", "
|
|
"port = %d, tx = 0x"VXGE_OS_STXFMT", "
|
|
"rx = 0x"VXGE_OS_STXFMT, (ptr_t) devh, port, (ptr_t) tx,
|
|
(ptr_t) rx);
|
|
|
|
if (hldev->header.magic != VXGE_HAL_DEVICE_MAGIC) {
|
|
vxge_hal_trace_log_device("<== %s:%s:%d Result: %d",
|
|
__FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_DEVICE);
|
|
return (VXGE_HAL_ERR_INVALID_DEVICE);
|
|
}
|
|
|
|
if (port >= VXGE_HAL_MAC_MAX_PORTS) {
|
|
vxge_hal_trace_log_device("<== %s:%s:%d Result: %d",
|
|
__FILE__, __func__, __LINE__, VXGE_HAL_ERR_INVALID_PORT);
|
|
return (VXGE_HAL_ERR_INVALID_PORT);
|
|
}
|
|
|
|
for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) {
|
|
|
|
if (!(hldev->vpath_assignments & mBIT(i)))
|
|
continue;
|
|
|
|
val64 = vxge_os_pio_mem_read64(hldev->header.pdev,
|
|
hldev->header.regh0,
|
|
&hldev->vpmgmt_reg[i]->
|
|
rxmac_pause_cfg_port_vpmgmt_clone[port]);
|
|
|
|
if (val64 & VXGE_HAL_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_GEN_EN)
|
|
*tx = 1;
|
|
|
|
if (val64 & VXGE_HAL_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_RCV_EN)
|
|
*rx = 1;
|
|
|
|
status = VXGE_HAL_OK;
|
|
|
|
break;
|
|
}
|
|
|
|
vxge_hal_trace_log_device("<== %s:%s:%d Result: %d",
|
|
__FILE__, __func__, __LINE__, status);
|
|
|
|
return (status);
|
|
}
|
|
|
|
vxge_hal_status_e
|
|
vxge_hal_device_is_privileged(u32 host_type, u32 func_id)
|
|
{
|
|
u32 access_rights;
|
|
vxge_hal_status_e status = VXGE_HAL_ERR_PRIVILAGED_OPEARATION;
|
|
|
|
access_rights = __hal_device_access_rights_get(host_type, func_id);
|
|
|
|
if (access_rights & VXGE_HAL_DEVICE_ACCESS_RIGHT_MRPCIM)
|
|
status = VXGE_HAL_OK;
|
|
|
|
return (status);
|
|
}
|