xgehal-device.c revision a23fd118e437af0a7877dd313db8fdaa3537c675
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * CDDL HEADER START
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * The contents of this file are subject to the terms of the
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Common Development and Distribution License (the "License").
a23fd118e437af0a7877dd313db8fdaa3537c675yl * You may not use this file except in compliance with the License.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
a23fd118e437af0a7877dd313db8fdaa3537c675yl * or http://www.opensolaris.org/os/licensing.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See the License for the specific language governing permissions
a23fd118e437af0a7877dd313db8fdaa3537c675yl * and limitations under the License.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * When distributing Covered Code, include this CDDL HEADER in each
a23fd118e437af0a7877dd313db8fdaa3537c675yl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * If applicable, add the following below this CDDL HEADER, with the
a23fd118e437af0a7877dd313db8fdaa3537c675yl * fields enclosed by brackets "[]" replaced with your own identifying
a23fd118e437af0a7877dd313db8fdaa3537c675yl * information: Portions Copyright [yyyy] [name of copyright owner]
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * CDDL HEADER END
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Copyright (c) 2002-2005 Neterion, Inc.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * All right Reserved.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * FileName : xgehal-device.c
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Description: HAL device object functionality
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Created: 10 May 2004
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#include "xgehal-device.h"
a23fd118e437af0a7877dd313db8fdaa3537c675yl#include "xgehal-channel.h"
a23fd118e437af0a7877dd313db8fdaa3537c675yl#include "xgehal-fifo.h"
a23fd118e437af0a7877dd313db8fdaa3537c675yl#include "xgehal-ring.h"
a23fd118e437af0a7877dd313db8fdaa3537c675yl#include "xgehal-driver.h"
a23fd118e437af0a7877dd313db8fdaa3537c675yl#include "xgehal-mgmt.h"
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#define SWITCH_SIGN 0xA5A5A5A5A5A5A5A5ULL
a23fd118e437af0a7877dd313db8fdaa3537c675yl#define END_SIGN 0x0
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_HERC_EMULATION
a23fd118e437af0a7877dd313db8fdaa3537c675yl#undef XGE_HAL_PROCESS_LINK_INT_IN_ISR
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Jenkins hash key length(in bytes)
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl#define XGE_HAL_JHASH_MSG_LEN 50
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * mix(a,b,c) used in Jenkins hash algorithm
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl#define mix(a,b,c) { \
a23fd118e437af0a7877dd313db8fdaa3537c675yl a -= b; a -= c; a ^= (c>>13); \
a23fd118e437af0a7877dd313db8fdaa3537c675yl b -= c; b -= a; b ^= (a<<8); \
a23fd118e437af0a7877dd313db8fdaa3537c675yl c -= a; c -= b; c ^= (b>>13); \
a23fd118e437af0a7877dd313db8fdaa3537c675yl a -= b; a -= c; a ^= (c>>12); \
a23fd118e437af0a7877dd313db8fdaa3537c675yl b -= c; b -= a; b ^= (a<<16); \
a23fd118e437af0a7877dd313db8fdaa3537c675yl c -= a; c -= b; c ^= (b>>5); \
a23fd118e437af0a7877dd313db8fdaa3537c675yl a -= b; a -= c; a ^= (c>>3); \
a23fd118e437af0a7877dd313db8fdaa3537c675yl b -= c; b -= a; b ^= (a<<10); \
a23fd118e437af0a7877dd313db8fdaa3537c675yl c -= a; c -= b; c ^= (b>>15); \
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675ylextern xge_hal_driver_t *g_xge_hal_driver;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_event_queued
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @data: pointer to xge_hal_device_t structure
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Will be called when new event succesfully queued.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_event_queued(void *data, int event_type)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(((xge_hal_device_t*)data)->magic == XGE_HAL_MAGIC);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (g_xge_hal_driver->uld_callbacks.event_queued) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->uld_callbacks.event_queued(data, event_type);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_pio_mem_write32_upper
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Endiann-aware implementation of xge_os_pio_mem_write32().
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Since Xframe has 64bit registers, we differintiate uppper and lower
a23fd118e437af0a7877dd313db8fdaa3537c675yl * parts.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_pio_mem_write32_upper(pci_dev_h pdev, pci_reg_h regh, u32 val, void *addr)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_OS_HOST_BIG_ENDIAN) && !defined(XGE_OS_PIO_LITTLE_ENDIAN)
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write32(pdev, regh, val, addr);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#else
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write32(pdev, regh, val, (void *)((char *)addr + 4));
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_pio_mem_write32_upper
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Endiann-aware implementation of xge_os_pio_mem_write32().
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Since Xframe has 64bit registers, we differintiate uppper and lower
a23fd118e437af0a7877dd313db8fdaa3537c675yl * parts.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_pio_mem_write32_lower(pci_dev_h pdev, pci_reg_h regh, u32 val,
a23fd118e437af0a7877dd313db8fdaa3537c675yl void *addr)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_OS_HOST_BIG_ENDIAN) && !defined(XGE_OS_PIO_LITTLE_ENDIAN)
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write32(pdev, regh, val,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void *) ((char *)addr + 4));
a23fd118e437af0a7877dd313db8fdaa3537c675yl#else
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write32(pdev, regh, val, addr);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_register_poll
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: pointer to xge_hal_device_t structure
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @reg: register to poll for
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @op: 0 - bit reset, 1 - bit set
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @mask: mask for logical "and" condition based on %op
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @max_millis: maximum time to try to poll in milliseconds
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Will poll certain register for specified amount of time.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Will poll until masked bit is not cleared.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_register_poll(xge_hal_device_t *hldev, u64 *reg,
a23fd118e437af0a7877dd313db8fdaa3537c675yl int op, u64 mask, int max_millis)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e ret = XGE_HAL_FAIL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl do {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_udelay(1000);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (op == 0 && !(val64 & mask)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl ret = XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else if (op == 1 && (val64 & mask) == mask) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl ret = XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } while (++i <= max_millis);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return ret;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_wait_quiescent
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: the device
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hw_status: hw_status in case of error
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Will wait until device is quiescent for some blocks.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic xge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_wait_quiescent(xge_hal_device_t *hldev, u64 *hw_status)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* poll and wait first */
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_HERC_EMULATION
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) __hal_device_register_poll(hldev, &bar0->adapter_status, 1,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (XGE_HAL_ADAPTER_STATUS_TDMA_READY |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_RDMA_READY |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_PFC_READY |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_TMAC_BUF_EMPTY |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_PIC_QUIESCENT |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_MC_DRAM_READY |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_MC_QUEUES_READY |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_M_PLL_LOCK),
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_QUIESCENT_WAIT_MAX_MILLIS);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#else
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) __hal_device_register_poll(hldev, &bar0->adapter_status, 1,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (XGE_HAL_ADAPTER_STATUS_TDMA_READY |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_RDMA_READY |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_PFC_READY |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_TMAC_BUF_EMPTY |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_PIC_QUIESCENT |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_MC_DRAM_READY |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_MC_QUEUES_READY |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_M_PLL_LOCK |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_P_PLL_LOCK),
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_QUIESCENT_WAIT_MAX_MILLIS);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return xge_hal_device_status(hldev, hw_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_is_slot_freeze
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: the device
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns non-zero if the slot is freezed.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * The determination is made based on the adapter_status
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register which will never give all FFs, unless PCI read
a23fd118e437af0a7877dd313db8fdaa3537c675yl * cannot go through.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylint
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_is_slot_freeze(xge_hal_device_h devh)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 device_id;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 adapter_status =
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->pif_rd_swapper_fb);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev,hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, device_id),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &device_id);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef TX_DEBUG
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (adapter_status == XGE_HAL_ALL_FOXES &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 == XGE_HAL_ALL_FOXES)
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 dummy;
a23fd118e437af0a7877dd313db8fdaa3537c675yl dummy = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->pcc_enable);
a23fd118e437af0a7877dd313db8fdaa3537c675yl printf(">>> Slot is frozen!\n");
a23fd118e437af0a7877dd313db8fdaa3537c675yl brkpoint(0);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl return ((adapter_status == XGE_HAL_ALL_FOXES &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 == XGE_HAL_ALL_FOXES) || (device_id == 0xffff));
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_led_actifity_fix
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: pointer to xge_hal_device_t structure
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * SXE-002: Configure link and activity LED to turn it off
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_led_actifity_fix(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 subid;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, subsystem_id), &subid);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * In the case of Herc, there is a new register named beacon control
a23fd118e437af0a7877dd313db8fdaa3537c675yl * is added which was not present in Xena.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Beacon control register in Herc is at the same offset as
a23fd118e437af0a7877dd313db8fdaa3537c675yl * gpio control register in Xena. It means they are one and same in
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the case of Xena. Also, gpio control register offset in Herc and
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Xena is different.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * The current register map represents Herc(It means we have
a23fd118e437af0a7877dd313db8fdaa3537c675yl * both beacon and gpio control registers in register map).
a23fd118e437af0a7877dd313db8fdaa3537c675yl * WRT transition from Xena to Herc, all the code in Xena which was
a23fd118e437af0a7877dd313db8fdaa3537c675yl * using gpio control register for LED handling would have to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * use beacon control register in Herc and the rest of the code
a23fd118e437af0a7877dd313db8fdaa3537c675yl * which uses gpio control in Xena would use the same register
a23fd118e437af0a7877dd313db8fdaa3537c675yl * in Herc.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * WRT LED handling(following code), In the case of Herc, beacon
a23fd118e437af0a7877dd313db8fdaa3537c675yl * control register has to be used. This is applicable for Xena also,
a23fd118e437af0a7877dd313db8fdaa3537c675yl * since it represents the gpio control register in Xena.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((subid & 0xFF) >= 0x07) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->beacon_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= 0x0000800000000000ULL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->beacon_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = 0x0411040400000000ULL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void *) ((u8 *)bar0 + 0x2700));
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/* Constants for Fixing the MacAddress problem seen mostly on
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Alpha machines.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic u64 xena_fix_mac[] = {
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0060000000000000ULL, 0x0060600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0040600000000000ULL, 0x0000600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0020600000000000ULL, 0x0060600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0020600000000000ULL, 0x0060600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0020600000000000ULL, 0x0060600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0020600000000000ULL, 0x0060600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0020600000000000ULL, 0x0060600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0020600000000000ULL, 0x0060600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0020600000000000ULL, 0x0060600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0020600000000000ULL, 0x0060600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0020600000000000ULL, 0x0060600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0020600000000000ULL, 0x0060600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0020600000000000ULL, 0x0000600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0040600000000000ULL, 0x0060600000000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl END_SIGN
a23fd118e437af0a7877dd313db8fdaa3537c675yl};
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_fix_mac
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Fix for all "FFs" MAC address problems observed on Alpha platforms.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_xena_fix_mac(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * In the case of Herc, there is a new register named beacon control
a23fd118e437af0a7877dd313db8fdaa3537c675yl * is added which was not present in Xena.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Beacon control register in Herc is at the same offset as
a23fd118e437af0a7877dd313db8fdaa3537c675yl * gpio control register in Xena. It means they are one and same in
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the case of Xena. Also, gpio control register offset in Herc and
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Xena is different.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * The current register map represents Herc(It means we have
a23fd118e437af0a7877dd313db8fdaa3537c675yl * both beacon and gpio control registers in register map).
a23fd118e437af0a7877dd313db8fdaa3537c675yl * WRT transition from Xena to Herc, all the code in Xena which was
a23fd118e437af0a7877dd313db8fdaa3537c675yl * using gpio control register for LED handling would have to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * use beacon control register in Herc and the rest of the code
a23fd118e437af0a7877dd313db8fdaa3537c675yl * which uses gpio control in Xena would use the same register
a23fd118e437af0a7877dd313db8fdaa3537c675yl * in Herc.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * In the following code(xena_fix_mac), beacon control register has
a23fd118e437af0a7877dd313db8fdaa3537c675yl * to be used in the case of Xena, since it represents gpio control
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register. In the case of Herc, there is no change required.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl while (xena_fix_mac[i] != END_SIGN) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xena_fix_mac[i++], &bar0->beacon_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_bcast_enable
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Enable receiving broadcasts.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * The host must first write RMAC_CFG_KEY "key"
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register, and then - MAC_CFG register.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_bcast_enable(xge_hal_device_h devh)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mac_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_MAC_RMAC_BCAST_ENABLE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u32)(val64 >> 32), &bar0->mac_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "mac_cfg 0x%llx: broadcast %s",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.mac.rmac_bcast_en ? "enabled" : "disabled");
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_bcast_disable
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Disable receiving broadcasts.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * The host must first write RMAC_CFG_KEY "key"
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register, and then - MAC_CFG register.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_bcast_disable(xge_hal_device_h devh)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mac_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~(XGE_HAL_MAC_RMAC_BCAST_ENABLE);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u32)(val64 >> 32), &bar0->mac_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "mac_cfg 0x%llx: broadcast %s",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.mac.rmac_bcast_en ? "enabled" : "disabled");
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_shared_splits_configure
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * TxDMA will stop Read request if the number of read split had exceeded
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the limit set by shared_splits
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_shared_splits_configure(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->pic_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |=
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PIC_CNTL_SHARED_SPLITS(hldev->config.shared_splits);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->pic_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "shared splits configured");
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_rmac_padding_configure
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Configure RMAC frame padding. Depends on configuration, it
a23fd118e437af0a7877dd313db8fdaa3537c675yl * can be send to host or removed by MAC.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_rmac_padding_configure(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mac_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ( ~XGE_HAL_MAC_RMAC_ALL_ADDR_ENABLE );
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ( ~XGE_HAL_MAC_CFG_RMAC_PROM_ENABLE );
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_MAC_CFG_TMAC_APPEND_PAD;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * If the RTH enable bit is not set, strip the FCS
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->config.rth_en ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl !(xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_cfg) & XGE_HAL_RTS_RTH_EN)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_MAC_CFG_RMAC_STRIP_FCS;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ( ~XGE_HAL_MAC_CFG_RMAC_STRIP_PAD );
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_MAC_RMAC_DISCARD_PFRM;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u32)(val64 >> 32), (char*)&bar0->mac_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "mac_cfg 0x%llx: frame padding configured",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_pause_frames_configure
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Set Pause threshold.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Pause frame is generated if the amount of data outstanding
a23fd118e437af0a7877dd313db8fdaa3537c675yl * on any queue exceeded the ratio of
a23fd118e437af0a7877dd313db8fdaa3537c675yl * (mac_control.mc_pause_threshold_q0q3 or q4q7)/256
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_pause_frames_configure(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl switch (hldev->config.mac.media) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_MEDIA_SR:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_MEDIA_SW:
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64=0xfffbfffbfffbfffbULL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_MEDIA_LR:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_MEDIA_LW:
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64=0xffbbffbbffbbffbbULL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_MEDIA_ER:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_MEDIA_EW:
a23fd118e437af0a7877dd313db8fdaa3537c675yl default:
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64=0xffbbffbbffbbffbbULL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->mc_pause_thresh_q0q3);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->mc_pause_thresh_q4q7);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Set the time value to be inserted in the pause frame generated
a23fd118e437af0a7877dd313db8fdaa3537c675yl * by Xframe */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_pause_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.mac.rmac_pause_gen_en)
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RMAC_PAUSE_GEN_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl else
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~(XGE_HAL_RMAC_PAUSE_GEN_EN);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.mac.rmac_pause_rcv_en)
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RMAC_PAUSE_RCV_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl else
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~(XGE_HAL_RMAC_PAUSE_RCV_EN);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~(XGE_HAL_RMAC_PAUSE_HG_PTIME(0xffff));
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RMAC_PAUSE_HG_PTIME(hldev->config.mac.rmac_pause_time);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_pause_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i = 0; i<4; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |=
a23fd118e437af0a7877dd313db8fdaa3537c675yl (((u64)0xFF00|hldev->config.mac.mc_pause_threshold_q0q3)
a23fd118e437af0a7877dd313db8fdaa3537c675yl <<(i*2*8));
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mc_pause_thresh_q0q3);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i = 0; i<4; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |=
a23fd118e437af0a7877dd313db8fdaa3537c675yl (((u64)0xFF00|hldev->config.mac.mc_pause_threshold_q4q7)
a23fd118e437af0a7877dd313db8fdaa3537c675yl <<(i*2*8));
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mc_pause_thresh_q4q7);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "pause frames configured");
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Herc's clock rate doubled, unless the slot is 33MHz.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylunsigned int __hal_fix_time_ival_herc(xge_hal_device_t *hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl unsigned int time_ival)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
a23fd118e437af0a7877dd313db8fdaa3537c675yl return time_ival;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->bus_frequency != XGE_HAL_PCI_BUS_FREQUENCY_UNKNOWN &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->bus_frequency != XGE_HAL_PCI_BUS_FREQUENCY_33MHZ)
a23fd118e437af0a7877dd313db8fdaa3537c675yl time_ival *= 2;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return time_ival;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_bus_master_disable
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Disable bus mastership.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_bus_master_disable (xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 cmd;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 bus_master = 4;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, command), &cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl cmd &= ~bus_master;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_write16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, command), cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_bus_master_enable
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Disable bus mastership.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_bus_master_enable (xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 cmd;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 bus_master = 4;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, command), &cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* already enabled? do nothing */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (cmd & bus_master)
a23fd118e437af0a7877dd313db8fdaa3537c675yl return;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl cmd |= bus_master;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_write16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, command), cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_intr_mgmt
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @mask: mask indicating which Intr block must be modified.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @flag: if true - enable, otherwise - disable interrupts.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Disable or enable device interrupts. Mask is used to specify
a23fd118e437af0a7877dd313db8fdaa3537c675yl * which hardware blocks should produce interrupts. For details
a23fd118e437af0a7877dd313db8fdaa3537c675yl * please refer to Xframe User Guide.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_intr_mgmt(xge_hal_device_t *hldev, u64 mask, int flag)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64 = 0, temp64 = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 gim, gim_saved;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim_saved = gim = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, &bar0->general_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Top level interrupt classification */
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* PIC Interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((mask & (XGE_HAL_TX_PIC_INTR/* | XGE_HAL_RX_PIC_INTR*/))) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Enable PIC Intrs in the general intr mask register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_TXPIC_INT_M/* | XGE_HAL_PIC_RX_INT_M*/;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (flag) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim &= ~((u64) val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, &bar0->pic_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 &= ~XGE_HAL_PIC_INT_TX;
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) ==
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_CARD_HERC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 &= ~XGE_HAL_PIC_INT_MISC;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64, &bar0->pic_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) ==
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_CARD_HERC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Unmask only Link Up interrupt
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, &bar0->misc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 &= ~XGE_HAL_MISC_INT_REG_LINK_UP_INT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, temp64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->misc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "unmask link up flag %llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)temp64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else { /* flag == 0 */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) ==
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_CARD_HERC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Mask both Link Up and Down interrupts
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, &bar0->misc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 |= XGE_HAL_MISC_INT_REG_LINK_UP_INT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 |= XGE_HAL_MISC_INT_REG_LINK_DOWN_INT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, temp64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->misc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "mask link up/down flag %llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)temp64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Disable PIC Intrs in the general intr mask
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->pic_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim |= val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* DMA Interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Enabling/Disabling Tx DMA interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (mask & XGE_HAL_TX_DMA_INTR) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Enable TxDMA Intrs in the general intr mask register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_TXDMA_INT_M;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (flag) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim &= ~((u64) val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Disable all TxDMA interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->txdma_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->pfc_err_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else { /* flag == 0 */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Disable TxDMA Intrs in the general intr mask
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->txdma_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->pfc_err_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim |= val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Enabling/Disabling Rx DMA interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (mask & XGE_HAL_RX_DMA_INTR) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Enable RxDMA Intrs in the general intr mask register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RXDMA_INT_M;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (flag) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim &= ~((u64) val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* All RxDMA block interrupts are disabled for now
a23fd118e437af0a7877dd313db8fdaa3537c675yl * TODO */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rxdma_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else { /* flag == 0 */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Disable RxDMA Intrs in the general intr mask
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rxdma_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim |= val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* MAC Interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Enabling/Disabling MAC interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (mask & (XGE_HAL_TX_MAC_INTR | XGE_HAL_RX_MAC_INTR)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_TXMAC_INT_M | XGE_HAL_RXMAC_INT_M;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (flag) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim &= ~((u64) val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* All MAC block error inter. are disabled for now. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS, &bar0->mac_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS, &bar0->mac_rmac_err_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else { /* flag == 0 */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Disable MAC Intrs in the general intr mask
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS, &bar0->mac_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS, &bar0->mac_rmac_err_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim |= val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* XGXS Interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (mask & (XGE_HAL_TX_XGXS_INTR | XGE_HAL_RX_XGXS_INTR)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_TXXGXS_INT_M | XGE_HAL_RXXGXS_INT_M;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (flag) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim &= ~((u64) val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* All XGXS block error interrupts are disabled for now
a23fd118e437af0a7877dd313db8fdaa3537c675yl * TODO */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS, &bar0->xgxs_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else { /* flag == 0 */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Disable MC Intrs in the general intr mask register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS, &bar0->xgxs_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim |= val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Memory Controller(MC) interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (mask & XGE_HAL_MC_INTR) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_MC_INT_M;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (flag) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim &= ~((u64) val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Enable all MC blocks error interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x0ULL, &bar0->mc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else { /* flag == 0 */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Disable MC Intrs in the general intr mask
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS, &bar0->mc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim |= val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Tx traffic interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (mask & XGE_HAL_TX_TRAFFIC_INTR) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_TXTRAFFIC_INT_M;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (flag) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim &= ~((u64) val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Enable all the Tx side interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* '0' Enables all 64 TX interrupt levels. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0x0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->tx_traffic_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else { /* flag == 0 */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Disable Tx Traffic Intrs in the general intr mask
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->tx_traffic_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim |= val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Rx traffic interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (mask & XGE_HAL_RX_TRAFFIC_INTR) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RXTRAFFIC_INT_M;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (flag) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim &= ~((u64) val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* '0' Enables all 8 RX interrupt levels. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0x0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rx_traffic_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else { /* flag == 0 */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Disable Rx Traffic Intrs in the general intr mask
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ALL_INTRS_DIS,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rx_traffic_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl gim |= val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Sched Timer interrupt */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (mask & XGE_HAL_SCHED_INTR) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (flag) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, &bar0->txpic_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 &= ~XGE_HAL_TXPIC_INT_SCHED_INTR;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64, &bar0->txpic_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_sched_timer(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.sched_timer_us,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.sched_timer_one_shot);
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, &bar0->txpic_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 |= XGE_HAL_TXPIC_INT_SCHED_INTR;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64, &bar0->txpic_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_sched_timer(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SCHED_TIMER_DISABLED,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SCHED_TIMER_ON_SHOT_ENABLE);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (gim != gim_saved) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, gim,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->general_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "general_int_mask updated %llx => %llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)gim_saved, (unsigned long long)gim);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_rti_configure
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * RTI Initialization.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Initialize Receive Traffic Interrupt Scheme.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic xge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_rti_configure(xge_hal_device_t *hldev, int runtime)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64, data1 = 0, data2 = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (runtime)
a23fd118e437af0a7877dd313db8fdaa3537c675yl bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl else
a23fd118e437af0a7877dd313db8fdaa3537c675yl bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i=0; i<XGE_HAL_MAX_RING_NUM; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_rti_config_t *rti = &hldev->config.ring.queue[i].rti;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->config.ring.queue[i].configured)
a23fd118e437af0a7877dd313db8fdaa3537c675yl continue;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (rti->timer_val_us) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl unsigned int rx_interval;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.pci_freq_mherz) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl rx_interval = hldev->config.pci_freq_mherz *
a23fd118e437af0a7877dd313db8fdaa3537c675yl rti->timer_val_us / 8;
a23fd118e437af0a7877dd313db8fdaa3537c675yl rx_interval =
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_fix_time_ival_herc(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl rx_interval);
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl rx_interval = rti->timer_val_us;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl data1 |=XGE_HAL_RTI_DATA1_MEM_RX_TIMER_VAL(rx_interval);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (rti->timer_ac_en) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl data1 |= XGE_HAL_RTI_DATA1_MEM_RX_TIMER_AC_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl data1 |= XGE_HAL_RTI_DATA1_MEM_RX_TIMER_CI_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (rti->urange_a ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl rti->urange_b ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl rti->urange_c ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl rti->ufc_a ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl rti->ufc_b ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl rti->ufc_c ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl rti->ufc_d) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl data1 |=XGE_HAL_RTI_DATA1_MEM_RX_URNG_A(rti->urange_a) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTI_DATA1_MEM_RX_URNG_B(rti->urange_b) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTI_DATA1_MEM_RX_URNG_C(rti->urange_c);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl data2 |= XGE_HAL_RTI_DATA2_MEM_RX_UFC_A(rti->ufc_a) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTI_DATA2_MEM_RX_UFC_B(rti->ufc_b) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTI_DATA2_MEM_RX_UFC_C(rti->ufc_c) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTI_DATA2_MEM_RX_UFC_D(rti->ufc_d);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, data1,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rti_data1_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, data2,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rti_data2_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_wmb();
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RTI_CMD_MEM_WE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTI_CMD_MEM_STROBE_NEW_CMD;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTI_CMD_MEM_OFFSET(i);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rti_command_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!runtime && __hal_device_register_poll(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rti_command_mem, 0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTI_CMD_MEM_STROBE_NEW_CMD,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* upper layer may require to repeat */
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!runtime) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "RTI configured: rti_data1_mem 0x%llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, &bar0->rti_data1_mem));
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_tti_configure
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * TTI Initialization.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Initialize Transmit Traffic Interrupt Scheme.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic xge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_tti_configure(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_tti_config_t *tti = &hldev->config.tti;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64, data1 = 0, data2 = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (tti->timer_val_us) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl unsigned int tx_interval;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.pci_freq_mherz) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl tx_interval = hldev->config.pci_freq_mherz *
a23fd118e437af0a7877dd313db8fdaa3537c675yl tti->timer_val_us / 64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl tx_interval =
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_fix_time_ival_herc(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl tx_interval);
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl tx_interval = tti->timer_val_us;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl data1 |= XGE_HAL_TTI_DATA1_MEM_TX_TIMER_VAL(tx_interval);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (tti->timer_ac_en) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl data1 |= XGE_HAL_TTI_DATA1_MEM_TX_TIMER_AC_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (tti->timer_ci_en) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl data1 |= XGE_HAL_TTI_DATA1_MEM_TX_TIMER_CI_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "TTI timer enabled to %d, ci %s",
a23fd118e437af0a7877dd313db8fdaa3537c675yl tx_interval, tti->timer_ci_en ?
a23fd118e437af0a7877dd313db8fdaa3537c675yl "enabled": "disabled");
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (tti->urange_a ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl tti->urange_b ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl tti->urange_c ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl tti->ufc_a ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl tti->ufc_b ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl tti->ufc_c ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl tti->ufc_d ) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl data1 |= XGE_HAL_TTI_DATA1_MEM_TX_URNG_A(tti->urange_a) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_TTI_DATA1_MEM_TX_URNG_B(tti->urange_b) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_TTI_DATA1_MEM_TX_URNG_C(tti->urange_c);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl data2 |= XGE_HAL_TTI_DATA2_MEM_TX_UFC_A(tti->ufc_a) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_TTI_DATA2_MEM_TX_UFC_B(tti->ufc_b) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_TTI_DATA2_MEM_TX_UFC_C(tti->ufc_c) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_TTI_DATA2_MEM_TX_UFC_D(tti->ufc_d);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "TTI utiliz. enabled");
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, data1,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->tti_data1_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, data2,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->tti_data2_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_TTI_CMD_MEM_WE | XGE_HAL_TTI_CMD_MEM_STROBE_NEW_CMD;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->tti_command_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev, &bar0->tti_command_mem, 0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_TTI_CMD_MEM_STROBE_NEW_CMD,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* upper layer may require to repeat */
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "TTI configured: tti_data1_mem 0x%llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->tti_data1_mem));
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/* Constants to be programmed into the Xena's registers to configure
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the XAUI. */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic u64 default_xena_mdio_cfg[] = {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Reset PMA PLL */
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0xC001010000000000ULL, 0xC0010100000000E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0xC0010100008000E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Remove Reset from PMA PLL */
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0xC001010000000000ULL, 0xC0010100000000E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0xC0010100000000E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl END_SIGN
a23fd118e437af0a7877dd313db8fdaa3537c675yl};
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic u64 default_herc_mdio_cfg[] = {
a23fd118e437af0a7877dd313db8fdaa3537c675yl END_SIGN
a23fd118e437af0a7877dd313db8fdaa3537c675yl};
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic u64 default_xena_dtx_cfg[] = {
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x8000051500000000ULL, 0x80000515000000E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80000515D93500E4ULL, 0x8001051500000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80010515000000E0ULL, 0x80010515001E00E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x8002051500000000ULL, 0x80020515000000E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80020515F21000E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Set PADLOOPBACKN */
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x8002051500000000ULL, 0x80020515000000E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80020515B20000E4ULL, 0x8003051500000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80030515000000E0ULL, 0x80030515B20000E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x8004051500000000ULL, 0x80040515000000E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80040515B20000E4ULL, 0x8005051500000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80050515000000E0ULL, 0x80050515B20000E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl SWITCH_SIGN,
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Remove PADLOOPBACKN */
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x8002051500000000ULL, 0x80020515000000E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80020515F20000E4ULL, 0x8003051500000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80030515000000E0ULL, 0x80030515F20000E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x8004051500000000ULL, 0x80040515000000E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80040515F20000E4ULL, 0x8005051500000000ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80050515000000E0ULL, 0x80050515F20000E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl END_SIGN
a23fd118e437af0a7877dd313db8fdaa3537c675yl};
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic u64 default_herc_dtx_cfg[] = {
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80000515BA750000ULL, 0x80000515BA7500E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80000515BA750004ULL, 0x80000515BA7500E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80010515003F0000ULL, 0x80010515003F00E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80010515003F0004ULL, 0x80010515003F00E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80020515F2100000ULL, 0x80020515F21000E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80020515F2100004ULL, 0x80020515F21000E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl END_SIGN
a23fd118e437af0a7877dd313db8fdaa3537c675yl};
a23fd118e437af0a7877dd313db8fdaa3537c675yl*/
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic u64 default_herc_dtx_cfg[] = {
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x8000051536750000ULL, 0x80000515367500E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x8000051536750004ULL, 0x80000515367500E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80010515003F0000ULL, 0x80010515003F00E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80010515003F0004ULL, 0x80010515003F00E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x801205150D440000ULL, 0x801205150D4400E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x801205150D440004ULL, 0x801205150D4400E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80020515F2100000ULL, 0x80020515F21000E0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80020515F2100004ULL, 0x80020515F21000E4ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl END_SIGN
a23fd118e437af0a7877dd313db8fdaa3537c675yl};
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_xaui_configure
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Configure XAUI Interface of Xena.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * To Configure the Xena's XAUI, one has to write a series
a23fd118e437af0a7877dd313db8fdaa3537c675yl * of 64 bit values into two registers in a particular
a23fd118e437af0a7877dd313db8fdaa3537c675yl * sequence. Hence a macro 'SWITCH_SIGN' has been defined
a23fd118e437af0a7877dd313db8fdaa3537c675yl * which will be defined in the array of configuration values
a23fd118e437af0a7877dd313db8fdaa3537c675yl * (default_dtx_cfg & default_mdio_cfg) at appropriate places
a23fd118e437af0a7877dd313db8fdaa3537c675yl * to switch writing from one regsiter to another. We continue
a23fd118e437af0a7877dd313db8fdaa3537c675yl * writing these values until we encounter the 'END_SIGN' macro.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * For example, After making a series of 21 writes into
a23fd118e437af0a7877dd313db8fdaa3537c675yl * dtx_control register the 'SWITCH_SIGN' appears and hence we
a23fd118e437af0a7877dd313db8fdaa3537c675yl * start writing into mdio_control until we encounter END_SIGN.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_xaui_configure(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int mdio_cnt = 0, dtx_cnt = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 *default_dtx_cfg = NULL, *default_mdio_cfg = NULL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl default_dtx_cfg = default_xena_dtx_cfg;
a23fd118e437af0a7877dd313db8fdaa3537c675yl default_mdio_cfg = default_xena_mdio_cfg;
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl default_dtx_cfg = default_herc_dtx_cfg;
a23fd118e437af0a7877dd313db8fdaa3537c675yl default_mdio_cfg = default_herc_mdio_cfg;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(default_dtx_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl do {
a23fd118e437af0a7877dd313db8fdaa3537c675yl dtx_cfg:
a23fd118e437af0a7877dd313db8fdaa3537c675yl while (default_dtx_cfg[dtx_cnt] != END_SIGN) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (default_dtx_cfg[dtx_cnt] == SWITCH_SIGN) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl dtx_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl goto mdio_cfg;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u32)(default_dtx_cfg[dtx_cnt]>>32),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->dtx_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u32)default_dtx_cfg[dtx_cnt],
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->dtx_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_wmb();
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl dtx_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl mdio_cfg:
a23fd118e437af0a7877dd313db8fdaa3537c675yl while (default_mdio_cfg[mdio_cnt] != END_SIGN) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (default_mdio_cfg[mdio_cnt] == SWITCH_SIGN) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl mdio_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl goto dtx_cfg;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u32)(default_mdio_cfg[mdio_cnt]>>32),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mdio_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u32)default_mdio_cfg[mdio_cnt],
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mdio_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_wmb();
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl mdio_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } while ( !((default_dtx_cfg[dtx_cnt] == END_SIGN) &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl (default_mdio_cfg[mdio_cnt] == END_SIGN)) );
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "XAUI interface configured");
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_mac_link_util_set
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Set sampling rate to calculate link utilization.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_mac_link_util_set(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_MAC_TX_LINK_UTIL_VAL(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.mac.tmac_util_period) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_MAC_RX_LINK_UTIL_VAL(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.mac.rmac_util_period);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mac_link_util);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s",
a23fd118e437af0a7877dd313db8fdaa3537c675yl "bandwidth link utilization configured");
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_set_swapper
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Set the Xframe's byte "swapper" in accordance with
a23fd118e437af0a7877dd313db8fdaa3537c675yl * endianness of the host.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_set_swapper(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * from 32bit errarta:
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * The SWAPPER_CONTROL register determines how the adapter accesses
a23fd118e437af0a7877dd313db8fdaa3537c675yl * host memory as well as how it responds to read and write requests
a23fd118e437af0a7877dd313db8fdaa3537c675yl * from the host system. Writes to this register should be performed
a23fd118e437af0a7877dd313db8fdaa3537c675yl * carefully, since the byte swappers could reverse the order of bytes.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * When configuring this register keep in mind that writes to the PIF
a23fd118e437af0a7877dd313db8fdaa3537c675yl * read and write swappers could reverse the order of the upper and
a23fd118e437af0a7877dd313db8fdaa3537c675yl * lower 32-bit words. This means that the driver may have to write
a23fd118e437af0a7877dd313db8fdaa3537c675yl * to the upper 32 bits of the SWAPPER_CONTROL twice in order to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * configure the entire register. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * The device by default set to a big endian format, so a big endian
a23fd118e437af0a7877dd313db8fdaa3537c675yl * driver need not set anything.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_CUSTOM_HW_SWAPPER)
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0xffffffffffffffffULL, &bar0->swapper_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_CUSTOM_HW_SWAPPER;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_wmb();
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->swapper_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "using custom HW swapper 0x%llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#elif !defined(XGE_OS_HOST_BIG_ENDIAN)
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Initially we enable all bits to make it accessible by the driver,
a23fd118e437af0a7877dd313db8fdaa3537c675yl * then we selectively enable only those bits that we want to set.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * i.e. force swapper to swap for the first time since second write
a23fd118e437af0a7877dd313db8fdaa3537c675yl * will overwrite with the final settings.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Use only for little endian platforms.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0xffffffffffffffffULL, &bar0->swapper_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_wmb();
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = (XGE_HAL_SWAPPER_CTRL_PIF_R_FE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_PIF_R_SE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_PIF_W_FE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_PIF_W_SE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_RTH_FE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_RTH_SE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_TXP_FE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_TXP_SE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_TXD_R_FE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_TXD_R_SE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_TXD_W_FE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_TXD_W_SE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_TXF_R_FE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_RXD_R_FE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_RXD_R_SE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_RXD_W_FE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_RXD_W_SE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_RXF_W_FE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_XMSI_FE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SWAPPER_CTRL_STATS_FE | XGE_HAL_SWAPPER_CTRL_STATS_SE);
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_SWAPPER_CTRL_XMSI_SE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl } */
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0, (u32)val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->swapper_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_wmb();
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0, (u32)(val64>>32),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->swapper_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_wmb();
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0, (u32)(val64>>32),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->swapper_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "using little endian set");
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Verifying if endian settings are accurate by reading a feedback
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->pif_rd_swapper_fb);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 != XGE_HAL_IF_RD_SWAPPER_FB) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "pif_rd_swapper_fb read %llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long) val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_SWAPPER_CTRL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "be/le swapper enabled");
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_rts_mac_configure - Configure RTS steering based on
a23fd118e437af0a7877dd313db8fdaa3537c675yl * destination mac address.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_rts_mac_configure(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->config.rts_mac_en) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Set the receive traffic steering mode from default(classic)
a23fd118e437af0a7877dd313db8fdaa3537c675yl * to enhanced.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_CTRL_ENHANCED_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->rts_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge__hal_device_rts_mac_enable
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @devh: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @index: index number where the MAC addr will be stored
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @macaddr: MAC address
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - Enable RTS steering for the given MAC address. This function has to be
a23fd118e437af0a7877dd313db8fdaa3537c675yl * called with lock acquired.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * NOTE:
a23fd118e437af0a7877dd313db8fdaa3537c675yl * 1. ULD has to call this function with the index value which
a23fd118e437af0a7877dd313db8fdaa3537c675yl * statisfies the following condition:
a23fd118e437af0a7877dd313db8fdaa3537c675yl * ring_num = (index % 8)
a23fd118e437af0a7877dd313db8fdaa3537c675yl * 2.ULD also needs to make sure that the index is not
a23fd118e437af0a7877dd313db8fdaa3537c675yl * occupied by any MAC address. If that index has any MAC address
a23fd118e437af0a7877dd313db8fdaa3537c675yl * it will be overwritten and HAL will not check for it.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_rts_mac_enable(xge_hal_device_h devh, int index, macaddr_t macaddr)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int section;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ( index >= XGE_HAL_MAX_MAC_ADDRESSES )
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Set the MAC address at the given location marked by index.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = xge_hal_device_macaddr_set(hldev, index, macaddr);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "%s",
a23fd118e437af0a7877dd313db8fdaa3537c675yl "Not able to set the mac addr");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Calculate the section value
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl section = index / 32;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "the Section value is %d \n", section);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_mac_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl switch(section)
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 0:
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_MAC_SECT0_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 1:
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_MAC_SECT1_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 2:
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_MAC_SECT2_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 3:
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_MAC_SECT3_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 4:
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_MAC_SECT4_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 5:
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_MAC_SECT5_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 6:
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_MAC_SECT6_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 7:
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_MAC_SECT7_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl default:
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "Invalid Section value %d \n"
a23fd118e437af0a7877dd313db8fdaa3537c675yl , section);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->rts_mac_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge__hal_device_rts_mac_disable
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @index: index number where to disable the MAC addr
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Disable RTS Steering based on the MAC address.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function should be called with lock acquired.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_rts_mac_disable(xge_hal_device_h devh, int index)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u8 macaddr[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_ll(XGE_TRACE, "the index value is %d \n", index);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ( index >= XGE_HAL_MAX_MAC_ADDRESSES )
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Disable MAC address @ given index location
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = xge_hal_device_macaddr_set(hldev, index, macaddr);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "%s",
a23fd118e437af0a7877dd313db8fdaa3537c675yl "Not able to set the mac addr");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_rth_configure - Configure RTH for the device
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Using IT (Indirection Table).
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_rth_it_configure(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int rings[XGE_HAL_MAX_RING_NUM]={0};
a23fd118e437af0a7877dd313db8fdaa3537c675yl int rnum;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int rmax;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int buckets_num;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int bucket;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->config.rth_en) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Set the receive traffic steering mode from default(classic)
a23fd118e437af0a7877dd313db8fdaa3537c675yl * to enhanced.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_CTRL_ENHANCED_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->rts_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl buckets_num = (1 << hldev->config.rth_bucket_size);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl rmax=0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (rnum = 0; rnum < XGE_HAL_MAX_RING_NUM; rnum++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.ring.queue[rnum].configured &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.ring.queue[rnum].rth_en)
a23fd118e437af0a7877dd313db8fdaa3537c675yl rings[rmax++] = rnum;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl rnum = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* for starters: fill in all the buckets with rings "equally" */
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (bucket = 0; bucket < buckets_num; bucket++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (rnum == rmax)
a23fd118e437af0a7877dd313db8fdaa3537c675yl rnum = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* write data */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RTS_RTH_MAP_MEM_DATA_ENTRY_EN |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTS_RTH_MAP_MEM_DATA(rings[rnum]);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_map_mem_data);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* execute */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RTS_RTH_MAP_MEM_CTRL_WE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTS_RTH_MAP_MEM_CTRL_STROBE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTS_RTH_MAP_MEM_CTRL_OFFSET(bucket);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_map_mem_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* poll until done */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_map_mem_ctrl, 0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTS_RTH_MAP_MEM_CTRL_STROBE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl rnum++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RTS_RTH_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_RTH_BUCKET_SIZE(hldev->config.rth_bucket_size);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_RTH_TCP_IPV4_EN | XGE_HAL_RTS_RTH_UDP_IPV4_EN | XGE_HAL_RTS_RTH_IPV4_EN |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTS_RTH_TCP_IPV6_EN |XGE_HAL_RTS_RTH_UDP_IPV6_EN | XGE_HAL_RTS_RTH_IPV6_EN |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTS_RTH_TCP_IPV6_EX_EN | XGE_HAL_RTS_RTH_UDP_IPV6_EX_EN | XGE_HAL_RTS_RTH_IPV6_EX_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "RTH configured, bucket_size %d",
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.rth_bucket_size);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_spdm_entry_add - Add a new entry to the SPDM table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Add a new entry to the SPDM table
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function add a new entry to the SPDM table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Note:
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function should be called with spdm_lock.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_spdm_entry_add , xge_hal_spdm_entry_remove.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic xge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_spdm_entry_add(xge_hal_device_t *hldev, xge_hal_ipaddr_t *src_ip,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_ipaddr_t *dst_ip, u16 l4_sp, u16 l4_dp, u8 is_tcp,
a23fd118e437af0a7877dd313db8fdaa3537c675yl u8 is_ipv4, u8 tgt_queue, u32 jhash_value, u16 spdm_entry)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 spdm_line_arr[8];
a23fd118e437af0a7877dd313db8fdaa3537c675yl u8 line_no;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Poll the rxpic_int_reg register until spdm ready bit is set or
a23fd118e437af0a7877dd313db8fdaa3537c675yl * timeout happens.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev, &bar0->rxpic_int_reg, 1,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RX_PIC_INT_REG_SPDM_READY,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* upper layer may require to repeat */
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Clear the SPDM READY bit
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rxpic_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~XGE_HAL_RX_PIC_INT_REG_SPDM_READY;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rxpic_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "L4 SP %x:DP %x: hash %x tgt_queue %d \n",
a23fd118e437af0a7877dd313db8fdaa3537c675yl l4_sp, l4_dp, jhash_value, tgt_queue);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_memzero(&spdm_line_arr, sizeof(spdm_line_arr));
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Construct the SPDM entry.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_line_arr[0] = vBIT(l4_sp,0,16) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl vBIT(l4_dp,16,32) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl vBIT(tgt_queue,53,3) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl vBIT(is_tcp,59,1) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl vBIT(is_ipv4,63,1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (is_ipv4) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_line_arr[1] = vBIT(src_ip->ipv4.addr,0,32) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl vBIT(dst_ip->ipv4.addr,32,32);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_memcpy(&spdm_line_arr[1], &src_ip->ipv6.addr[0], 8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_memcpy(&spdm_line_arr[2], &src_ip->ipv6.addr[1], 8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_memcpy(&spdm_line_arr[3], &dst_ip->ipv6.addr[0], 8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_memcpy(&spdm_line_arr[4], &dst_ip->ipv6.addr[1], 8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_line_arr[7] = vBIT(jhash_value,0,32) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl BIT(63); /* entry enable bit */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Add the entry to the SPDM table
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl for(line_no = 0; line_no < 8; line_no++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_line_arr[line_no],
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void *)((char *)hldev->spdm_mem_base +
a23fd118e437af0a7877dd313db8fdaa3537c675yl (spdm_entry * 64) +
a23fd118e437af0a7877dd313db8fdaa3537c675yl (line_no * 8)));
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Wait for the operation to be completed.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev, &bar0->rxpic_int_reg, 1,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RX_PIC_INT_REG_SPDM_READY,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Add this information to a local SPDM table. The purpose of
a23fd118e437af0a7877dd313db8fdaa3537c675yl * maintaining a local SPDM table is to avoid a search in the
a23fd118e437af0a7877dd313db8fdaa3537c675yl * adapter SPDM table for spdm entry lookup which is very costly
a23fd118e437af0a7877dd313db8fdaa3537c675yl * in terms of time.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_table[spdm_entry]->in_use = 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_memcpy(&hldev->spdm_table[spdm_entry]->src_ip, src_ip,
a23fd118e437af0a7877dd313db8fdaa3537c675yl sizeof(xge_hal_ipaddr_t));
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_memcpy(&hldev->spdm_table[spdm_entry]->dst_ip, dst_ip,
a23fd118e437af0a7877dd313db8fdaa3537c675yl sizeof(xge_hal_ipaddr_t));
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_table[spdm_entry]->l4_sp = l4_sp;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_table[spdm_entry]->l4_dp = l4_dp;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_table[spdm_entry]->is_tcp = is_tcp;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_table[spdm_entry]->is_ipv4 = is_ipv4;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_table[spdm_entry]->tgt_queue = tgt_queue;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_table[spdm_entry]->jhash_value = jhash_value;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_table[spdm_entry]->spdm_entry = spdm_entry;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_rth_spdm_configure - Configure RTH for the device
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Using SPDM (Socket-Pair Direct Match).
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_rth_spdm_configure(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u8 spdm_bar_num;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u32 spdm_bar_offset;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int spdm_table_size;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->config.rth_spdm_en) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Retrieve the base address of SPDM Table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, &bar0->spdm_bir_offset);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_bar_num = XGE_HAL_SPDM_PCI_BAR_NUM(val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_bar_offset = XGE_HAL_SPDM_PCI_BAR_OFFSET(val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * spdm_bar_num specifies the PCI bar num register used to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * address the memory space. spdm_bar_offset specifies the offset
a23fd118e437af0a7877dd313db8fdaa3537c675yl * of the SPDM memory with in the bar num memory space.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl switch (spdm_bar_num) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 0:
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_mem_base = (char *)bar0 +
a23fd118e437af0a7877dd313db8fdaa3537c675yl (spdm_bar_offset * 8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 1:
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl char *bar1 = (char *)hldev->bar1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_mem_base = bar1 + (spdm_bar_offset * 8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl default:
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(((spdm_bar_num != 0) && (spdm_bar_num != 1)));
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Retrieve the size of SPDM table(number of entries).
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, &bar0->spdm_structure);
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_max_entries = XGE_HAL_SPDM_MAX_ENTRIES(val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_table_size = hldev->spdm_max_entries *
a23fd118e437af0a7877dd313db8fdaa3537c675yl sizeof(xge_hal_spdm_entry_t);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->spdm_table == NULL) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl void *mem;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Allocate memory to hold the copy of SPDM table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((hldev->spdm_table = (xge_hal_spdm_entry_t **)
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_malloc(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (sizeof(xge_hal_spdm_entry_t *) *
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_max_entries))) == NULL) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_OUT_OF_MEMORY;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((mem = xge_os_malloc(hldev->pdev, spdm_table_size)) == NULL)
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_free(hldev->pdev, hldev->spdm_table,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (sizeof(xge_hal_spdm_entry_t *) *
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_max_entries));
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_OUT_OF_MEMORY;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_memzero(mem, spdm_table_size);
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i = 0; i < hldev->spdm_max_entries; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_table[i] = (xge_hal_spdm_entry_t *)
a23fd118e437af0a7877dd313db8fdaa3537c675yl ((char *)mem +
a23fd118e437af0a7877dd313db8fdaa3537c675yl i * sizeof(xge_hal_spdm_entry_t));
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_lock_init(&hldev->spdm_lock, hldev->pdev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * We are here because the host driver tries to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * do a soft reset on the device.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Since the device soft reset clears the SPDM table, copy
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the entries from the local SPDM table to the actual one.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_lock(&hldev->spdm_lock);
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i = 0; i < hldev->spdm_max_entries; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_spdm_entry_t *spdm_entry = hldev->spdm_table[i];
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (spdm_entry->in_use) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_spdm_entry_add(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &spdm_entry->src_ip,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &spdm_entry->dst_ip,
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_entry->l4_sp,
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_entry->l4_dp,
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_entry->is_tcp,
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_entry->is_ipv4,
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_entry->tgt_queue,
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_entry->jhash_value,
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_entry->spdm_entry)
a23fd118e437af0a7877dd313db8fdaa3537c675yl != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Log an warning */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "SPDM table update from local"
a23fd118e437af0a7877dd313db8fdaa3537c675yl " memory failed");
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_unlock(&hldev->spdm_lock);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Set the receive traffic steering mode from default(classic)
a23fd118e437af0a7877dd313db8fdaa3537c675yl * to enhanced.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, &bar0->rts_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_CTRL_ENHANCED_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->rts_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * We may not need to configure rts_rth_jhash_cfg register as the
a23fd118e437af0a7877dd313db8fdaa3537c675yl * default values are good enough to calculate the hash.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * As of now, set all the rth mask registers to zero. TODO.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl for(i = 0; i < 5; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0, &bar0->rts_rth_hash_mask[i]);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0, &bar0->rts_rth_hash_mask_5);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.rth_spdm_use_l4) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RTH_STATUS_SPDM_USE_L4;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->rts_rth_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RTS_RTH_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_RTH_IPV4_EN | XGE_HAL_RTS_RTH_TCP_IPV4_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_pci_init
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Initialize certain PCI/PCI-X configuration registers
a23fd118e437af0a7877dd313db8fdaa3537c675yl * with recommended values. Save config space for future hw resets.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_pci_init(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i, pcisize = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 cmd = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u8 val;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Set the PErr Repconse bit and SERR in PCI command register. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, command), &cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl cmd |= 0x140;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_write16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, command), cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Set user spcecified value for the PCI Latency Timer */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.latency_timer &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.latency_timer != XGE_HAL_USE_BIOS_DEFAULT_LATENCY) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_write8(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t,
a23fd118e437af0a7877dd313db8fdaa3537c675yl latency_timer),
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u8)hldev->config.latency_timer);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Read back latency timer to reflect it into user level */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read8(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, latency_timer), &val);
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.latency_timer = val;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Enable Data Parity Error Recovery in PCI-X command register. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, pcix_command), &cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl cmd |= 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_write16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, pcix_command), cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Set MMRB count in PCI-X command register. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.mmrb_count != XGE_HAL_DEFAULT_BIOS_MMRB_COUNT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl cmd &= 0xFFF3;
a23fd118e437af0a7877dd313db8fdaa3537c675yl cmd |= hldev->config.mmrb_count << 2;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_write16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, pcix_command),
a23fd118e437af0a7877dd313db8fdaa3537c675yl cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Read back MMRB count to reflect it into user level */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, pcix_command),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl cmd &= 0x000C;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.mmrb_count = cmd>>2;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Setting Maximum outstanding splits based on system type. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.max_splits_trans != XGE_HAL_USE_BIOS_DEFAULT_SPLITS) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, pcix_command),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl cmd &= 0xFF8F;
a23fd118e437af0a7877dd313db8fdaa3537c675yl cmd |= hldev->config.max_splits_trans << 4;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_write16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, pcix_command),
a23fd118e437af0a7877dd313db8fdaa3537c675yl cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Read back max split trans to reflect it into user level */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, pcix_command), &cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl cmd &= 0x0070;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.max_splits_trans = cmd>>4;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Forcibly disabling relaxed ordering capability of the card. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, pcix_command), &cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl cmd &= 0xFFFD;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_write16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, pcix_command), cmd);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Store PCI device ID and revision for future references where in we
a23fd118e437af0a7877dd313db8fdaa3537c675yl * decide Xena revision using PCI sub system ID */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev,hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, device_id),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &hldev->device_id);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read8(hldev->pdev,hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, revision),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &hldev->revision);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC)
a23fd118e437af0a7877dd313db8fdaa3537c675yl pcisize = XGE_HAL_PCISIZE_HERC;
a23fd118e437af0a7877dd313db8fdaa3537c675yl else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
a23fd118e437af0a7877dd313db8fdaa3537c675yl pcisize = XGE_HAL_PCISIZE_XENA;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* save PCI config space for future resets */
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i = 0; i < pcisize; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read32(hldev->pdev, hldev->cfgh, i*4,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u32*)&hldev->pci_config_space + i);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_MSI)
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Upper limit of the MSI number enabled by the system */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read32(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, msi_control),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &hldev->msi_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->msi_mask &= 0x70;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->msi_mask)
a23fd118e437af0a7877dd313db8fdaa3537c675yl return;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->msi_mask >>= 4; /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This number's power of 2 is the number
a23fd118e437af0a7877dd313db8fdaa3537c675yl * of MSIs enabled.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->msi_mask = (0x1 << hldev->msi_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * NOTE:
a23fd118e437af0a7877dd313db8fdaa3537c675yl * If 32 MSIs are enabled, then MSI numbers range from 0 - 31.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->msi_mask -= 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_pci_info_get - Get PCI bus informations such as width, frequency
a23fd118e437af0a7877dd313db8fdaa3537c675yl * and mode.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @devh: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @pci_mode: pointer to a variable of enumerated type
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_pci_mode_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @bus_frequency: pointer to a variable of enumerated type
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_pci_bus_frequency_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @bus_width: pointer to a variable of enumerated type
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_pci_bus_width_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Get pci mode, frequency, and PCI bus width.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: one of the xge_hal_status_e{} enumerated types.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_OK - for success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_INVALID_PCI_INFO - for invalid PCI information from the card.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_BAD_DEVICE_ID - for invalid card.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See Also: xge_hal_pci_mode_e, xge_hal_pci_mode_e, xge_hal_pci_width_e.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic xge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_pci_info_get(xge_hal_device_h devh, xge_hal_pci_mode_e *pci_mode,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bus_frequency_e *bus_frequency,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bus_width_e *bus_width)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e rc_status = XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_card_e card_id = xge_hal_device_check_id (devh);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_HERC_EMULATION
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.pci_freq_mherz =
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PCI_BUS_FREQUENCY_66MHZ;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_frequency =
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PCI_BUS_FREQUENCY_66MHZ;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *pci_mode = XGE_HAL_PCI_66MHZ_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl#else
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (card_id == XGE_HAL_CARD_HERC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 =
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 pci_info = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->pci_info);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (XGE_HAL_PCI_32_BIT & pci_info)
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_width = XGE_HAL_PCI_BUS_WIDTH_32BIT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl else
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_width = XGE_HAL_PCI_BUS_WIDTH_64BIT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl switch((pci_info & XGE_HAL_PCI_INFO)>>60)
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCI_33MHZ_MODE:
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_frequency =
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PCI_BUS_FREQUENCY_33MHZ;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *pci_mode = XGE_HAL_PCI_33MHZ_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCI_66MHZ_MODE:
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_frequency =
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PCI_BUS_FREQUENCY_66MHZ;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *pci_mode = XGE_HAL_PCI_66MHZ_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCIX_M1_66MHZ_MODE:
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_frequency =
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PCI_BUS_FREQUENCY_66MHZ;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *pci_mode = XGE_HAL_PCIX_M1_66MHZ_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCIX_M1_100MHZ_MODE:
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_frequency =
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PCI_BUS_FREQUENCY_100MHZ;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *pci_mode = XGE_HAL_PCIX_M1_100MHZ_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCIX_M1_133MHZ_MODE:
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_frequency =
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PCI_BUS_FREQUENCY_133MHZ;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *pci_mode = XGE_HAL_PCIX_M1_133MHZ_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCIX_M2_66MHZ_MODE:
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_frequency =
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PCI_BUS_FREQUENCY_133MHZ;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *pci_mode = XGE_HAL_PCIX_M2_66MHZ_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCIX_M2_100MHZ_MODE:
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_frequency =
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PCI_BUS_FREQUENCY_200MHZ;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *pci_mode = XGE_HAL_PCIX_M2_100MHZ_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCIX_M2_133MHZ_MODE:
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_frequency =
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PCI_BUS_FREQUENCY_266MHZ;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *pci_mode = XGE_HAL_PCIX_M2_133MHZ_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCIX_M1_RESERVED:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCIX_M1_66MHZ_NS:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCIX_M1_100MHZ_NS:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCIX_M1_133MHZ_NS:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCIX_M2_RESERVED:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_PCIX_533_RESERVED:
a23fd118e437af0a7877dd313db8fdaa3537c675yl default:
a23fd118e437af0a7877dd313db8fdaa3537c675yl rc_status = XGE_HAL_ERR_INVALID_PCI_INFO;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "invalid pci info %llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)pci_info);
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (rc_status != XGE_HAL_ERR_INVALID_PCI_INFO)
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "PCI info: mode %d width "
a23fd118e437af0a7877dd313db8fdaa3537c675yl "%d frequency %d", *pci_mode, *bus_width,
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_frequency);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.pci_freq_mherz = *bus_frequency;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* for XENA, we report PCI mode, only. PCI bus frequency, and bus width
a23fd118e437af0a7877dd313db8fdaa3537c675yl * are set to unknown */
a23fd118e437af0a7877dd313db8fdaa3537c675yl else if (card_id == XGE_HAL_CARD_XENA) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl u32 pcix_status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u8 dev_num, bus_num;
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* initialize defaults for XENA */
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_frequency = XGE_HAL_PCI_BUS_FREQUENCY_UNKNOWN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_width = XGE_HAL_PCI_BUS_WIDTH_UNKNOWN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read32(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, pcix_status),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &pcix_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl dev_num = (u8)((pcix_status & 0xF8) >> 3);
a23fd118e437af0a7877dd313db8fdaa3537c675yl bus_num = (u8)((pcix_status & 0xFF00) >> 8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (dev_num == 0 && bus_num == 0)
a23fd118e437af0a7877dd313db8fdaa3537c675yl *pci_mode = XGE_HAL_PCI_BASIC_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl else
a23fd118e437af0a7877dd313db8fdaa3537c675yl *pci_mode = XGE_HAL_PCIX_BASIC_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "PCI info: mode %d", *pci_mode);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.pci_freq_mherz ==
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEFAULT_USE_HARDCODE) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * There is no way to detect BUS frequency on Xena,
a23fd118e437af0a7877dd313db8fdaa3537c675yl * so, in case of automatic configuration we hopelessly
a23fd118e437af0a7877dd313db8fdaa3537c675yl * assume 133MHZ.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.pci_freq_mherz =
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PCI_BUS_FREQUENCY_133MHZ;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else{
a23fd118e437af0a7877dd313db8fdaa3537c675yl rc_status = XGE_HAL_ERR_BAD_DEVICE_ID;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "invalid device id %d", card_id);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return rc_status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_handle_link_up_ind
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Link up indication handler. The function is invoked by HAL when
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Xframe indicates that the link is up for programmable amount of time.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic int
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_link_up_ind(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * If the previous link state is not down, return.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->link_state == XGE_HAL_LINK_UP) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC){
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->misc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_MISC_INT_REG_LINK_UP_INT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~XGE_HAL_MISC_INT_REG_LINK_DOWN_INT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->misc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "link up indication while link is up, ignoring..");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Now re-enable it as due to noise, hardware turned it off */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_ADAPTER_CNTL_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = val64 & (~XGE_HAL_ADAPTER_ECC_EN); /* ECC enable */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Turn on the Laser */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = val64|(XGE_HAL_ADAPTER_EOI_TX_ON |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_LED_ON);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s",
a23fd118e437af0a7877dd313db8fdaa3537c675yl "fail to transition link to up...");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Mask the Link Up interrupt and unmask the Link Down
a23fd118e437af0a7877dd313db8fdaa3537c675yl * interrupt.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->misc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_MISC_INT_REG_LINK_UP_INT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~XGE_HAL_MISC_INT_REG_LINK_DOWN_INT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->misc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "calling link up..");
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->link_state = XGE_HAL_LINK_UP;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* notify ULD */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (g_xge_hal_driver->uld_callbacks.link_up) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->uld_callbacks.link_up(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->upper_layer_info);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl return 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev, &bar0->adapter_status, 0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT),
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_FAULT_WAIT_MAX_MILLIS) == XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* notify ULD */
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_queue_produce_context(hldev->queueh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_EVENT_LINK_IS_UP,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* link is up after been enabled */
a23fd118e437af0a7877dd313db8fdaa3537c675yl return 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s",
a23fd118e437af0a7877dd313db8fdaa3537c675yl "fail to transition link to up...");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_handle_link_down_ind
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Link down indication handler. The function is invoked by HAL when
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Xframe indicates that the link is down.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic int
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_link_down_ind(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * If the previous link state is not up, return.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->link_state == XGE_HAL_LINK_DOWN) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC){
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->misc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_MISC_INT_REG_LINK_DOWN_INT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~XGE_HAL_MISC_INT_REG_LINK_UP_INT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->misc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "link down indication while link is down, ignoring..");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* try to debounce the link only if the adapter is enabled. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_ADAPTER_CNTL_EN) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev, &bar0->adapter_status, 0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT),
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_FAULT_WAIT_MAX_MILLIS) == XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "link is actually up (possible noisy link?), ignoring.");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return(0);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* turn off LED */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = val64 & (~XGE_HAL_ADAPTER_LED_ON);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Mask the Link Down interrupt and unmask the Link up
a23fd118e437af0a7877dd313db8fdaa3537c675yl * interrupt
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->misc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_MISC_INT_REG_LINK_DOWN_INT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~XGE_HAL_MISC_INT_REG_LINK_UP_INT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->misc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* link is down */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "calling link down..");
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->link_state = XGE_HAL_LINK_DOWN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* notify ULD */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (g_xge_hal_driver->uld_callbacks.link_down) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->uld_callbacks.link_down(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->upper_layer_info);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl return 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* notify ULD */
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_queue_produce_context(hldev->queueh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_EVENT_LINK_IS_DOWN,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* link is down */
a23fd118e437af0a7877dd313db8fdaa3537c675yl return 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_handle_link_state_change
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Link state change handler. The function is invoked by HAL when
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Xframe indicates link state change condition. The code here makes sure to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * 1) ignore redundant state change indications;
a23fd118e437af0a7877dd313db8fdaa3537c675yl * 2) execute link-up sequence, and handle the failure to bring the link up;
a23fd118e437af0a7877dd313db8fdaa3537c675yl * 3) generate XGE_HAL_LINK_UP/DOWN event for the subsequent handling by
a23fd118e437af0a7877dd313db8fdaa3537c675yl * upper-layer driver (ULD).
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic int
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_link_state_change(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 hw_status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int hw_link_state;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int retcode;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* If the adapter is not enabled but the hal thinks we are in the up
a23fd118e437af0a7877dd313db8fdaa3537c675yl * state then transition to the down state.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ( !(val64 & XGE_HAL_ADAPTER_CNTL_EN) &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl (hldev->link_state == XGE_HAL_LINK_UP) ) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return(__hal_device_handle_link_down_ind(hldev));
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_hal_device_status(hldev, &hw_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl hw_link_state = (hw_status &
a23fd118e437af0a7877dd313db8fdaa3537c675yl (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)) ?
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_LINK_DOWN : XGE_HAL_LINK_UP;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* If the current link state is same as previous, just return */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->link_state == hw_link_state)
a23fd118e437af0a7877dd313db8fdaa3537c675yl retcode = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* detected state change */
a23fd118e437af0a7877dd313db8fdaa3537c675yl else if (hw_link_state == XGE_HAL_LINK_UP)
a23fd118e437af0a7877dd313db8fdaa3537c675yl retcode = __hal_device_handle_link_up_ind(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl else
a23fd118e437af0a7877dd313db8fdaa3537c675yl retcode = __hal_device_handle_link_down_ind(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return retcode;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_serr(xge_hal_device_t *hldev, char *reg, u64 value)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_err_stats.serr_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.dump_on_serr) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_USE_MGMT_AUX
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_hal_aux_device_dump(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_queue_produce(hldev->queueh, XGE_HAL_EVENT_SERR, hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 1, sizeof(u64), (void *)&value);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "%s: read %llx", reg,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long) value);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_eccerr(xge_hal_device_t *hldev, char *reg, u64 value)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.dump_on_eccerr) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_USE_MGMT_AUX
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_hal_aux_device_dump(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Herc smart enough to recover on its own! */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_queue_produce(hldev->queueh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_EVENT_ECCERR, hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 1, sizeof(u64), (void *)&value);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "%s: read %llx", reg,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long) value);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_parityerr(xge_hal_device_t *hldev, char *reg, u64 value)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.dump_on_parityerr) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_USE_MGMT_AUX
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_hal_aux_device_dump(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_queue_produce_context(hldev->queueh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_EVENT_PARITYERR, hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "%s: read %llx", reg,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long) value);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_targetabort(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_queue_produce_context(hldev->queueh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_EVENT_TARGETABORT, hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_hw_initialize
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Initialize Xframe hardware.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic xge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_hw_initialize(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Set proper endian settings and verify the same by reading the PIF
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Feed-back register. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_device_set_swapper(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* update the pci mode, frequency, and width */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_pci_info_get(hldev, &hldev->pci_mode,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &hldev->bus_frequency, &hldev->bus_width) != XGE_HAL_OK){
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->pci_mode = XGE_HAL_PCI_INVALID_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->bus_frequency = XGE_HAL_PCI_BUS_FREQUENCY_UNKNOWN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->bus_width = XGE_HAL_PCI_BUS_WIDTH_UNKNOWN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * FIXME: this cannot happen.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * But if it happens we cannot continue just like that
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "unable to get pci info");
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((hldev->pci_mode == XGE_HAL_PCI_33MHZ_MODE) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (hldev->pci_mode == XGE_HAL_PCI_66MHZ_MODE) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (hldev->pci_mode == XGE_HAL_PCI_BASIC_MODE)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* PCI optimization: set TxReqTimeOut
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register (0x800+0x120) to 0x1ff or
a23fd118e437af0a7877dd313db8fdaa3537c675yl * something close to this.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Note: not to be used for PCI-X! */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_TXREQTO_VAL(0x1FF);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_TXREQTO_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->txreqtimeout);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->read_retry_delay);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0ULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->write_retry_delay);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "optimizing for PCI mode");
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* added this to clear the EOI_RESET field while leaving XGXS_RESET
a23fd118e437af0a7877dd313db8fdaa3537c675yl * in reset, then a 1-second delay */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SW_RESET_XGXS, &bar0->sw_reset);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1000);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Clear the XGXS_RESET field of the SW_RESET register in order to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * release the XGXS from reset. Its reset value is 0xA5; write 0x00
a23fd118e437af0a7877dd313db8fdaa3537c675yl * to activate the XGXS. The core requires a minimum 500 us reset.*/
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 0, &bar0->sw_reset);
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->sw_reset);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* read registers in all blocks */
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mac_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mc_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->xgxs_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* set default MTU and steer based on length*/
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_ring_mtu_set(hldev, hldev->config.mtu+22); // Alway set 22 bytes extra for steering to work
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.mac.rmac_bcast_en) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_bcast_enable(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_bcast_disable(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifndef XGE_HAL_HERC_EMULATION
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_xaui_configure(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_mac_link_util_set(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_mac_link_util_set(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Keep its PCI REQ# line asserted during a write
a23fd118e437af0a7877dd313db8fdaa3537c675yl * transaction up to the end of the transaction
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->misc_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_MISC_CONTROL_EXT_REQ_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->misc_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Initialize the device tti registers only if the TTI feature is
a23fd118e437af0a7877dd313db8fdaa3537c675yl * enabled.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.tti.enabled) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((status = __hal_device_tti_configure(hldev)) !=
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_device_rti_configure(hldev, 0);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_device_rth_it_configure(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_device_rth_spdm_configure(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_device_rts_mac_configure(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "__hal_device_rts_mac_configure Failed \n");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_pause_frames_configure(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_rmac_padding_configure(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_shared_splits_configure(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* make sure all interrupts going to be disabled at the moment */
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_intr_mgmt(hldev, XGE_HAL_ALL_INTRS, 0);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* SXE-008 Transmit DMA arbitration issue */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->revision < 4) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev,hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_PCC_ENABLE_FOUR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->pcc_enable);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_fifo_hw_initialize(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_ring_hw_initialize(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_wait_quiescent(hldev, &val64)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev, &bar0->adapter_status, 1,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_RC_PRC_QUIESCENT,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_QUIESCENT_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "PRC is not QUIESCENT!");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "device 0x%llx is quiescent",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)(ulong_t)hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_MSI)
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * If MSI is enabled, ensure that One Shot for MSI in PCI_CTRL
a23fd118e437af0a7877dd313db8fdaa3537c675yl * is disabled.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->pic_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~(XGE_HAL_PIC_CNTL_ONE_SHOT_TINT);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->pic_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->hw_is_initialized = 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->terminating = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_reset - Reset device only.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Reset the device, and subsequently restore
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the previously saved PCI configuration space.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic xge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_reset(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i, swap_done, pcisize = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64, rawval = 0ULL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_MSI_X)
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Restore MSI-X vector table */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ( hldev->bar2 ) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 *msix_vetor_table = (u64 *)hldev->bar2;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl // 2 64bit words for each entry
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i = 0; i < XGE_HAL_MAX_MSIX_MESSAGES * 2; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->msix_vector_table[i] = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh2, &msix_vetor_table[i]);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->pif_rd_swapper_fb);
a23fd118e437af0a7877dd313db8fdaa3537c675yl swap_done = (val64 == XGE_HAL_IF_RD_SWAPPER_FB);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (swap_done) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u32)(XGE_HAL_SW_RESET_ALL>>32), (char *)&bar0->sw_reset);
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl u32 val = (u32)(XGE_HAL_SW_RESET_ALL >> 32);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_OS_HOST_LITTLE_ENDIAN) || defined(XGE_OS_PIO_LITTLE_ENDIAN)
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* swap it */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val = (((val & (u32)0x000000ffUL) << 24) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl ((val & (u32)0x0000ff00UL) << 8) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl ((val & (u32)0x00ff0000UL) >> 8) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl ((val & (u32)0xff000000UL) >> 24));
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write32(hldev->pdev, hldev->regh0, val,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->sw_reset);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl int cnt = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl rawval = XGE_HAL_SW_RESET_RAW_VAL_HERC;
a23fd118e437af0a7877dd313db8fdaa3537c675yl pcisize = XGE_HAL_PCISIZE_HERC;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl do {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->sw_reset);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 != rawval) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1); /* Wait for 1ms before retry */
a23fd118e437af0a7877dd313db8fdaa3537c675yl } while(cnt < 20);
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl rawval = XGE_HAL_SW_RESET_RAW_VAL_XENA;
a23fd118e437af0a7877dd313db8fdaa3537c675yl pcisize = XGE_HAL_PCISIZE_XENA;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(XGE_HAL_DEVICE_RESET_WAIT_MAX_MILLIS);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i = 0; i < pcisize; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_write32(hldev->pdev, hldev->cfgh, i * 4,
a23fd118e437af0a7877dd313db8fdaa3537c675yl *((u32*)&hldev->pci_config_space + i));
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_MSI_X)
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Restore MSI-X vector table */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ( hldev->bar2 ) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl 94: MSIXTable 00000004 ( BIR:4 Offset:0x0 )
a23fd118e437af0a7877dd313db8fdaa3537c675yl 98: PBATable 00000404 ( BIR:4 Offset:0x400 )
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 *msix_vetor_table = (u64 *)hldev->bar2;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl //xge_os_pci_read16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl //xge_offsetof(xge_hal_pci_config_le_t, subsystem_id), &subid);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl // 2 64bit words for each entry
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i = 0; i < XGE_HAL_MAX_MSIX_MESSAGES * 2; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh2,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->msix_vector_table[i], &msix_vetor_table[i]);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->link_state = XGE_HAL_LINK_DOWN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->sw_reset);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 != rawval) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "device has not been reset "
a23fd118e437af0a7877dd313db8fdaa3537c675yl "got 0x%llx, expected 0x%llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)val64, (unsigned long long)rawval);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_RESET_FAILED;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->hw_is_initialized = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_poll - General private routine to poll the device.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: one of the xge_hal_status_e{} enumerated types.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_OK - for success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_CRITICAL - when encounters critical error.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic xge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_poll(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 err_reg;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Handling SERR errors by forcing a H/W reset. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl err_reg = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->serr_source);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (err_reg & XGE_HAL_SERR_SOURCE_ANY) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_handle_serr(hldev, "serr_source", err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_CRITICAL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl err_reg = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->misc_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (err_reg & XGE_HAL_MISC_INT_REG_DP_ERR_INT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_err_stats.parity_err_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_handle_parityerr(hldev, "misc_int_reg", err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_CRITICAL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Handling link status change error Intr */
a23fd118e437af0a7877dd313db8fdaa3537c675yl err_reg = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mac_rmac_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_handle_link_state_change(hldev))
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl err_reg, &bar0->mac_rmac_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->inject_serr != 0) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl err_reg = hldev->inject_serr;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->inject_serr = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_handle_serr(hldev, "inject_serr", err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_CRITICAL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->inject_ecc != 0) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl err_reg = hldev->inject_ecc;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->inject_ecc = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_err_stats.ecc_err_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_handle_eccerr(hldev, "inject_ecc", err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_CRITICAL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->inject_bad_tcode != 0) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl u8 t_code = hldev->inject_bad_tcode;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_channel_t channel;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_fifo_txd_t txd;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_ring_rxd_1_t rxd;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl channel.devh = hldev;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->inject_bad_tcode_for_chan_type ==
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_CHANNEL_TYPE_FIFO) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl channel.type = XGE_HAL_CHANNEL_TYPE_FIFO;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl channel.type = XGE_HAL_CHANNEL_TYPE_RING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->inject_bad_tcode = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (channel.type == XGE_HAL_CHANNEL_TYPE_FIFO)
a23fd118e437af0a7877dd313db8fdaa3537c675yl return xge_hal_device_handle_tcode(&channel, &txd,
a23fd118e437af0a7877dd313db8fdaa3537c675yl t_code);
a23fd118e437af0a7877dd313db8fdaa3537c675yl else
a23fd118e437af0a7877dd313db8fdaa3537c675yl return xge_hal_device_handle_tcode(&channel, &rxd,
a23fd118e437af0a7877dd313db8fdaa3537c675yl t_code);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_verify_pcc_idle - Verify All Enbled PCC are IDLE or not
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @adp_status: Adapter Status value
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Usage: See xge_hal_device_enable{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_verify_pcc_idle(xge_hal_device_t *hldev, u64 adp_status)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->revision < 4) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * For Xena 1,2,3 we enable only 4 PCCs Due to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * SXE-008 (Transmit DMA arbitration issue)
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((adp_status & XGE_HAL_ADAPTER_STATUS_RMAC_PCC_4_IDLE)
a23fd118e437af0a7877dd313db8fdaa3537c675yl != XGE_HAL_ADAPTER_STATUS_RMAC_PCC_4_IDLE) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s",
a23fd118e437af0a7877dd313db8fdaa3537c675yl "PCC is not IDLE after adapter enabled!");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((adp_status & XGE_HAL_ADAPTER_STATUS_RMAC_PCC_IDLE) !=
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_RMAC_PCC_IDLE) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s",
a23fd118e437af0a7877dd313db8fdaa3537c675yl "PCC is not IDLE after adapter enabled!");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_update_rxufca(xge_hal_device_t *hldev, int ring_no)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl int ufc = hldev->config.ring.queue[ring_no].rti.ufc_a;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int ic = hldev->stats.sw_dev_info_stats.total_intr_cnt -
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_info_stats.not_traffic_intr_cnt;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* urange_a adaptive coalescing */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->rxufca_lbolt > hldev->rxufca_lbolt_time) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (ic > hldev->rxufca_intr_thres) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (ufc < hldev->config.rxufca_hi_lim) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl ufc += 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i=0; i<XGE_HAL_MAX_RING_NUM; i++)
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.ring.queue[i].rti.ufc_a = ufc;
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) __hal_device_rti_configure(hldev, 1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_info_stats.
a23fd118e437af0a7877dd313db8fdaa3537c675yl rxufca_hi_adjust_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->rxufca_intr_thres = ic +
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.rxufca_intr_thres; /* def: 30 */
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (ufc > hldev->config.rxufca_lo_lim) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl ufc -= 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i=0; i<XGE_HAL_MAX_RING_NUM; i++)
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.ring.queue[i].rti.ufc_a = ufc;
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) __hal_device_rti_configure(hldev, 1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_info_stats.
a23fd118e437af0a7877dd313db8fdaa3537c675yl rxufca_lo_adjust_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->rxufca_lbolt_time = hldev->rxufca_lbolt +
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.rxufca_lbolt_period;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->rxufca_lbolt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_handle_mc - Handle MC interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @reason: interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_mc(xge_hal_device_t *hldev, u64 reason)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *isrbar0 =
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->mc_int_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(val64 & XGE_HAL_MC_INT_STATUS_MC_INT))
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->mc_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &isrbar0->mc_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_SG_ERR_L ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_SG_ERR_U ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_SG_ERR_0 ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_SG_ERR_1 ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_XENA &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl (val64 & XGE_HAL_MC_ERR_REG_ITQ_ECC_SG_ERR_L ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 & XGE_HAL_MC_ERR_REG_ITQ_ECC_SG_ERR_U ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 & XGE_HAL_MC_ERR_REG_RLD_ECC_SG_ERR_L ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 & XGE_HAL_MC_ERR_REG_RLD_ECC_SG_ERR_U))) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_err_stats.single_ecc_err_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_err_stats.ecc_err_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_DB_ERR_L ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_DB_ERR_U ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_DB_ERR_0 ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_DB_ERR_1 ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_device_check_id(hldev) != XGE_HAL_CARD_XENA &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl (val64 & XGE_HAL_MC_ERR_REG_ITQ_ECC_DB_ERR_L ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 & XGE_HAL_MC_ERR_REG_ITQ_ECC_DB_ERR_U ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 & XGE_HAL_MC_ERR_REG_RLD_ECC_DB_ERR_L ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 & XGE_HAL_MC_ERR_REG_RLD_ECC_DB_ERR_U))) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_err_stats.double_ecc_err_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_err_stats.ecc_err_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_MC_ERR_REG_SM_ERR) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_err_stats.sm_err_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* those two should result in device reset */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_DB_ERR_0 ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 & XGE_HAL_MC_ERR_REG_MIRI_ECC_DB_ERR_1) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_handle_eccerr(hldev, "mc_err_reg", val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_CRITICAL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_handle_pic - Handle non-traffic PIC interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @reason: interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_pic(xge_hal_device_t *hldev, u64 reason)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *isrbar0 =
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (reason & XGE_HAL_PIC_INT_FLSH) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->flsh_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &isrbar0->flsh_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (reason & XGE_HAL_PIC_INT_MDIO) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->mdio_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &isrbar0->mdio_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (reason & XGE_HAL_PIC_INT_IIC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->iic_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &isrbar0->iic_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (reason & XGE_HAL_PIC_INT_MISC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, &isrbar0->misc_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_PROCESS_LINK_INT_IN_ISR
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Check for Link interrupts. If both Link Up/Down
a23fd118e437af0a7877dd313db8fdaa3537c675yl * bits are set, clear both and check adapter status
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((val64 & XGE_HAL_MISC_INT_REG_LINK_UP_INT) &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl (val64 & XGE_HAL_MISC_INT_REG_LINK_DOWN_INT)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 temp64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "both link up and link down detected %llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 = (XGE_HAL_MISC_INT_REG_LINK_DOWN_INT |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_MISC_INT_REG_LINK_UP_INT);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, temp64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->misc_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl else if (val64 & XGE_HAL_MISC_INT_REG_LINK_UP_INT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "link up call request, misc_int %llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_handle_link_up_ind(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl else if (val64 & XGE_HAL_MISC_INT_REG_LINK_DOWN_INT){
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "link down request, misc_int %llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_handle_link_down_ind(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &isrbar0->misc_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_handle_txpic - Handle TxPIC interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @reason: interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_txpic(xge_hal_device_t *hldev, u64 reason)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e status = XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *isrbar0 =
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl volatile u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->pic_int_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ( val64 & (XGE_HAL_PIC_INT_FLSH |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PIC_INT_MDIO |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PIC_INT_IIC |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_PIC_INT_MISC) ) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_device_handle_pic(hldev, val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_wmb();
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(val64 & XGE_HAL_PIC_INT_TX))
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->txpic_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &isrbar0->txpic_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_wmb();
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_TXPIC_INT_SCHED_INTR) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (g_xge_hal_driver->uld_callbacks.sched_timer != NULL)
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->uld_callbacks.sched_timer(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev, hldev->upper_layer_info);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This feature implement adaptive receive interrupt
a23fd118e437af0a7877dd313db8fdaa3537c675yl * coalecing. It is disabled by default. To enable it
a23fd118e437af0a7877dd313db8fdaa3537c675yl * set hldev->config.rxufca_lo_lim to be not equal to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * hldev->config.rxufca_hi_lim.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * We are using HW timer for this feature, so
a23fd118e437af0a7877dd313db8fdaa3537c675yl * use needs to configure hldev->config.rxufca_lbolt_period
a23fd118e437af0a7877dd313db8fdaa3537c675yl * which is essentially a time slice of timer.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * For those who familiar with Linux, lbolt means jiffies
a23fd118e437af0a7877dd313db8fdaa3537c675yl * of this timer. I.e. timer tick.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.ring.queue[i].rti.urange_a) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.rxufca_lo_lim !=
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.rxufca_hi_lim)
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_update_rxufca(hldev, i);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_handle_txdma - Handle TxDMA interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @reason: interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_txdma(xge_hal_device_t *hldev, u64 reason)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *isrbar0 =
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64, err;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->txdma_int_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_TXDMA_PFC_INT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->pfc_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl err, &isrbar0->pfc_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_TXDMA_TDA_INT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->tda_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl err, &isrbar0->tda_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_TXDMA_PCC_INT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->pcc_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl err, &isrbar0->pcc_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_TXDMA_TTI_INT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->tti_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl err, &isrbar0->tti_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_TXDMA_LSO_INT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->lso_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl err, &isrbar0->lso_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_TXDMA_TPA_INT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->tpa_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl err, &isrbar0->tpa_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_TXDMA_SM_INT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->sm_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl err, &isrbar0->sm_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_handle_txmac - Handle TxMAC interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @reason: interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_txmac(xge_hal_device_t *hldev, u64 reason)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *isrbar0 =
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->mac_int_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(val64 & XGE_HAL_MAC_INT_STATUS_TMAC_INT))
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->mac_tmac_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &isrbar0->mac_tmac_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_handle_txxgxs - Handle TxXGXS interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @reason: interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_txxgxs(xge_hal_device_t *hldev, u64 reason)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_handle_rxpic - Handle RxPIC interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @reason: interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_rxpic(xge_hal_device_t *hldev, u64 reason)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_handle_rxdma - Handle RxDMA interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @reason: interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_rxdma(xge_hal_device_t *hldev, u64 reason)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *isrbar0 =
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64, err;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->rxdma_int_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_RXDMA_RC_INT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->rc_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl err, &isrbar0->rc_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_RXDMA_RPA_INT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->rpa_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl err, &isrbar0->rpa_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_RXDMA_RDA_INT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->rda_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl err, &isrbar0->rda_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_RXDMA_RTI_INT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl err = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->rti_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl err, &isrbar0->rti_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_handle_rxmac - Handle RxMAC interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @reason: interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_rxmac(xge_hal_device_t *hldev, u64 reason)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *isrbar0 =
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_pci_bar0_t *)(void *)hldev->isrbar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->mac_int_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(val64 & XGE_HAL_MAC_INT_STATUS_RMAC_INT))
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &isrbar0->mac_rmac_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &isrbar0->mac_rmac_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_handle_rxxgxs - Handle RxXGXS interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @reason: interrupt reason
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_device_handle_rxxgxs(xge_hal_device_t *hldev, u64 reason)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* FIXME: handle register */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_enable - Enable device.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Enable the specified device: bring up the link/interface.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: XGE_HAL_OK - success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT - Failed to restore the device
a23fd118e437af0a7877dd313db8fdaa3537c675yl * to a "quiescent" state.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_status_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Usage: See ex_open{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_enable(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 adp_status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i, j;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->hw_is_initialized) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_device_hw_initialize(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Not needed in most cases, i.e.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * when device_disable() is followed by reset -
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the latter copies back PCI config space, along with
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the bus mastership - see __hal_device_reset().
a23fd118e437af0a7877dd313db8fdaa3537c675yl * However, there are/may-in-future be other cases, and
a23fd118e437af0a7877dd313db8fdaa3537c675yl * does not hurt.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_bus_master_enable(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Configure the link stability period.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->misc_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.link_stability_period !=
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEFAULT_USE_HARDCODE) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_MISC_CONTROL_LINK_STABILITY_PERIOD(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.link_stability_period);
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Use the link stability period 1 ms as default
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_MISC_CONTROL_LINK_STABILITY_PERIOD(
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEFAULT_LINK_STABILITY_PERIOD);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->misc_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Clearing any possible Link up/down interrupts that
a23fd118e437af0a7877dd313db8fdaa3537c675yl * could have popped up just before Enabling the card.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->misc_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->misc_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s","link state cleared");
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Clearing any possible Link state change interrupts that
a23fd118e437af0a7877dd313db8fdaa3537c675yl * could have popped up just before Enabling the card.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mac_rmac_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->mac_rmac_err_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "link state cleared");
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_wait_quiescent(hldev, &val64)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Enabling Laser. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_ADAPTER_EOI_TX_ON;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* let link establish */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* set link down untill poll() routine will set it up (maybe) */
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->link_state = XGE_HAL_LINK_DOWN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* If link is UP (adpter is connected) then enable the adapter */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if( val64 & (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT) ) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = val64 & (~XGE_HAL_ADAPTER_LED_ON);
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = val64 | ( XGE_HAL_ADAPTER_EOI_TX_ON |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_LED_ON );
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = val64 | XGE_HAL_ADAPTER_CNTL_EN; /* adapter enable */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = val64 & (~XGE_HAL_ADAPTER_ECC_EN); /* ECC enable */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64 (hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* We spin here waiting for the Link to come up.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This is the fix for the Link being unstable after the reset. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl i = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl j = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl do
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl adp_status = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Read the adapter control register for Adapter_enable bit */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(adp_status & (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)) &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl (val64 & XGE_HAL_ADAPTER_CNTL_EN)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl j++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (j >= hldev->config.link_valid_cnt) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_status(hldev, &adp_status) ==
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_verify_pcc_idle(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl adp_status) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "adp_status: %llx, link is up on "
a23fd118e437af0a7877dd313db8fdaa3537c675yl "adapter enable!",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)adp_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = val64|
a23fd118e437af0a7877dd313db8fdaa3537c675yl (XGE_HAL_ADAPTER_EOI_TX_ON |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_LED_ON );
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl break; /* out of for loop */
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl j = 0; /* Reset the count */
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Turn on the Laser */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = val64 | XGE_HAL_ADAPTER_EOI_TX_ON;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64 (hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Now re-enable it as due to noise, hardware
a23fd118e437af0a7877dd313db8fdaa3537c675yl * turned it off */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_ADAPTER_CNTL_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = val64 & (~XGE_HAL_ADAPTER_ECC_EN);/*ECC enable*/
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1); /* Sleep for 1 msec */
a23fd118e437af0a7877dd313db8fdaa3537c675yl i++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl } while (i < hldev->config.link_retry_cnt);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_led_actifity_fix(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifndef XGE_HAL_PROCESS_LINK_INT_IN_ISR
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Here we are performing soft reset on XGXS to force link down.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Since link is already up, we will get link state change
a23fd118e437af0a7877dd313db8fdaa3537c675yl * poll notificatoin after adapter is enabled */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80010515001E0000ULL, &bar0->dtx_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->dtx_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1); /* Sleep for 1 msec */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80010515001E00E0ULL, &bar0->dtx_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->dtx_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(1); /* Sleep for 1 msec */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0x80070515001F00E4ULL, &bar0->dtx_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->dtx_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(100); /* Sleep for 500 msec */
a23fd118e437af0a7877dd313db8fdaa3537c675yl#else
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * With some switches the link state change interrupt does not
a23fd118e437af0a7877dd313db8fdaa3537c675yl * occur even though the xgxs reset is done as per SPN-006. So,
a23fd118e437af0a7877dd313db8fdaa3537c675yl * poll the adapter status register and check if the link state
a23fd118e437af0a7877dd313db8fdaa3537c675yl * is ok.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl adp_status = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(adp_status & (XGE_HAL_ADAPTER_STATUS_RMAC_REMOTE_FAULT |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT)))
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s",
a23fd118e437af0a7877dd313db8fdaa3537c675yl "enable device causing link state change ind..");
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) __hal_device_handle_link_state_change(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.stats_refresh_time_sec !=
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_STATS_REFRESH_DISABLE)
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_stats_enable(&hldev->stats);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_disable - Disable Xframe adapter.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: Device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Disable this device. To gracefully reset the adapter, the host should:
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - call xge_hal_device_disable();
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - call xge_hal_device_intr_disable();
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - close all opened channels and clean up outstanding resources;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - do some work (error recovery, change mtu, reset, etc);
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - call xge_hal_device_enable();
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - open channels, replenish RxDs, etc.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - call xge_hal_device_intr_enable().
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Note: Disabling the device does _not_ include disabling of interrupts.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * After disabling the device stops receiving new frames but those frames
a23fd118e437af0a7877dd313db8fdaa3537c675yl * that were already in the pipe will keep coming for some few milliseconds.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: XGE_HAL_OK - success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT - Failed to restore the device to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * a "quiescent" state.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_status_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_disable(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e status = XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "turn off laser, cleanup hardware");
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = val64 & (~XGE_HAL_ADAPTER_CNTL_EN);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_wait_quiescent(hldev, &val64) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev, &bar0->adapter_status, 1,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_ADAPTER_STATUS_RC_PRC_QUIESCENT,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_QUIESCENT_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "PRC is not QUIESCENT!");
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.stats_refresh_time_sec !=
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_STATS_REFRESH_DISABLE)
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_stats_disable(&hldev->stats);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_DEBUG_ASSERT
a23fd118e437af0a7877dd313db8fdaa3537c675yl else
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(!hldev->stats.is_enabled);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_bus_master_disable(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_reset - Reset device.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Soft-reset the device, reset the device stats except reset_cnt.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * After reset is done, will try to re-initialize HW.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: XGE_HAL_OK - success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_DEVICE_NOT_INITIALIZED - Device is not initialized.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_RESET_FAILED - Reset failed.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_status_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_reset(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* increment the soft reset counter */
a23fd118e437af0a7877dd313db8fdaa3537c675yl u32 reset_cnt = hldev->stats.sw_dev_info_stats.soft_reset_cnt;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "%s (%d)", "resetting the device", reset_cnt);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->is_initialized)
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_DEVICE_NOT_INITIALIZED;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* actual "soft" reset of the adapter */
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_device_reset(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* reset all stats including saved */
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_stats_soft_reset(hldev, 1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* increment reset counter */
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_info_stats.soft_reset_cnt = reset_cnt + 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* re-initialize rxufca_intr_thres */
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->rxufca_intr_thres = hldev->config.rxufca_intr_thres;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->reset_needed_after_close = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_status - Check whether Xframe hardware is ready for
a23fd118e437af0a7877dd313db8fdaa3537c675yl * operation.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hw_status: Xframe status register. Returned by HAL.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Check whether Xframe hardware is ready for operation.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * The checking includes TDMA, RDMA, PFC, PIC, MC_DRAM, and the rest
a23fd118e437af0a7877dd313db8fdaa3537c675yl * hardware functional blocks.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: XGE_HAL_OK if the device is ready for operation. Otherwise
a23fd118e437af0a7877dd313db8fdaa3537c675yl * returns XGE_HAL_FAIL. Also, fills in adapter status (in @hw_status).
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_status_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Usage: See ex_open{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_status(xge_hal_device_t *hldev, u64 *hw_status)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 tmp64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl tmp64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_status);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_TDMA_READY)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "TDMA is not ready!");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_FAIL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_RDMA_READY)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "RDMA is not ready!");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_FAIL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_PFC_READY)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "PFC is not ready!");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_FAIL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_TMAC_BUF_EMPTY)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "TMAC BUF is not empty!");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_FAIL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_PIC_QUIESCENT)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "PIC is not QUIESCENT!");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_FAIL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_MC_DRAM_READY)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "MC_DRAM is not ready!");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_FAIL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_MC_QUEUES_READY)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "MC_QUEUES is not ready!");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_FAIL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_M_PLL_LOCK)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "M_PLL is not locked!");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_FAIL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_P_PLL_LOCK)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "P_PLL is not locked!");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_FAIL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl *hw_status = tmp64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_intr_enable - Enable Xframe interrupts.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @op: One of the xge_hal_device_intr_e enumerated values specifying
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the type(s) of interrupts to enable.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Enable Xframe interrupts. The function is to be executed the last in
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Xframe initialization sequence.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_intr_disable()
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_intr_enable(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_list_t *item;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* PRC initialization and configuration */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_list_for_each(item, &hldev->ring_channels) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_channel_h channel;
a23fd118e437af0a7877dd313db8fdaa3537c675yl channel = xge_container_of(item, xge_hal_channel_t, item);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_ring_prc_enable(channel);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* enable traffic only interrupts */
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_MSI)
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * make sure all interrupts going to be disabled if MSI
a23fd118e437af0a7877dd313db8fdaa3537c675yl * is enabled.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_intr_mgmt(hldev, XGE_HAL_ALL_INTRS, 0);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#else
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Enable the Tx traffic interrupts only if the TTI feature is
a23fd118e437af0a7877dd313db8fdaa3537c675yl * enabled.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.tti.enabled) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_TX_TRAFFIC_INTR;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RX_TRAFFIC_INTR |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_TX_PIC_INTR |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_MC_INTR |
a23fd118e437af0a7877dd313db8fdaa3537c675yl (hldev->config.sched_timer_us != XGE_HAL_SCHED_TIMER_DISABLED ?
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SCHED_INTR : 0);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_intr_mgmt(hldev, val64, 1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "interrupts are enabled");
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_intr_disable - Disable Xframe interrupts.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @op: One of the xge_hal_device_intr_e enumerated values specifying
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the type(s) of interrupts to disable.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Disable Xframe interrupts.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_intr_enable()
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_intr_disable(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_list_t *item;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Disable traffic only interrupts.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Tx traffic interrupts are used only if the TTI feature is
a23fd118e437af0a7877dd313db8fdaa3537c675yl * enabled.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.tti.enabled) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_TX_TRAFFIC_INTR;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RX_TRAFFIC_INTR |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_TX_PIC_INTR |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_MC_INTR |
a23fd118e437af0a7877dd313db8fdaa3537c675yl (hldev->config.sched_timer_us != XGE_HAL_SCHED_TIMER_DISABLED ?
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_SCHED_INTR : 0);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_intr_mgmt(hldev, val64, 0);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl 0xFFFFFFFFFFFFFFFFULL,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->general_int_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* disable all configured PRCs */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_list_for_each(item, &hldev->ring_channels) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_channel_h channel;
a23fd118e437af0a7877dd313db8fdaa3537c675yl channel = xge_container_of(item, xge_hal_channel_t, item);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_ring_prc_disable(channel);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s", "interrupts are disabled");
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_mcast_enable - Enable Xframe multicast addresses.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Enable Xframe multicast addresses.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: XGE_HAL_OK on success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to enable mcast
a23fd118e437af0a7877dd313db8fdaa3537c675yl * feature within the time(timeout).
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_mcast_disable(), xge_hal_status_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_mcast_enable(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev == NULL)
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_INVALID_DEVICE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->mcast_refcnt)
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->mcast_refcnt = 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Enable all Multicast addresses */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_DATA0_MEM_ADDR(0x010203040506ULL),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_data0_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_DATA1_MEM_MASK(0xfeffffffffffULL),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_data1_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RMAC_ADDR_CMD_MEM_WE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET(
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_MAC_MC_ALL_MC_ADDR_OFFSET);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_cmd_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_cmd_mem, 0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* upper layer may require to repeat */
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_mcast_disable - Disable Xframe multicast addresses.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Disable Xframe multicast addresses.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: XGE_HAL_OK - success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to disable mcast
a23fd118e437af0a7877dd313db8fdaa3537c675yl * feature within the time(timeout).
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_mcast_enable(), xge_hal_status_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_mcast_disable(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev == NULL)
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_INVALID_DEVICE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->mcast_refcnt == 0)
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->mcast_refcnt = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Disable all Multicast addresses */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_DATA0_MEM_ADDR(0xffffffffffffULL),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_data0_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_DATA1_MEM_MASK(0),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_data1_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RMAC_ADDR_CMD_MEM_WE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET(
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_MAC_MC_ALL_MC_ADDR_OFFSET);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_cmd_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_cmd_mem, 0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* upper layer may require to repeat */
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_promisc_enable - Enable promiscuous mode.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Enable promiscuous mode of Xframe operation.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_promisc_disable().
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_promisc_enable(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->is_promisc) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Put the NIC into promiscuous mode */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mac_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_MAC_CFG_RMAC_PROM_ENABLE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_CFG_KEY(0x4C0D),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_cfg_key);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u32)(val64 >> 32),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mac_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->is_promisc = 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "mac_cfg 0x%llx: promisc enabled",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_promisc_disable - Disable promiscuous mode.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Disable promiscuous mode of Xframe operation.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_promisc_enable().
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_promisc_disable(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->is_promisc) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Remove the NIC from promiscuous mode */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mac_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~XGE_HAL_MAC_CFG_RMAC_PROM_ENABLE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_CFG_KEY(0x4C0D),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_cfg_key);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u32)(val64 >> 32),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->mac_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->is_promisc = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "mac_cfg 0x%llx: promisc disabled",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_macaddr_get - Get MAC addresses.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @index: MAC address index, in the range from 0 to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_MAX_MAC_ADDRESSES.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @macaddr: MAC address. Returned by HAL.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Retrieve one of the stored MAC addresses by reading non-volatile
a23fd118e437af0a7877dd313db8fdaa3537c675yl * memory on the chip.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Up to %XGE_HAL_MAX_MAC_ADDRESSES addresses is supported.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: XGE_HAL_OK - success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to retrieve the mac
a23fd118e437af0a7877dd313db8fdaa3537c675yl * address within the time(timeout).
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES - Invalid MAC address index.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_macaddr_set(), xge_hal_status_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_macaddr_get(xge_hal_device_t *hldev, int index,
a23fd118e437af0a7877dd313db8fdaa3537c675yl macaddr_t *macaddr)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 =
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev == NULL) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_INVALID_DEVICE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ( index >= XGE_HAL_MAX_MAC_ADDRESSES ) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_HERC_EMULATION
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,0x0000010000000000,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_data0_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,0x0000000000000000,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_data1_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RMAC_ADDR_CMD_MEM_RD |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET((index));
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_cmd_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* poll until done */
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_register_poll(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_cmd_mem, 0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = ( XGE_HAL_RMAC_ADDR_CMD_MEM_RD |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET((index)) );
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_cmd_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev, &bar0->rmac_addr_cmd_mem, 0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* upper layer may require to repeat */
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_data0_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i=0; i < XGE_HAL_ETH_ALEN; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl (*macaddr)[i] = (u8)(val64 >> ((64 - 8) - (i * 8)));
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifdef XGE_HAL_HERC_EMULATION
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i=0; i < XGE_HAL_ETH_ALEN; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl (*macaddr)[i] = (u8)0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl (*macaddr)[1] = (u8)1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_macaddr_set - Set MAC address.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @index: MAC address index, in the range from 0 to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_MAX_MAC_ADDRESSES.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @macaddr: New MAC address to configure.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Configure one of the available MAC address "slots".
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Up to %XGE_HAL_MAX_MAC_ADDRESSES addresses is supported.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: XGE_HAL_OK - success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to set the new mac
a23fd118e437af0a7877dd313db8fdaa3537c675yl * address within the time(timeout).
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES - Invalid MAC address index.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_macaddr_get(), xge_hal_status_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_macaddr_set(xge_hal_device_t *hldev, int index,
a23fd118e437af0a7877dd313db8fdaa3537c675yl macaddr_t macaddr)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 =
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64, temp64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ( index >= XGE_HAL_MAX_MAC_ADDRESSES )
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i=0; i < XGE_HAL_ETH_ALEN; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 |= macaddr[i];
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 <<= 8;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl temp64 >>= 8;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_DATA0_MEM_ADDR(temp64),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_data0_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_DATA1_MEM_MASK(0ULL),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_data1_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = ( XGE_HAL_RMAC_ADDR_CMD_MEM_WE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_OFFSET((index)) );
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rmac_addr_cmd_mem);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev, &bar0->rmac_addr_cmd_mem, 0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* upper layer may require to repeat */
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_macaddr_find - Finds index in the rmac table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @wanted: Wanted MAC address.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_macaddr_set().
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylint
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_macaddr_find(xge_hal_device_t *hldev, macaddr_t wanted)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev == NULL) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_INVALID_DEVICE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i=1; i<XGE_HAL_MAX_MAC_ADDRESSES; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl macaddr_t macaddr;
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_hal_device_macaddr_get(hldev, i, &macaddr);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!xge_os_memcmp(macaddr, wanted, sizeof(macaddr_t))) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return i;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return -1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_mtu_set - Set MTU.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @new_mtu: New MTU size to configure.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Set new MTU value. Example, to use jumbo frames:
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_mtu_set(my_device, my_channel, 9600);
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: XGE_HAL_OK on success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_SWAPPER_CTRL - Failed to configure swapper control
a23fd118e437af0a7877dd313db8fdaa3537c675yl * register.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to initialize TTI/RTI
a23fd118e437af0a7877dd313db8fdaa3537c675yl * schemes.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT - Failed to restore the device to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * a "quiescent" state.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_mtu_set(xge_hal_device_t *hldev, int new_mtu)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * reset needed if 1) new MTU differs, and
a23fd118e437af0a7877dd313db8fdaa3537c675yl * 2a) device was closed or
a23fd118e437af0a7877dd313db8fdaa3537c675yl * 2b) device is being upped for first time.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.mtu != new_mtu) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->reset_needed_after_close ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl !hldev->mtu_first_time_set) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = xge_hal_device_reset(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "%s",
a23fd118e437af0a7877dd313db8fdaa3537c675yl "fatal: can not reset the device");
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* store the new MTU in device, reset will use it */
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.mtu = new_mtu;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "new MTU %d applied",
a23fd118e437af0a7877dd313db8fdaa3537c675yl new_mtu);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->mtu_first_time_set)
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->mtu_first_time_set = 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_initialize - Initialize Xframe device.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @attr: pointer to xge_hal_device_attr_t structure
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @device_config: Configuration to be _applied_ to the device,
a23fd118e437af0a7877dd313db8fdaa3537c675yl * For the Xframe configuration "knobs" please
a23fd118e437af0a7877dd313db8fdaa3537c675yl * refer to xge_hal_device_config_t and Xframe
a23fd118e437af0a7877dd313db8fdaa3537c675yl * User Guide.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Initialize Xframe device. Note that all the arguments of this public API
a23fd118e437af0a7877dd313db8fdaa3537c675yl * are 'IN', including @hldev. Upper-layer driver (ULD) cooperates with
a23fd118e437af0a7877dd313db8fdaa3537c675yl * OS to find new Xframe device, locate its PCI and memory spaces.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * When done, the ULD allocates sizeof(xge_hal_device_t) bytes for HAL
a23fd118e437af0a7877dd313db8fdaa3537c675yl * to enable the latter to perform Xframe hardware initialization.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: XGE_HAL_OK - success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_DRIVER_NOT_INITIALIZED - Driver is not initialized.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_BAD_DEVICE_CONFIG - Device configuration params are not
a23fd118e437af0a7877dd313db8fdaa3537c675yl * valid.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_OUT_OF_MEMORY - Memory allocation failed.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_BAD_SUBSYSTEM_ID - Device subsystem id is invalid.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_INVALID_MAC_ADDRESS - Device mac address in not valid.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to retrieve the mac
a23fd118e437af0a7877dd313db8fdaa3537c675yl * address within the time(timeout) or TTI/RTI initialization failed.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_SWAPPER_CTRL - Failed to configure swapper control.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT -Device is not queiscent.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_terminate(), xge_hal_status_e{}
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_attr_t{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_initialize(xge_hal_device_t *hldev, xge_hal_device_attr_t *attr,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_config_t *device_config)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_channel_t *channel;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 subsys_device;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 subsys_vendor;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int total_dram_size, ring_auto_dram_cfg, left_dram_size;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int total_dram_size_max = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "device 0x%llx is initializing",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)(ulong_t)hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* sanity check */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (g_xge_hal_driver == NULL ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl !g_xge_hal_driver->is_initialized) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_DRIVER_NOT_INITIALIZED;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_memzero(hldev, sizeof(xge_hal_device_t));
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * validate a common part of Xframe-I/II configuration
a23fd118e437af0a7877dd313db8fdaa3537c675yl * (and run check_card() later, once PCI inited - see below)
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_device_config_check_common(device_config);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK)
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* apply config */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_memcpy(&hldev->config, device_config,
a23fd118e437af0a7877dd313db8fdaa3537c675yl sizeof(xge_hal_device_config_t));
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* save original attr */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_memcpy(&hldev->orig_attr, attr,
a23fd118e437af0a7877dd313db8fdaa3537c675yl sizeof(xge_hal_device_attr_t));
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* initialize rxufca_intr_thres */
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->rxufca_intr_thres = hldev->config.rxufca_intr_thres;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0 = attr->regh0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh1 = attr->regh1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh2 = attr->regh2;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->isrbar0 = hldev->bar0 = attr->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->bar1 = attr->bar1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->bar2 = attr->bar2;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->pdev = attr->pdev;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->irqh = attr->irqh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->cfgh = attr->cfgh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->queueh = xge_queue_create(hldev->pdev, hldev->irqh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->config.queue_size_initial,
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->config.queue_size_max,
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_event_queued, hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->queueh == NULL)
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_OUT_OF_MEMORY;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->magic = XGE_HAL_MAGIC;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(hldev->regh0);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(hldev->regh1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(hldev->bar0);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(hldev->bar1);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(hldev->pdev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(hldev->irqh);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(hldev->cfgh);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* initialize some PCI/PCI-X fields of this PCI device. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_pci_init(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * initlialize lists to properly handling a potential
a23fd118e437af0a7877dd313db8fdaa3537c675yl * terminate request
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_list_init(&hldev->free_channels);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_list_init(&hldev->fifo_channels);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_list_init(&hldev->ring_channels);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* fixups for xena */
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.rth_en = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.rth_spdm_en = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.rts_mac_en = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl total_dram_size_max = XGE_HAL_MAX_RING_QUEUE_SIZE_XENA;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_device_config_check_xena(device_config);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_terminate(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_HERC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* fixups for herc */
a23fd118e437af0a7877dd313db8fdaa3537c675yl total_dram_size_max = XGE_HAL_MAX_RING_QUEUE_SIZE_HERC;
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_device_config_check_herc(device_config);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_terminate(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "detected unknown device_id 0x%x", hldev->device_id);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_terminate(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_BAD_DEVICE_ID;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* allocate and initialize FIFO types of channels according to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * configuration */
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i = 0; i < XGE_HAL_MAX_FIFO_NUM; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!device_config->fifo.queue[i].configured)
a23fd118e437af0a7877dd313db8fdaa3537c675yl continue;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl channel = __hal_channel_allocate(hldev, i,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_CHANNEL_TYPE_FIFO);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (channel == NULL) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "fifo: __hal_channel_allocate failed");
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_terminate(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_OUT_OF_MEMORY;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* add new channel to the device */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_list_insert(&channel->item, &hldev->free_channels);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * automatic DRAM adjustment
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl total_dram_size = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl ring_auto_dram_cfg = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!device_config->ring.queue[i].configured)
a23fd118e437af0a7877dd313db8fdaa3537c675yl continue;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (device_config->ring.queue[i].dram_size_mb ==
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEFAULT_USE_HARDCODE) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl ring_auto_dram_cfg++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl continue;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl total_dram_size += device_config->ring.queue[i].dram_size_mb;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl left_dram_size = total_dram_size_max - total_dram_size;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (left_dram_size < 0 ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (ring_auto_dram_cfg && left_dram_size / ring_auto_dram_cfg == 0)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "ring config: exceeded DRAM size %d MB",
a23fd118e437af0a7877dd313db8fdaa3537c675yl total_dram_size_max);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_terminate(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_BADCFG_RING_QUEUE_SIZE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * allocate and initialize RING types of channels according to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * configuration
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!device_config->ring.queue[i].configured)
a23fd118e437af0a7877dd313db8fdaa3537c675yl continue;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (device_config->ring.queue[i].dram_size_mb ==
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEFAULT_USE_HARDCODE) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->config.ring.queue[i].dram_size_mb =
a23fd118e437af0a7877dd313db8fdaa3537c675yl device_config->ring.queue[i].dram_size_mb =
a23fd118e437af0a7877dd313db8fdaa3537c675yl left_dram_size / ring_auto_dram_cfg;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl channel = __hal_channel_allocate(hldev, i,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_CHANNEL_TYPE_RING);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (channel == NULL) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "ring: __hal_channel_allocate failed");
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_terminate(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_OUT_OF_MEMORY;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* add new channel to the device */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_list_insert(&channel->item, &hldev->free_channels);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* get subsystem IDs */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, subsystem_id),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &subsys_device);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, subsystem_vendor_id),
a23fd118e437af0a7877dd313db8fdaa3537c675yl &subsys_vendor);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "subsystem_id %04x:%04x",
a23fd118e437af0a7877dd313db8fdaa3537c675yl subsys_vendor, subsys_device);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* reset device initially */
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) __hal_device_reset(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* set host endian before, to assure proper action */
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_device_set_swapper(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "__hal_device_set_swapper failed");
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_terminate(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) __hal_device_reset(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#ifndef XGE_HAL_HERC_EMULATION
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA)
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_xena_fix_mac(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* MAC address initialization.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * For now only one mac address will be read and used. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = xge_hal_device_macaddr_get(hldev, 0, &hldev->macaddr[0]);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "xge_hal_device_macaddr_get failed");
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_terminate(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->macaddr[0][0] == 0xFF &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->macaddr[0][1] == 0xFF &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->macaddr[0][2] == 0xFF &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->macaddr[0][3] == 0xFF &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->macaddr[0][4] == 0xFF &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->macaddr[0][5] == 0xFF) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "xge_hal_device_macaddr_get returns all FFs");
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_terminate(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_INVALID_MAC_ADDRESS;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "default macaddr: 0x%02x-%02x-%02x-%02x-%02x-%02x",
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->macaddr[0][0], hldev->macaddr[0][1],
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->macaddr[0][2], hldev->macaddr[0][3],
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->macaddr[0][4], hldev->macaddr[0][5]);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_stats_initialize(&hldev->stats, hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "__hal_stats_initialize failed");
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_terminate(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_device_hw_initialize(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (status != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "__hal_device_hw_initialize failed");
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_terminate(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->dump_buf = xge_os_malloc(hldev->pdev, XGE_HAL_DUMP_BUF_SIZE);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->dump_buf == NULL) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "__hal_device_hw_initialize failed");
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_terminate(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_OUT_OF_MEMORY;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Xena-only: need to serialize fifo posts across all device fifos */
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_TX_MULTI_POST)
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_lock_init(&hldev->xena_post_lock, hldev->pdev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#elif defined(XGE_HAL_TX_MULTI_POST_IRQ)
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_lock_init_irq(&hldev->xena_post_lock, hldev->irqh);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->is_initialized = 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_terminating - Mark the device as 'terminating'.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @devh: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Mark the device as 'terminating', going to terminate. Can be used
a23fd118e437af0a7877dd313db8fdaa3537c675yl * to serialize termination with other running processes/contexts.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_terminate().
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_terminating(xge_hal_device_h devh)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->terminating = 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_terminate - Terminate Xframe device.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Terminate HAL device.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_initialize().
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_terminate(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(g_xge_hal_driver != NULL);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(hldev != NULL);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(hldev->magic == XGE_HAL_MAGIC);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_queue_flush(hldev->queueh);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->terminating = 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->is_initialized = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->in_poll = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->magic = XGE_HAL_DEAD;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_TX_MULTI_POST)
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_lock_destroy(&hldev->xena_post_lock, hldev->pdev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#elif defined(XGE_HAL_TX_MULTI_POST_IRQ)
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_lock_destroy_irq(&hldev->xena_post_lock, hldev->pdev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "device %llx is terminating",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)(ulong_t)hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(xge_list_is_empty(&hldev->fifo_channels));
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(xge_list_is_empty(&hldev->ring_channels));
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->stats.is_initialized) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_stats_terminate(&hldev->stats);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* close if open and free all channels */
a23fd118e437af0a7877dd313db8fdaa3537c675yl while (!xge_list_is_empty(&hldev->free_channels)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_channel_t *channel = (xge_hal_channel_t*)
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->free_channels.next;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(!channel->is_open);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_list_remove(&channel->item);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_channel_free(channel);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->queueh) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_queue_destroy(hldev->queueh);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->spdm_table) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_free(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_table[0],
a23fd118e437af0a7877dd313db8fdaa3537c675yl (sizeof(xge_hal_spdm_entry_t) *
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_max_entries));
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_free(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_table,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (sizeof(xge_hal_spdm_entry_t *) *
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_max_entries));
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_lock_destroy(&hldev->spdm_lock, hldev->pdev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_table = NULL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->dump_buf) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_free(hldev->pdev, hldev->dump_buf,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DUMP_BUF_SIZE);
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->dump_buf = NULL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_handle_tcode - Handle transfer code.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @channelh: Channel handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @dtrh: Descriptor handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @t_code: One of the enumerated (and documented in the Xframe user guide)
a23fd118e437af0a7877dd313db8fdaa3537c675yl * "transfer codes".
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Handle descriptor's transfer code. The latter comes with each completed
a23fd118e437af0a7877dd313db8fdaa3537c675yl * descriptor, see xge_hal_fifo_dtr_next_completed() and
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_ring_dtr_next_completed().
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Transfer codes are enumerated in xgehal-fifo.h and xgehal-ring.h.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: one of the xge_hal_status_e{} enumerated types.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_OK - for success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_CRITICAL - when encounters critical error.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_handle_tcode (xge_hal_channel_h channelh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_dtr_h dtrh, u8 t_code)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)channel->devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (t_code > 15) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_printf("invalid t_code %d", t_code);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_err_stats.txd_t_code_err_cnt[t_code]++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_DEBUG_BAD_TCODE)
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_fifo_txd_t *txdp = (xge_hal_fifo_txd_t *)dtrh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_printf("%llx:%llx:%llx:%llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl txdp->control_1, txdp->control_2, txdp->buffer_pointer,
a23fd118e437af0a7877dd313db8fdaa3537c675yl txdp->host_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* handle link "down" immediately without going through
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_poll() routine. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (t_code == XGE_HAL_TXD_T_CODE_LOSS_OF_LINK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* link is down */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->link_state != XGE_HAL_LINK_DOWN) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 =
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->link_state = XGE_HAL_LINK_DOWN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* turn off LED */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = val64 & (~XGE_HAL_ADAPTER_LED_ON);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->adapter_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->uld_callbacks.link_down(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->upper_layer_info);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else if (t_code == XGE_HAL_TXD_T_CODE_ABORT_BUFFER ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl t_code == XGE_HAL_TXD_T_CODE_ABORT_DTOR) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_handle_targetabort(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_CRITICAL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_err_stats.rxd_t_code_err_cnt[t_code]++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_DEBUG_BAD_TCODE)
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_ring_rxd_1_t *rxdp = (xge_hal_ring_rxd_1_t *)dtrh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_printf("%llx:%llx:%llx:%llx", rxdp->control_1,
a23fd118e437af0a7877dd313db8fdaa3537c675yl rxdp->control_2, rxdp->buffer0_ptr,
a23fd118e437af0a7877dd313db8fdaa3537c675yl rxdp->host_control);
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (t_code == XGE_HAL_RXD_T_CODE_BAD_ECC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_err_stats.ecc_err_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_handle_eccerr(hldev, "rxd_t_code",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u64)t_code);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_CRITICAL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else if (t_code == XGE_HAL_RXD_T_CODE_PARITY ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl t_code == XGE_HAL_RXD_T_CODE_PARITY_ABORT) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->stats.sw_dev_err_stats.parity_err_cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_handle_parityerr(hldev, "rxd_t_code",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u64)t_code);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_CRITICAL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_link_state - Get link state.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @devh: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @ls: Link state, see xge_hal_device_link_state_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Get link state.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: XGE_HAL_OK.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_link_state_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e xge_hal_device_link_state(xge_hal_device_h devh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_link_state_e *ls)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_assert(ls != NULL);
a23fd118e437af0a7877dd313db8fdaa3537c675yl *ls = hldev->link_state;
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_sched_timer - Configure scheduled device interrupt.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @devh: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @interval_us: Time interval, in miscoseconds.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Unlike transmit and receive interrupts,
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the scheduled interrupt is generated independently of
a23fd118e437af0a7877dd313db8fdaa3537c675yl * traffic, but purely based on time.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @one_shot: 1 - generate scheduled interrupt only once.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * 0 - generate scheduled interrupt periodically at the specified
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @interval_us interval.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * (Re-)configure scheduled interrupt. Can be called at runtime to change
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the setting, generate one-shot interrupts based on the resource and/or
a23fd118e437af0a7877dd313db8fdaa3537c675yl * traffic conditions, other purposes.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_device_config_t{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid xge_hal_device_sched_timer(xge_hal_device_h devh, int interval_us,
a23fd118e437af0a7877dd313db8fdaa3537c675yl int one_shot)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 =
a23fd118e437af0a7877dd313db8fdaa3537c675yl (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl unsigned int interval = hldev->config.pci_freq_mherz * interval_us;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl interval = __hal_fix_time_ival_herc(hldev, interval);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->scheduled_int_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (interval) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= XGE_HAL_SCHED_INT_PERIOD_MASK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_SCHED_INT_PERIOD(interval);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (one_shot) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_SCHED_INT_CTRL_ONE_SHOT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_SCHED_INT_CTRL_TIMER_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~XGE_HAL_SCHED_INT_CTRL_TIMER_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->scheduled_int_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_TRACE, "sched_timer 0x%llx: %s",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (unsigned long long)val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl interval ? "enabled" : "disabled");
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_check_id - Verify device ID.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @devh: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Verify device ID.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: one of the xge_hal_card_e{} enumerated types.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_card_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_card_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_check_id(xge_hal_device_h devh)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl switch (hldev->device_id) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_PCI_DEVICE_ID_XENA_1:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_PCI_DEVICE_ID_XENA_2:
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_CARD_XENA;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_PCI_DEVICE_ID_HERC_1:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_PCI_DEVICE_ID_HERC_2:
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_CARD_HERC;
a23fd118e437af0a7877dd313db8fdaa3537c675yl default:
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_CARD_UNKNOWN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_pci_info_get - Get PCI bus informations such as width,
a23fd118e437af0a7877dd313db8fdaa3537c675yl * frequency, and mode from previously stored values.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @devh: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @pci_mode: pointer to a variable of enumerated type
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_pci_mode_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @bus_frequency: pointer to a variable of enumerated type
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_pci_bus_frequency_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @bus_width: pointer to a variable of enumerated type
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_pci_bus_width_e{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Get pci mode, frequency, and PCI bus width.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: one of the xge_hal_status_e{} enumerated types.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_OK - for success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_INVALID_DEVICE - for invalid device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See Also: xge_hal_pci_mode_e, xge_hal_pci_mode_e, xge_hal_pci_width_e.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_pci_info_get(xge_hal_device_h devh, xge_hal_pci_mode_e *pci_mode,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bus_frequency_e *bus_frequency,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bus_width_e *bus_width)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e rc_status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev || !hldev->is_initialized || hldev->magic != XGE_HAL_MAGIC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl rc_status = XGE_HAL_ERR_INVALID_DEVICE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "xge_hal_device_pci_info_get error, rc %d for device %p",
a23fd118e437af0a7877dd313db8fdaa3537c675yl rc_status, hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return rc_status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl *pci_mode = hldev->pci_mode;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_frequency = hldev->bus_frequency;
a23fd118e437af0a7877dd313db8fdaa3537c675yl *bus_width = hldev->bus_width;
a23fd118e437af0a7877dd313db8fdaa3537c675yl rc_status = XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl return rc_status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_reinitialize_hw
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: private member of the device structure.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function will soft reset the NIC and re-initalize all the
a23fd118e437af0a7877dd313db8fdaa3537c675yl * I/O registers to the values they had after it's inital initialization
a23fd118e437af0a7877dd313db8fdaa3537c675yl * through the probe function.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylint xge_hal_reinitialize_hw(xge_hal_device_t * hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) xge_hal_device_reset(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_hw_initialize(hldev) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_terminate(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void) __hal_device_reset(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl return 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_read_spdm_entry_line
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: pointer to xge_hal_device_t structure
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @spdm_line: spdm line in the spdm entry to be read.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @spdm_entry: spdm entry of the spdm_line in the SPDM table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @spdm_line_val: Contains the value stored in the spdm line.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * SPDM table contains upto a maximum of 256 spdm entries.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Each spdm entry contains 8 lines and each line stores 8 bytes.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function reads the spdm line(addressed by @spdm_line)
a23fd118e437af0a7877dd313db8fdaa3537c675yl * of the spdm entry(addressed by @spdm_entry) in
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the SPDM table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_read_spdm_entry_line(xge_hal_device_t *hldev, u8 spdm_line,
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 spdm_entry, u64 *spdm_line_val)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RTS_RTH_SPDM_MEM_CTRL_STROBE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTS_RTH_SPDM_MEM_CTRL_LINE_SEL(spdm_line) |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTS_RTH_SPDM_MEM_CTRL_OFFSET(spdm_entry);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_spdm_mem_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* poll until done */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_spdm_mem_ctrl, 0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTS_RTH_SPDM_MEM_CTRL_STROBE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl *spdm_line_val = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, &bar0->rts_rth_spdm_mem_data);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_get_free_spdm_entry
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: pointer to xge_hal_device_t structure
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @spdm_entry: Contains an index to the unused spdm entry in the SPDM table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function returns an index of unused spdm entry in the SPDM
a23fd118e437af0a7877dd313db8fdaa3537c675yl * table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic xge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675yl__hal_get_free_spdm_entry(xge_hal_device_t *hldev, u16 *spdm_entry)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 spdm_line_val=0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Search in the local SPDM table for a free slot.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl *spdm_entry = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl for(; *spdm_entry < hldev->spdm_max_entries; (*spdm_entry)++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->spdm_table[*spdm_entry]->in_use) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (*spdm_entry >= hldev->spdm_max_entries) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_SPDM_TABLE_FULL;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Make sure that the corresponding spdm entry in the SPDM
a23fd118e437af0a7877dd313db8fdaa3537c675yl * table is free.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Seventh line of the spdm entry contains information about
a23fd118e437af0a7877dd313db8fdaa3537c675yl * whether the entry is free or not.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((status = __hal_read_spdm_entry_line(hldev, 7, *spdm_entry,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &spdm_line_val)) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* BIT(63) in spdm_line 7 corresponds to entry_enable bit */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((spdm_line_val & BIT(63))) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Log a warning
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "Local SPDM table is not "
a23fd118e437af0a7877dd313db8fdaa3537c675yl "consistent with the actual one for the spdm "
a23fd118e437af0a7877dd313db8fdaa3537c675yl "entry %d\n", *spdm_entry);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_SPDM_TABLE_DATA_INCONSISTENT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_spdm_entry_add - Add a new entry to the SPDM table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @devh: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @src_ip: Source ip address(IPv4/IPv6).
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @dst_ip: Destination ip address(IPv4/IPv6).
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @l4_sp: L4 source port.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @l4_dp: L4 destination port.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @is_tcp: Set to 1, if the protocol is TCP.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * 0, if the protocol is UDP.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @is_ipv4: Set to 1, if the protocol is IPv4.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * 0, if the protocol is IPv6.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @tgt_queue: Target queue to route the receive packet.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function add a new entry to the SPDM table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: XGE_HAL_OK - success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_SPDM_NOT_ENABLED - SPDM support is not enabled.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to add a new entry with in
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the time(timeout).
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_SPDM_TABLE_FULL - SPDM table is full.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_SPDM_INVALID_ENTRY - Invalid SPDM entry.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_spdm_entry_remove{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_spdm_entry_add(xge_hal_device_h devh, xge_hal_ipaddr_t *src_ip,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_ipaddr_t *dst_ip, u16 l4_sp, u16 l4_dp,
a23fd118e437af0a7877dd313db8fdaa3537c675yl u8 is_tcp, u8 is_ipv4, u8 tgt_queue)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u32 jhash_value;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u32 jhash_init_val;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u32 jhash_golden_ratio;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int off;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 spdm_entry;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u8 msg[XGE_HAL_JHASH_MSG_LEN];
a23fd118e437af0a7877dd313db8fdaa3537c675yl int ipaddr_len;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->config.rth_spdm_en) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_SPDM_NOT_ENABLED;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((tgt_queue < XGE_HAL_MIN_RING_NUM) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (tgt_queue > XGE_HAL_MAX_RING_NUM)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_SPDM_INVALID_ENTRY;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Calculate the jenkins hash.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Create the Jenkins hash algorithm key.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * key = {L3SA, L3DA, L4SP, L4DP}, if SPDM is configured to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * use L4 information. Otherwize key = {L3SA, L3DA}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (is_ipv4) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl ipaddr_len = 4; // In bytes
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl ipaddr_len = 16;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Jenkins hash algorithm expects the key in the big endian
a23fd118e437af0a7877dd313db8fdaa3537c675yl * format. Since key is the byte array, memcpy won't work in the
a23fd118e437af0a7877dd313db8fdaa3537c675yl * case of little endian. So, the current code extracts each
a23fd118e437af0a7877dd313db8fdaa3537c675yl * byte starting from MSB and store it in the key.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (is_ipv4) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (off = 0; off < ipaddr_len; off++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl u32 mask = vBIT32(0xff,(off*8),8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl int shift = 32-(off+1)*8;
a23fd118e437af0a7877dd313db8fdaa3537c675yl msg[off] = (u8)((src_ip->ipv4.addr & mask) >> shift);
a23fd118e437af0a7877dd313db8fdaa3537c675yl msg[off+ipaddr_len] =
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u8)((dst_ip->ipv4.addr & mask) >> shift);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (off = 0; off < ipaddr_len; off++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl int loc = off % 8;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 mask = vBIT(0xff,(loc*8),8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl int shift = 64-(loc+1)*8;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl msg[off] = (u8)((src_ip->ipv6.addr[off/8] & mask)
a23fd118e437af0a7877dd313db8fdaa3537c675yl >> shift);
a23fd118e437af0a7877dd313db8fdaa3537c675yl msg[off+ipaddr_len] = (u8)((dst_ip->ipv6.addr[off/8]
a23fd118e437af0a7877dd313db8fdaa3537c675yl & mask) >> shift);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl off = (2*ipaddr_len);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hldev->config.rth_spdm_use_l4) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl msg[off] = (u8)((l4_sp & 0xff00) >> 8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl msg[off + 1] = (u8)(l4_sp & 0xff);
a23fd118e437af0a7877dd313db8fdaa3537c675yl msg[off + 2] = (u8)((l4_dp & 0xff00) >> 8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl msg[off + 3] = (u8)(l4_dp & 0xff);
a23fd118e437af0a7877dd313db8fdaa3537c675yl off += 4;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Calculate jenkins hash for this configuration
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_jhash_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl jhash_golden_ratio = (u32)(val64 >> 32);
a23fd118e437af0a7877dd313db8fdaa3537c675yl jhash_init_val = (u32)(val64 & 0xffffffff);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl jhash_value = __hal_calc_jhash(msg, off,
a23fd118e437af0a7877dd313db8fdaa3537c675yl jhash_golden_ratio,
a23fd118e437af0a7877dd313db8fdaa3537c675yl jhash_init_val);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_lock(&hldev->spdm_lock);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Locate a free slot in the SPDM table. To avoid a seach in the
a23fd118e437af0a7877dd313db8fdaa3537c675yl * actual SPDM table, which is very expensive in terms of time,
a23fd118e437af0a7877dd313db8fdaa3537c675yl * we are maintaining a local copy of the table and the search for
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the free entry is performed in the local table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((status = __hal_get_free_spdm_entry(hldev,&spdm_entry))
a23fd118e437af0a7877dd313db8fdaa3537c675yl != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_unlock(&hldev->spdm_lock);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Add this entry to the SPDM table
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl status = __hal_spdm_entry_add(hldev, src_ip, dst_ip, l4_sp, l4_dp,
a23fd118e437af0a7877dd313db8fdaa3537c675yl is_tcp, is_ipv4, tgt_queue,
a23fd118e437af0a7877dd313db8fdaa3537c675yl jhash_value, /* calculated jhash */
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_entry);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_unlock(&hldev->spdm_lock);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_spdm_entry_remove - Remove an entry from the SPDM table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @devh: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @src_ip: Source ip address(IPv4/IPv6).
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @dst_ip: Destination ip address(IPv4/IPv6).
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @l4_sp: L4 source port.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @l4_dp: L4 destination port.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @is_tcp: Set to 1, if the protocol is TCP.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * 0, if the protocol os UDP.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @is_ipv4: Set to 1, if the protocol is IPv4.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * 0, if the protocol is IPv6.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function remove an entry from the SPDM table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: XGE_HAL_OK - success.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_SPDM_NOT_ENABLED - SPDM support is not enabled.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to remove an entry with in
a23fd118e437af0a7877dd313db8fdaa3537c675yl * the time(timeout).
a23fd118e437af0a7877dd313db8fdaa3537c675yl * XGE_HAL_ERR_SPDM_ENTRY_NOT_FOUND - Unable to locate the entry in the SPDM
a23fd118e437af0a7877dd313db8fdaa3537c675yl * table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_spdm_entry_add{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_spdm_entry_remove(xge_hal_device_h devh, xge_hal_ipaddr_t *src_ip,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_ipaddr_t *dst_ip, u16 l4_sp, u16 l4_dp,
a23fd118e437af0a7877dd313db8fdaa3537c675yl u8 is_tcp, u8 is_ipv4)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 spdm_entry;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 spdm_line_arr[8];
a23fd118e437af0a7877dd313db8fdaa3537c675yl u8 line_no;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u8 spdm_is_tcp;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u8 spdm_is_ipv4;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 spdm_l4_sp;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 spdm_l4_dp;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->config.rth_spdm_en) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_SPDM_NOT_ENABLED;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_lock(&hldev->spdm_lock);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Poll the rxpic_int_reg register until spdm ready bit is set or
a23fd118e437af0a7877dd313db8fdaa3537c675yl * timeout happens.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev, &bar0->rxpic_int_reg, 1,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RX_PIC_INT_REG_SPDM_READY,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* upper layer may require to repeat */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_unlock(&hldev->spdm_lock);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Clear the SPDM READY bit.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rxpic_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~XGE_HAL_RX_PIC_INT_REG_SPDM_READY;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rxpic_int_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Search in the local SPDM table to get the index of the
a23fd118e437af0a7877dd313db8fdaa3537c675yl * corresponding entry in the SPDM table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_entry = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (;spdm_entry < hldev->spdm_max_entries; spdm_entry++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((!hldev->spdm_table[spdm_entry]->in_use) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (hldev->spdm_table[spdm_entry]->is_tcp != is_tcp) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (hldev->spdm_table[spdm_entry]->l4_sp != l4_sp) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (hldev->spdm_table[spdm_entry]->l4_dp != l4_dp) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (hldev->spdm_table[spdm_entry]->is_ipv4 != is_ipv4)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl continue;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Compare the src/dst IP addresses of source and target
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (is_ipv4) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((hldev->spdm_table[spdm_entry]->src_ip.ipv4.addr
a23fd118e437af0a7877dd313db8fdaa3537c675yl != src_ip->ipv4.addr) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (hldev->spdm_table[spdm_entry]->dst_ip.ipv4.addr
a23fd118e437af0a7877dd313db8fdaa3537c675yl != dst_ip->ipv4.addr)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl continue;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((hldev->spdm_table[spdm_entry]->src_ip.ipv6.addr[0]
a23fd118e437af0a7877dd313db8fdaa3537c675yl != src_ip->ipv6.addr[0]) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (hldev->spdm_table[spdm_entry]->src_ip.ipv6.addr[1]
a23fd118e437af0a7877dd313db8fdaa3537c675yl != src_ip->ipv6.addr[1]) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (hldev->spdm_table[spdm_entry]->dst_ip.ipv6.addr[0]
a23fd118e437af0a7877dd313db8fdaa3537c675yl != dst_ip->ipv6.addr[0]) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (hldev->spdm_table[spdm_entry]->dst_ip.ipv6.addr[1]
a23fd118e437af0a7877dd313db8fdaa3537c675yl != dst_ip->ipv6.addr[1])) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl continue;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (spdm_entry >= hldev->spdm_max_entries) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_unlock(&hldev->spdm_lock);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_SPDM_ENTRY_NOT_FOUND;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Retrieve the corresponding entry from the SPDM table and
a23fd118e437af0a7877dd313db8fdaa3537c675yl * make sure that the data is consistent.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl for(line_no = 0; line_no < 8; line_no++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * SPDM line 2,3,4 are valid only for IPv6 entry.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * SPDM line 5 & 6 are reserved. We don't have to
a23fd118e437af0a7877dd313db8fdaa3537c675yl * read these entries in the above cases.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (((is_ipv4) &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl ((line_no == 2)||(line_no == 3)||(line_no == 4))) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (line_no == 5) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (line_no == 6)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl continue;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((status = __hal_read_spdm_entry_line(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl line_no,
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_entry,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &spdm_line_arr[line_no]))
a23fd118e437af0a7877dd313db8fdaa3537c675yl != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_unlock(&hldev->spdm_lock);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return status;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Seventh line of the spdm entry contains the entry_enable
a23fd118e437af0a7877dd313db8fdaa3537c675yl * bit. Make sure that the entry_enable bit of this spdm entry
a23fd118e437af0a7877dd313db8fdaa3537c675yl * is set.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * To remove an entry from the SPDM table, reset this
a23fd118e437af0a7877dd313db8fdaa3537c675yl * bit.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!(spdm_line_arr[7] & BIT(63))) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Log a warning
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "Local SPDM table is not "
a23fd118e437af0a7877dd313db8fdaa3537c675yl "consistent with the actual one for the spdm "
a23fd118e437af0a7877dd313db8fdaa3537c675yl "entry %d \n", spdm_entry);
a23fd118e437af0a7877dd313db8fdaa3537c675yl goto err_exit;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Retreive the L4 SP/DP, src/dst ip addresses from the SPDM
a23fd118e437af0a7877dd313db8fdaa3537c675yl * table and do a comparision.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_is_tcp = (u8)((spdm_line_arr[0] & BIT(59)) >> 4);
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_is_ipv4 = (u8)(spdm_line_arr[0] & BIT(63));
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_l4_sp = (u16)(spdm_line_arr[0] >> 48);
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_l4_dp = (u16)((spdm_line_arr[0] >> 32) & 0xffff);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((spdm_is_tcp != is_tcp) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (spdm_is_ipv4 != is_ipv4) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (spdm_l4_sp != l4_sp) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (spdm_l4_dp != l4_dp)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Log a warning
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "Local SPDM table is not "
a23fd118e437af0a7877dd313db8fdaa3537c675yl "consistent with the actual one for the spdm "
a23fd118e437af0a7877dd313db8fdaa3537c675yl "entry %d \n", spdm_entry);
a23fd118e437af0a7877dd313db8fdaa3537c675yl goto err_exit;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (is_ipv4) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Upper 32 bits of spdm_line(64 bit) contains the
a23fd118e437af0a7877dd313db8fdaa3537c675yl * src IPv4 address. Lower 32 bits of spdm_line
a23fd118e437af0a7877dd313db8fdaa3537c675yl * contains the destination IPv4 address.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl u32 temp_src_ip = (u32)(spdm_line_arr[1] >> 32);
a23fd118e437af0a7877dd313db8fdaa3537c675yl u32 temp_dst_ip = (u32)(spdm_line_arr[1] & 0xffffffff);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((temp_src_ip != src_ip->ipv4.addr) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (temp_dst_ip != dst_ip->ipv4.addr)) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "Local SPDM table is not "
a23fd118e437af0a7877dd313db8fdaa3537c675yl "consistent with the actual one for the spdm "
a23fd118e437af0a7877dd313db8fdaa3537c675yl "entry %d \n", spdm_entry);
a23fd118e437af0a7877dd313db8fdaa3537c675yl goto err_exit;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * SPDM line 1 & 2 contains the src IPv6 address.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * SPDM line 3 & 4 contains the dst IPv6 address.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if ((spdm_line_arr[1] != src_ip->ipv6.addr[0]) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (spdm_line_arr[2] != src_ip->ipv6.addr[1]) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (spdm_line_arr[3] != dst_ip->ipv6.addr[0]) ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl (spdm_line_arr[4] != dst_ip->ipv6.addr[1])) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Log a warning
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_device(XGE_ERR, "Local SPDM table is not "
a23fd118e437af0a7877dd313db8fdaa3537c675yl "consistent with the actual one for the spdm "
a23fd118e437af0a7877dd313db8fdaa3537c675yl "entry %d \n", spdm_entry);
a23fd118e437af0a7877dd313db8fdaa3537c675yl goto err_exit;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Reset the entry_enable bit to zero
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_line_arr[7] &= ~BIT(63);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl spdm_line_arr[7],
a23fd118e437af0a7877dd313db8fdaa3537c675yl (void *)((char *)hldev->spdm_mem_base +
a23fd118e437af0a7877dd313db8fdaa3537c675yl (spdm_entry * 64) + (7 * 8)));
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Wait for the operation to be completed.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rxpic_int_reg, 1,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RX_PIC_INT_REG_SPDM_READY,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_unlock(&hldev->spdm_lock);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Make the corresponding spdm entry in the local SPDM table
a23fd118e437af0a7877dd313db8fdaa3537c675yl * available for future use.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->spdm_table[spdm_entry]->in_use = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_unlock(&hldev->spdm_lock);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675ylerr_exit:
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_spin_unlock(&hldev->spdm_lock);
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_ERR_SPDM_TABLE_DATA_INCONSISTENT;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_calc_jhash - Calculate Jenkins hash.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @msg: Jenkins hash algorithm key.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @length: Length of the key.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @golden_ratio: Jenkins hash golden ratio.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @init_value: Jenkins hash initial value.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function implements the Jenkins based algorithm used for the
a23fd118e437af0a7877dd313db8fdaa3537c675yl * calculation of the RTH hash.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Returns: Jenkins hash value.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylu32 __hal_calc_jhash(u8 *msg, u32 length, u32 golden_ratio, u32 init_value)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl register u32 a,b,c,len;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Set up the internal state
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl len = length;
a23fd118e437af0a7877dd313db8fdaa3537c675yl a = b = golden_ratio; /* the golden ratio; an arbitrary value */
a23fd118e437af0a7877dd313db8fdaa3537c675yl c = init_value; /* the previous hash value */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* handle most of the key */
a23fd118e437af0a7877dd313db8fdaa3537c675yl while (len >= 12)
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl a += (msg[0] + ((u32)msg[1]<<8) + ((u32)msg[2]<<16)
a23fd118e437af0a7877dd313db8fdaa3537c675yl + ((u32)msg[3]<<24));
a23fd118e437af0a7877dd313db8fdaa3537c675yl b += (msg[4] + ((u32)msg[5]<<8) + ((u32)msg[6]<<16)
a23fd118e437af0a7877dd313db8fdaa3537c675yl + ((u32)msg[7]<<24));
a23fd118e437af0a7877dd313db8fdaa3537c675yl c += (msg[8] + ((u32)msg[9]<<8) + ((u32)msg[10]<<16)
a23fd118e437af0a7877dd313db8fdaa3537c675yl + ((u32)msg[11]<<24));
a23fd118e437af0a7877dd313db8fdaa3537c675yl mix(a,b,c);
a23fd118e437af0a7877dd313db8fdaa3537c675yl msg += 12; len -= 12;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* handle the last 11 bytes */
a23fd118e437af0a7877dd313db8fdaa3537c675yl c += length;
a23fd118e437af0a7877dd313db8fdaa3537c675yl switch(len) /* all the case statements fall through */
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 11: c+= ((u32)msg[10]<<24);
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 10: c+= ((u32)msg[9]<<16);
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 9 : c+= ((u32)msg[8]<<8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* the first byte of c is reserved for the length */
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 8 : b+= ((u32)msg[7]<<24);
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 7 : b+= ((u32)msg[6]<<16);
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 6 : b+= ((u32)msg[5]<<8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 5 : b+= msg[4];
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 4 : a+= ((u32)msg[3]<<24);
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 3 : a+= ((u32)msg[2]<<16);
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 2 : a+= ((u32)msg[1]<<8);
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case 1 : a+= msg[0];
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* case 0: nothing left to add */
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl mix(a,b,c);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* report the result */
a23fd118e437af0a7877dd313db8fdaa3537c675yl return c;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_MSI) | defined(XGE_HAL_MSI_X)
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_rti_set
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @ring: The post_qid of the ring.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @channel: HAL channel of the ring.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function stores the RTI value associated for the MSI and
a23fd118e437af0a7877dd313db8fdaa3537c675yl * also unmasks this particular RTI in the rti_mask register.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void __hal_device_rti_set(int ring_qid, xge_hal_channel_t *channel)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t*)channel->devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_MSI)
a23fd118e437af0a7877dd313db8fdaa3537c675yl channel->rti = (u8)ring_qid;
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rx_traffic_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~BIT(ring_qid);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rx_traffic_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_device_tti_set
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @ring: The post_qid of the FIFO.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @channel: HAL channel the FIFO.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function stores the TTI value associated for the MSI and
a23fd118e437af0a7877dd313db8fdaa3537c675yl * also unmasks this particular TTI in the tti_mask register.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void __hal_device_tti_set(int fifo_qid, xge_hal_channel_t *channel)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t*)channel->devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_MSI)
a23fd118e437af0a7877dd313db8fdaa3537c675yl channel->tti = (u8)fifo_qid;
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->tx_traffic_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~BIT(fifo_qid);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->tx_traffic_mask);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_MSI)
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_channel_msi_set - Associate a RTI with a ring or TTI with a
a23fd118e437af0a7877dd313db8fdaa3537c675yl * FIFO for a given MSI.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @channelh: HAL channel handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @msi: MSI Number associated with the channel.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @msi_msg: The MSI message associated with the MSI number above.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This API will associate a given channel (either Ring or FIFO) with the
a23fd118e437af0a7877dd313db8fdaa3537c675yl * given MSI number. It will alo program the Tx_Mat/Rx_Mat tables in the
a23fd118e437af0a7877dd313db8fdaa3537c675yl * hardware to indicate this association to the hardware.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_channel_msi_set(xge_hal_channel_h channelh, int msi, u32 msi_msg)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t*)channel->devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl channel->msi_msg = msi_msg;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl int ring = channel->post_qid;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_osdep(XGE_TRACE, "MSI Data: 0x%4x, Ring: %d,"
a23fd118e437af0a7877dd313db8fdaa3537c675yl " MSI: %d\n", channel->msi_msg, ring, msi);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rx_mat);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_SET_RX_MAT(ring, msi);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rx_mat);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_rti_set(ring, channel);
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else {
a23fd118e437af0a7877dd313db8fdaa3537c675yl int fifo = channel->post_qid;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_osdep(XGE_TRACE, "MSI Data: 0x%4x, Fifo: %d,"
a23fd118e437af0a7877dd313db8fdaa3537c675yl " MSI: %d\n", channel->msi_msg, fifo, msi);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->tx_mat[0]);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_SET_TX_MAT(fifo, msi);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->tx_mat[0]);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_tti_set(fifo, channel);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_MSI_X)
a23fd118e437af0a7877dd313db8fdaa3537c675yl/*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * __hal_set_xmsi_vals
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @devh: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @msix_value: 32bit MSI-X value transferred across PCI to @msix_address.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Filled in by this function.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @msix_address: 32bit MSI-X DMA address.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Filled in by this function.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @msix_idx: index that corresponds to the (@msix_value, @msix_address)
a23fd118e437af0a7877dd313db8fdaa3537c675yl * entry in the table of MSI-X (value, address) pairs.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function will program the hardware associating the given
a23fd118e437af0a7877dd313db8fdaa3537c675yl * address/value cobination to the specified msi number.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylstatic void __hal_set_xmsi_vals (xge_hal_device_h devh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl u32 *msix_value,
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 *msix_addr,
a23fd118e437af0a7877dd313db8fdaa3537c675yl int msix_idx)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl int cnt = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_XMSI_NO(msix_idx) | XGE_HAL_XMSI_STROBE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u32)(val64 >> 32), &bar0->xmsi_access);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u32)(val64), &bar0->xmsi_access);
a23fd118e437af0a7877dd313db8fdaa3537c675yl do {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->xmsi_access);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (val64 & XGE_HAL_XMSI_STROBE)
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl cnt++;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_mdelay(20);
a23fd118e437af0a7877dd313db8fdaa3537c675yl } while(cnt < 5);
a23fd118e437af0a7877dd313db8fdaa3537c675yl *msix_value = (u32)(xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->xmsi_data));
a23fd118e437af0a7877dd313db8fdaa3537c675yl *msix_addr = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->xmsi_address);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_channel_msix_set - Associate MSI-X with a channel.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @channelh: HAL channel handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @msix_idx: index that corresponds to a particular (@msix_value,
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @msix_address) entry in the MSI-X table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This API associates a given channel (either Ring or FIFO) with the
a23fd118e437af0a7877dd313db8fdaa3537c675yl * given MSI-X number. It programs the Xframe's Tx_Mat/Rx_Mat tables
a23fd118e437af0a7877dd313db8fdaa3537c675yl * to indicate this association.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_channel_msix_set(xge_hal_channel_h channelh, int msix_idx)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t*)channel->devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 msi_control_reg;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Currently Ring and RTI is one on one. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl int ring = channel->post_qid;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rx_mat);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_SET_RX_MAT(ring, msix_idx);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rx_mat);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_rti_set(ring, channel);
a23fd118e437af0a7877dd313db8fdaa3537c675yl } else if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl int fifo = channel->post_qid;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->tx_mat[0]);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_SET_TX_MAT(fifo, msix_idx);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->tx_mat[0]);
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_device_tti_set(fifo, channel);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl channel->msix_idx = msix_idx;
a23fd118e437af0a7877dd313db8fdaa3537c675yl __hal_set_xmsi_vals(hldev, &channel->msix_data,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &channel->msix_address,
a23fd118e437af0a7877dd313db8fdaa3537c675yl channel->msix_idx);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * To enable MSI-X, MSI also needs to be enabled, due to a bug
a23fd118e437af0a7877dd313db8fdaa3537c675yl * in the herc NIC. (Temp change, needs to be removed later)
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_read16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, msi_control), &msi_control_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl msi_control_reg |= 0x1; /* Enable MSI */
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pci_write16(hldev->pdev, hldev->cfgh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_offsetof(xge_hal_pci_config_le_t, msi_control), msi_control_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Enable the MSI-X interrupt */
a23fd118e437af0a7877dd313db8fdaa3537c675yl {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->xmsi_mask_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~(1LL << ( 63 - msix_idx ));
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->xmsi_mask_reg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl#if defined(XGE_HAL_CONFIG_LRO)
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_lro_terminate - Terminate lro resources.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @lro_scale: Amount of lro memory.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: Hal device structure.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_lro_terminate(u32 lro_scale,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_lro_init - Initiate lro resources.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @lro_scale: Amount of lro memory.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: Hal device structure.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Note: For time being I am using only one LRO per device. Later on size
a23fd118e437af0a7877dd313db8fdaa3537c675yl * will be increased.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_lro_init(u32 lro_scale,
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i;
a23fd118e437af0a7877dd313db8fdaa3537c675yl for(i = 0; i < XGE_HAL_MAX_LRO_SESSIONS; i++)
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->g_lro_pool[i].in_use = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl#endif
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_poll - HAL device "polling" entry point.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * HAL "polling" entry point. Note that this is part of HAL public API.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Upper-Layer driver _must_ periodically poll HAL via
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_poll().
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * HAL uses caller's execution context to serially process accumulated
a23fd118e437af0a7877dd313db8fdaa3537c675yl * slow-path events, such as link state changes and hardware error
a23fd118e437af0a7877dd313db8fdaa3537c675yl * indications.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * The rate of polling could be somewhere between 500us to 10ms,
a23fd118e437af0a7877dd313db8fdaa3537c675yl * depending on requirements (e.g., the requirement to support fail-over
a23fd118e437af0a7877dd313db8fdaa3537c675yl * could mean that 500us or even 100us polling interval need to be used).
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * The need and motivation for external polling includes
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - remove the error-checking "burden" from the HAL interrupt handler
a23fd118e437af0a7877dd313db8fdaa3537c675yl * (see xge_hal_device_handle_irq());
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - remove the potential source of portability issues by _not_
a23fd118e437af0a7877dd313db8fdaa3537c675yl * implementing separate polling thread within HAL itself.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_event_e{}, xge_hal_driver_config_t{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Usage: See ex_slow_path{}.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_poll(xge_hal_device_h devh)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl unsigned char item_buf[sizeof(xge_queue_item_t) +
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_DEFAULT_EVENT_MAX_DATA_SIZE];
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_queue_item_t *item = (xge_queue_item_t *)(void *)item_buf;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_queue_status_e qstatus;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_status_e hstatus;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int i = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl int queue_has_critical_event = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl_again:
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->is_initialized ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->terminating ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->magic != XGE_HAL_MAGIC)
a23fd118e437af0a7877dd313db8fdaa3537c675yl return;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!queue_has_critical_event)
a23fd118e437af0a7877dd313db8fdaa3537c675yl queue_has_critical_event =
a23fd118e437af0a7877dd313db8fdaa3537c675yl __queue_get_reset_critical(hldev->queueh);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->in_poll = 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl while (i++ < XGE_HAL_DRIVER_QUEUE_CONSUME_MAX || queue_has_critical_event) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl qstatus = xge_queue_consume(hldev->queueh,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_DEFAULT_EVENT_MAX_DATA_SIZE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl item);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (qstatus == XGE_QUEUE_IS_EMPTY)
a23fd118e437af0a7877dd313db8fdaa3537c675yl break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_queue(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "queueh 0x%llx consumed event: %d ctxt 0x%llx",
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u64)(ulong_t)hldev->queueh, item->event_type,
a23fd118e437af0a7877dd313db8fdaa3537c675yl (u64)(ulong_t)item->context);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!hldev->is_initialized ||
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->magic != XGE_HAL_MAGIC) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->in_poll = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl return;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl switch (item->event_type) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_EVENT_LINK_IS_UP: {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!queue_has_critical_event &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->uld_callbacks.link_up) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->uld_callbacks.link_up(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->upper_layer_info);
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->link_state = XGE_HAL_LINK_UP;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_EVENT_LINK_IS_DOWN: {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (!queue_has_critical_event &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->uld_callbacks.link_down) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->uld_callbacks.link_down(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->upper_layer_info);
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->link_state = XGE_HAL_LINK_DOWN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_EVENT_SERR:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_EVENT_ECCERR:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_EVENT_PARITYERR:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_EVENT_TARGETABORT:
a23fd118e437af0a7877dd313db8fdaa3537c675yl case XGE_HAL_EVENT_SLOT_FREEZE: {
a23fd118e437af0a7877dd313db8fdaa3537c675yl void *item_data = xge_queue_item_data(item);
a23fd118e437af0a7877dd313db8fdaa3537c675yl int event_type = item->event_type;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64 = *((u64*)item_data);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (event_type != XGE_HAL_EVENT_SLOT_FREEZE)
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_hal_device_is_slot_freeze(hldev))
a23fd118e437af0a7877dd313db8fdaa3537c675yl event_type = XGE_HAL_EVENT_SLOT_FREEZE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (g_xge_hal_driver->uld_callbacks.crit_err) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->uld_callbacks.crit_err(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->upper_layer_info,
a23fd118e437af0a7877dd313db8fdaa3537c675yl event_type,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64);
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* handle one critical event per poll cycle */
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->in_poll = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl return;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl } break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl default: {
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_debug_queue(XGE_TRACE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl "got non-HAL event %d",
a23fd118e437af0a7877dd313db8fdaa3537c675yl item->event_type);
a23fd118e437af0a7877dd313db8fdaa3537c675yl } break;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* broadcast this event */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (g_xge_hal_driver->uld_callbacks.event)
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->uld_callbacks.event(item);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (g_xge_hal_driver->uld_callbacks.before_device_poll) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (g_xge_hal_driver->uld_callbacks.before_device_poll(
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev) != 0) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->in_poll = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl return;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hstatus = __hal_device_poll(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (g_xge_hal_driver->uld_callbacks.after_device_poll)
a23fd118e437af0a7877dd313db8fdaa3537c675yl g_xge_hal_driver->uld_callbacks.after_device_poll(hldev);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * handle critical error right away:
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - walk the device queue again
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - drop non-critical events, if any
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - look for the 1st critical
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (hstatus == XGE_HAL_ERR_CRITICAL) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl queue_has_critical_event = 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl goto _again;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl hldev->in_poll = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_rts_rth_init - Set enhanced mode for RTS hashing.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function is used to set the adapter to enhanced mode.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_set().
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_rts_rth_init(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Set the receive traffic steering mode from default(classic)
a23fd118e437af0a7877dd313db8fdaa3537c675yl * to enhanced.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_CTRL_ENHANCED_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->rts_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_rts_rth_clr - Clear RTS hashing.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function is used to clear all RTS hashing related stuff.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * It brings the adapter out from enhanced mode to classic mode.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * It also clears RTS_RTH_CFG register i.e clears hash type, function etc.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_rts_rth_set(), xge_hal_rts_rth_itable_set().
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_rts_rth_clr(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /*
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Set the receive traffic steering mode from default(classic)
a23fd118e437af0a7877dd313db8fdaa3537c675yl * to enhanced.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~XGE_HAL_RTS_CTRL_ENHANCED_MODE;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64, &bar0->rts_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_rts_rth_set - Set/configure RTS hashing.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @def_q: default queue
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hash_type: hash type i.e TcpIpV4, TcpIpV6 etc.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @bucket_size: no of least significant bits to be used for hashing.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Used to set/configure all RTS hashing related stuff.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - set the steering mode to enhanced.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - set hash function i.e algo selection.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * - set the default queue.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_itable_set().
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_rts_rth_set(xge_hal_device_t *hldev, u8 def_q, u64 hash_type,
a23fd118e437af0a7877dd313db8fdaa3537c675yl u16 bucket_size)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RTS_DEFAULT_Q(def_q);
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_default_q);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = hash_type;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_RTH_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_RTH_BUCKET_SIZE(bucket_size);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_RTH_ALG_SEL_MS;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_rts_rth_start - Start RTS hashing.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Used to Start RTS hashing .
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_itable_set(), xge_hal_rts_rth_start.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_rts_rth_start(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= XGE_HAL_RTS_RTH_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_rts_rth_stop - Stop the RTS hashing.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Used to Staop RTS hashing .
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_itable_set(), xge_hal_rts_rth_start.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_rts_rth_stop(xge_hal_device_t *hldev)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 &= ~XGE_HAL_RTS_RTH_EN;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_cfg);
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_rts_rth_itable_set - Set/configure indirection table (IT).
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @itable: Pointer to the indirection table
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @itable_size: no of least significant bits to be used for hashing
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * Used to set/configure indirection table.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * It enables the required no of entries in the IT.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * It adds entries to the IT.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_set().
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_status_e
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_rts_rth_itable_set(xge_hal_device_t *hldev, u8 *itable, u32 itable_size)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *)hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u32 idx;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl for (idx = 0; idx < itable_size; idx++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = XGE_HAL_RTS_RTH_MAP_MEM_DATA_ENTRY_EN |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTS_RTH_MAP_MEM_DATA(itable[idx]);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_map_mem_data);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* execute */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = (XGE_HAL_RTS_RTH_MAP_MEM_CTRL_WE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTS_RTH_MAP_MEM_CTRL_STROBE |
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTS_RTH_MAP_MEM_CTRL_OFFSET(idx));
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_map_mem_ctrl);
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* poll until done */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (__hal_device_register_poll(hldev,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_map_mem_ctrl, 0,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_RTS_RTH_MAP_MEM_CTRL_STROBE,
a23fd118e437af0a7877dd313db8fdaa3537c675yl XGE_HAL_DEVICE_CMDMEM_WAIT_MAX_MILLIS) != XGE_HAL_OK) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* upper layer may require to repeat */
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING;
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return XGE_HAL_OK;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_rts_rth_key_set - Configure 40byte secret for hash calc.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @KeySize: Number of 64-bit words
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @Key: upto 40-byte array of 8-bit values
a23fd118e437af0a7877dd313db8fdaa3537c675yl * This function configures the 40-byte secret which is used for hash
a23fd118e437af0a7877dd313db8fdaa3537c675yl * calculation.
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_set().
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylvoid
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_rts_rth_key_set(xge_hal_device_t *hldev, u8 KeySize, u8 *Key)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)(void *) hldev->bar0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u64 val64;
a23fd118e437af0a7877dd313db8fdaa3537c675yl u32 entry, nreg, i;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl entry = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl nreg = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl while( KeySize ) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl for ( i = 0; i < 8 ; i++) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Prepare 64-bit word for 'nreg' containing 8 keys. */
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (i)
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 <<= 8;
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 |= Key[entry++];
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl KeySize--;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* temp64 = XGE_HAL_RTH_HASH_MASK_n(val64, (n<<3), (n<<3)+7);*/
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_hash_mask[nreg++]);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl while( nreg < 5 ) {
a23fd118e437af0a7877dd313db8fdaa3537c675yl /* Clear the rest if key is less than 40 bytes */
a23fd118e437af0a7877dd313db8fdaa3537c675yl val64 = 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64,
a23fd118e437af0a7877dd313db8fdaa3537c675yl &bar0->rts_rth_hash_mask[nreg++]);
a23fd118e437af0a7877dd313db8fdaa3537c675yl }
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl/**
a23fd118e437af0a7877dd313db8fdaa3537c675yl * xge_hal_device_is_closed - Device is closed
a23fd118e437af0a7877dd313db8fdaa3537c675yl *
a23fd118e437af0a7877dd313db8fdaa3537c675yl * @hldev: HAL device handle.
a23fd118e437af0a7877dd313db8fdaa3537c675yl */
a23fd118e437af0a7877dd313db8fdaa3537c675ylint
a23fd118e437af0a7877dd313db8fdaa3537c675ylxge_hal_device_is_closed(xge_hal_device_h devh)
a23fd118e437af0a7877dd313db8fdaa3537c675yl{
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_hal_device_t *hldev = (xge_hal_device_t *)devh;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl if (xge_list_is_empty(&hldev->fifo_channels) &&
a23fd118e437af0a7877dd313db8fdaa3537c675yl xge_list_is_empty(&hldev->ring_channels))
a23fd118e437af0a7877dd313db8fdaa3537c675yl return 1;
a23fd118e437af0a7877dd313db8fdaa3537c675yl
a23fd118e437af0a7877dd313db8fdaa3537c675yl return 0;
a23fd118e437af0a7877dd313db8fdaa3537c675yl}
a23fd118e437af0a7877dd313db8fdaa3537c675yl