xgehal-device.c revision 8347601bcb0a439f6e50fc36b4039a73d08700e1
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright (c) 2002-2006 Neterion, Inc.
*/
#include "xgehal-device.h"
#include "xgehal-channel.h"
#include "xgehal-fifo.h"
#include "xgehal-ring.h"
#include "xgehal-driver.h"
#include "xgehal-mgmt.h"
#define SWITCH_SIGN 0xA5A5A5A5A5A5A5A5ULL
#define END_SIGN 0x0
#ifdef XGE_HAL_HERC_EMULATION
#endif
/*
* Jenkins hash key length(in bytes)
*/
#define XGE_HAL_JHASH_MSG_LEN 50
/*
* mix(a,b,c) used in Jenkins hash algorithm
*/
#define mix(a,b,c) { \
a -= b; a -= c; a ^= (c>>13); \
b -= c; b -= a; b ^= (a<<8); \
c -= a; c -= b; c ^= (b>>13); \
a -= b; a -= c; a ^= (c>>12); \
b -= c; b -= a; b ^= (a<<16); \
c -= a; c -= b; c ^= (b>>5); \
a -= b; a -= c; a ^= (c>>3); \
b -= c; b -= a; b ^= (a<<10); \
c -= a; c -= b; c ^= (b>>15); \
}
extern xge_hal_driver_t *g_xge_hal_driver;
/*
* __hal_device_event_queued
* @data: pointer to xge_hal_device_t structure
*
* Will be called when new event succesfully queued.
*/
void
{
}
}
/*
* __hal_pio_mem_write32_upper
*
* Endiann-aware implementation of xge_os_pio_mem_write32().
* Since Xframe has 64bit registers, we differintiate uppper and lower
* parts.
*/
void
{
#if defined(XGE_OS_HOST_BIG_ENDIAN) && !defined(XGE_OS_PIO_LITTLE_ENDIAN)
#else
#endif
}
/*
* __hal_pio_mem_write32_upper
*
* Endiann-aware implementation of xge_os_pio_mem_write32().
* Since Xframe has 64bit registers, we differintiate uppper and lower
* parts.
*/
void
void *addr)
{
#if defined(XGE_OS_HOST_BIG_ENDIAN) && !defined(XGE_OS_PIO_LITTLE_ENDIAN)
(void *) ((char *)addr + 4));
#else
#endif
}
/*
* __hal_device_register_poll
* @hldev: pointer to xge_hal_device_t structure
* @reg: register to poll for
* @op: 0 - bit reset, 1 - bit set
* @mask: mask for logical "and" condition based on %op
* @max_millis: maximum time to try to poll in milliseconds
*
* Will poll certain register for specified amount of time.
* Will poll until masked bit is not cleared.
*/
{
int i = 0;
xge_os_udelay(10);
do {
return XGE_HAL_OK;
return XGE_HAL_OK;
xge_os_udelay(100);
} while (++i <= 9);
do {
return XGE_HAL_OK;
return XGE_HAL_OK;
xge_os_udelay(1000);
} while (++i < max_millis);
return ret;
}
/*
* __hal_device_wait_quiescent
* @hldev: the device
* @hw_status: hw_status in case of error
*
* Will wait until device is quiescent for some blocks.
*/
static xge_hal_status_e
{
/* poll and wait first */
#ifdef XGE_HAL_HERC_EMULATION
#else
#endif
}
/**
* xge_hal_device_is_slot_freeze
* @devh: the device
*
* Returns non-zero if the slot is freezed.
* The determination is made based on the adapter_status
* register which will never give all FFs, unless PCI read
* cannot go through.
*/
int
{
&bar0->adapter_status);
&device_id);
#ifdef TX_DEBUG
if (adapter_status == XGE_HAL_ALL_FOXES)
{
&bar0->pcc_enable);
printf(">>> Slot is frozen!\n");
brkpoint(0);
}
#endif
}
/*
* __hal_device_led_actifity_fix
* @hldev: pointer to xge_hal_device_t structure
*
* SXE-002: Configure link and activity LED to turn it off
*/
static void
{
/*
* In the case of Herc, there is a new register named beacon control
* is added which was not present in Xena.
* Beacon control register in Herc is at the same offset as
* gpio control register in Xena. It means they are one and same in
* the case of Xena. Also, gpio control register offset in Herc and
* Xena is different.
* The current register map represents Herc(It means we have
* both beacon and gpio control registers in register map).
* WRT transition from Xena to Herc, all the code in Xena which was
* using gpio control register for LED handling would have to
* use beacon control register in Herc and the rest of the code
* which uses gpio control in Xena would use the same register
* in Herc.
* WRT LED handling(following code), In the case of Herc, beacon
* control register has to be used. This is applicable for Xena also,
* since it represents the gpio control register in Xena.
*/
&bar0->beacon_control);
val64 |= 0x0000800000000000ULL;
val64 = 0x0411040400000000ULL;
}
}
/* Constants for Fixing the MacAddress problem seen mostly on
* Alpha machines.
*/
static u64 xena_fix_mac[] = {
0x0060000000000000ULL, 0x0060600000000000ULL,
0x0040600000000000ULL, 0x0000600000000000ULL,
0x0020600000000000ULL, 0x0060600000000000ULL,
0x0020600000000000ULL, 0x0060600000000000ULL,
0x0020600000000000ULL, 0x0060600000000000ULL,
0x0020600000000000ULL, 0x0060600000000000ULL,
0x0020600000000000ULL, 0x0060600000000000ULL,
0x0020600000000000ULL, 0x0060600000000000ULL,
0x0020600000000000ULL, 0x0060600000000000ULL,
0x0020600000000000ULL, 0x0060600000000000ULL,
0x0020600000000000ULL, 0x0060600000000000ULL,
0x0020600000000000ULL, 0x0060600000000000ULL,
0x0020600000000000ULL, 0x0000600000000000ULL,
0x0040600000000000ULL, 0x0060600000000000ULL,
};
/*
* __hal_device_fix_mac
* @hldev: HAL device handle.
*
* Fix for all "FFs" MAC address problems observed on Alpha platforms.
*/
static void
{
int i = 0;
/*
* In the case of Herc, there is a new register named beacon control
* is added which was not present in Xena.
* Beacon control register in Herc is at the same offset as
* gpio control register in Xena. It means they are one and same in
* the case of Xena. Also, gpio control register offset in Herc and
* Xena is different.
* The current register map represents Herc(It means we have
* both beacon and gpio control registers in register map).
* WRT transition from Xena to Herc, all the code in Xena which was
* using gpio control register for LED handling would have to
* use beacon control register in Herc and the rest of the code
* which uses gpio control in Xena would use the same register
* in Herc.
* In the following code(xena_fix_mac), beacon control register has
* to be used in the case of Xena, since it represents gpio control
* register. In the case of Herc, there is no change required.
*/
while (xena_fix_mac[i] != END_SIGN) {
xge_os_mdelay(1);
}
}
/*
* xge_hal_device_bcast_enable
* @hldev: HAL device handle.
*
* Enable receiving broadcasts.
* The host must first write RMAC_CFG_KEY "key"
* register, and then - MAC_CFG register.
*/
void
{
(unsigned long long)val64,
}
/*
* xge_hal_device_bcast_disable
* @hldev: HAL device handle.
*
* Disable receiving broadcasts.
* The host must first write RMAC_CFG_KEY "key"
* register, and then - MAC_CFG register.
*/
void
{
(unsigned long long)val64,
}
/*
* __hal_device_shared_splits_configure
* @hldev: HAL device handle.
*
* TxDMA will stop Read request if the number of read split had exceeded
* the limit set by shared_splits
*/
static void
{
&bar0->pic_control);
val64 |=
&bar0->pic_control);
}
/*
* __hal_device_rmac_padding_configure
* @hldev: HAL device handle.
*
* Configure RMAC frame padding. Depends on configuration, it
* can be send to host or removed by MAC.
*/
static void
{
val64 &= ( ~XGE_HAL_MAC_RMAC_ALL_ADDR_ENABLE );
val64 &= ( ~XGE_HAL_MAC_CFG_RMAC_PROM_ENABLE );
/*
* If the RTH enable bit is not set, strip the FCS
*/
}
val64 &= ( ~XGE_HAL_MAC_CFG_RMAC_STRIP_PAD );
xge_os_mdelay(1);
(unsigned long long)val64);
}
/*
* __hal_device_pause_frames_configure
* @hldev: HAL device handle.
*
* Set Pause threshold.
*
* Pause frame is generated if the amount of data outstanding
* on any queue exceeded the ratio of
* (mac_control.mc_pause_threshold_q0q3 or q4q7)/256
*/
static void
{
int i;
case XGE_HAL_MEDIA_SR:
case XGE_HAL_MEDIA_SW:
val64=0xfffbfffbfffbfffbULL;
break;
case XGE_HAL_MEDIA_LR:
case XGE_HAL_MEDIA_LW:
val64=0xffbbffbbffbbffbbULL;
break;
case XGE_HAL_MEDIA_ER:
case XGE_HAL_MEDIA_EW:
default:
val64=0xffbbffbbffbbffbbULL;
break;
}
/* Set the time value to be inserted in the pause frame generated
* by Xframe */
&bar0->rmac_pause_cfg);
else
val64 &= ~(XGE_HAL_RMAC_PAUSE_GEN_EN);
else
val64 &= ~(XGE_HAL_RMAC_PAUSE_RCV_EN);
&bar0->rmac_pause_cfg);
val64 = 0;
for (i = 0; i<4; i++) {
val64 |=
<<(i*2*8));
}
val64 = 0;
for (i = 0; i<4; i++) {
val64 |=
<<(i*2*8));
}
}
/*
* Herc's clock rate doubled, unless the slot is 33MHz.
*/
unsigned int time_ival)
{
return time_ival;
time_ival *= 2;
return time_ival;
}
/*
* __hal_device_bus_master_disable
* @hldev: HAL device handle.
*
* Disable bus mastership.
*/
static void
{
cmd &= ~bus_master;
}
/*
* __hal_device_bus_master_enable
* @hldev: HAL device handle.
*
* Disable bus mastership.
*/
static void
{
/* already enabled? do nothing */
if (cmd & bus_master)
return;
cmd |= bus_master;
}
/*
* __hal_device_intr_mgmt
* @hldev: HAL device handle.
* @mask: mask indicating which Intr block must be modified.
* @flag: if true - enable, otherwise - disable interrupts.
*
* Disable or enable device interrupts. Mask is used to specify
* which hardware blocks should produce interrupts. For details
* please refer to Xframe User Guide.
*/
static void
{
/* Top level interrupt classification */
/* PIC Interrupts */
/* Enable PIC Intrs in the general intr mask register */
if (flag) {
temp64 &= ~XGE_HAL_PIC_INT_TX;
if (xge_hal_device_check_id(hldev) ==
}
#endif
if (xge_hal_device_check_id(hldev) ==
/*
* Unmask only Link Up interrupt
*/
&bar0->misc_int_mask);
"unmask link up flag "XGE_OS_LLXFMT,
(unsigned long long)temp64);
}
#endif
} else { /* flag == 0 */
if (xge_hal_device_check_id(hldev) ==
/*
* Mask both Link Up and Down interrupts
*/
&bar0->misc_int_mask);
"mask link up/down flag "XGE_OS_LLXFMT,
(unsigned long long)temp64);
}
#endif
/* Disable PIC Intrs in the general intr mask
* register */
&bar0->pic_int_mask);
}
}
/* DMA Interrupts */
if (mask & XGE_HAL_TX_DMA_INTR) {
/* Enable TxDMA Intrs in the general intr mask register */
if (flag) {
/* Disable all TxDMA interrupts */
&bar0->txdma_int_mask);
&bar0->pfc_err_mask);
} else { /* flag == 0 */
/* Disable TxDMA Intrs in the general intr mask
* register */
&bar0->txdma_int_mask);
&bar0->pfc_err_mask);
}
}
if (mask & XGE_HAL_RX_DMA_INTR) {
/* Enable RxDMA Intrs in the general intr mask register */
if (flag) {
/* All RxDMA block interrupts are disabled for now
* TODO */
&bar0->rxdma_int_mask);
} else { /* flag == 0 */
/* Disable RxDMA Intrs in the general intr mask
* register */
&bar0->rxdma_int_mask);
}
}
/* MAC Interrupts */
if (flag) {
/* All MAC block error inter. are disabled for now. */
} else { /* flag == 0 */
/* Disable MAC Intrs in the general intr mask
* register */
}
}
/* XGXS Interrupts */
if (flag) {
/* All XGXS block error interrupts are disabled for now
* TODO */
} else { /* flag == 0 */
/* Disable MC Intrs in the general intr mask register */
}
}
/* Memory Controller(MC) interrupts */
if (mask & XGE_HAL_MC_INTR) {
if (flag) {
/* Enable all MC blocks error interrupts */
} else { /* flag == 0 */
/* Disable MC Intrs in the general intr mask
* register */
}
}
/* Tx traffic interrupts */
if (mask & XGE_HAL_TX_TRAFFIC_INTR) {
if (flag) {
/* Enable all the Tx side interrupts */
/* '0' Enables all 64 TX interrupt levels. */
&bar0->tx_traffic_mask);
} else { /* flag == 0 */
/* Disable Tx Traffic Intrs in the general intr mask
* register. */
&bar0->tx_traffic_mask);
}
}
/* Rx traffic interrupts */
if (mask & XGE_HAL_RX_TRAFFIC_INTR) {
if (flag) {
/* '0' Enables all 8 RX interrupt levels. */
&bar0->rx_traffic_mask);
} else { /* flag == 0 */
/* Disable Rx Traffic Intrs in the general intr mask
* register.
*/
&bar0->rx_traffic_mask);
}
}
/* Sched Timer interrupt */
if (mask & XGE_HAL_SCHED_INTR) {
if (flag) {
} else {
}
}
&bar0->general_int_mask);
}
}
/*
* __hal_device_bimodal_configure
* @hldev: HAL device handle.
*
* Bimodal parameters initialization.
*/
static void
{
int i;
for (i=0; i<XGE_HAL_MAX_RING_NUM; i++) {
continue;
tti->timer_ci_en = 0;
}
}
/*
* __hal_device_tti_apply
* @hldev: HAL device handle.
*
* apply TTI configuration.
*/
static xge_hal_status_e
{
if (runtime)
else
if (tti->timer_val_us) {
unsigned int tx_interval;
} else {
}
if (tti->timer_ac_en) {
}
if (tti->timer_ci_en) {
}
if (!runtime) {
"enabled": "disabled");
}
}
}
&bar0->tti_data1_mem);
&bar0->tti_data2_mem);
xge_os_wmb();
&bar0->tti_command_mem);
/* upper layer may require to repeat */
}
if (!runtime) {
}
return XGE_HAL_OK;
}
/*
* __hal_device_tti_configure
* @hldev: HAL device handle.
*
* TTI Initialization.
* Initialize Transmit Traffic Interrupt Scheme.
*/
static xge_hal_status_e
{
int i;
for (i=0; i<XGE_HAL_MAX_FIFO_NUM; i++) {
int j;
continue;
for (j=0; j<XGE_HAL_MAX_FIFO_TTI_NUM; j++) {
continue;
/* at least some TTI enabled. Record it. */
i * XGE_HAL_MAX_FIFO_TTI_NUM + j, runtime);
if (status != XGE_HAL_OK)
return status;
}
}
/* processing bimodal TTIs */
for (i=0; i<XGE_HAL_MAX_RING_NUM; i++) {
continue;
/* at least some bimodal TTI enabled. Record it. */
if (status != XGE_HAL_OK)
return status;
}
return XGE_HAL_OK;
}
/*
* __hal_device_rti_configure
* @hldev: HAL device handle.
*
* RTI Initialization.
* Initialize Receive Traffic Interrupt Scheme.
*/
{
int i;
if (runtime) {
/*
* we don't want to re-configure RTI in case when
* bimodal interrupts are in use. Instead reconfigure TTI
* with new RTI values.
*/
}
} else
for (i=0; i<XGE_HAL_MAX_RING_NUM; i++) {
continue;
if (rti->timer_val_us) {
unsigned int rx_interval;
} else {
}
if (rti->timer_ac_en) {
}
}
}
&bar0->rti_data1_mem);
&bar0->rti_data2_mem);
xge_os_wmb();
val64 |= XGE_HAL_RTI_CMD_MEM_OFFSET(i);
&bar0->rti_command_mem);
&bar0->rti_command_mem, 0,
/* upper layer may require to repeat */
}
if (!runtime) {
"RTI[%d] configured: rti_data1_mem 0x"XGE_OS_LLXFMT,
i,
}
}
return XGE_HAL_OK;
}
/* Constants to be programmed into the Xena's registers to configure
* the XAUI. */
static u64 default_xena_mdio_cfg[] = {
/* Reset PMA PLL */
0xC001010000000000ULL, 0xC0010100000000E0ULL,
0xC0010100008000E4ULL,
/* Remove Reset from PMA PLL */
0xC001010000000000ULL, 0xC0010100000000E0ULL,
0xC0010100000000E4ULL,
};
static u64 default_herc_mdio_cfg[] = {
};
static u64 default_xena_dtx_cfg[] = {
0x8000051500000000ULL, 0x80000515000000E0ULL,
0x80000515D93500E4ULL, 0x8001051500000000ULL,
0x80010515000000E0ULL, 0x80010515001E00E4ULL,
0x8002051500000000ULL, 0x80020515000000E0ULL,
0x80020515F21000E4ULL,
/* Set PADLOOPBACKN */
0x8002051500000000ULL, 0x80020515000000E0ULL,
0x80020515B20000E4ULL, 0x8003051500000000ULL,
0x80030515000000E0ULL, 0x80030515B20000E4ULL,
0x8004051500000000ULL, 0x80040515000000E0ULL,
0x80040515B20000E4ULL, 0x8005051500000000ULL,
0x80050515000000E0ULL, 0x80050515B20000E4ULL,
/* Remove PADLOOPBACKN */
0x8002051500000000ULL, 0x80020515000000E0ULL,
0x80020515F20000E4ULL, 0x8003051500000000ULL,
0x80030515000000E0ULL, 0x80030515F20000E4ULL,
0x8004051500000000ULL, 0x80040515000000E0ULL,
0x80040515F20000E4ULL, 0x8005051500000000ULL,
0x80050515000000E0ULL, 0x80050515F20000E4ULL,
};
/*
static u64 default_herc_dtx_cfg[] = {
0x80000515BA750000ULL, 0x80000515BA7500E0ULL,
0x80000515BA750004ULL, 0x80000515BA7500E4ULL,
0x80010515003F0000ULL, 0x80010515003F00E0ULL,
0x80010515003F0004ULL, 0x80010515003F00E4ULL,
0x80020515F2100000ULL, 0x80020515F21000E0ULL,
0x80020515F2100004ULL, 0x80020515F21000E4ULL,
END_SIGN
};
*/
static u64 default_herc_dtx_cfg[] = {
0x8000051536750000ULL, 0x80000515367500E0ULL,
0x8000051536750004ULL, 0x80000515367500E4ULL,
0x80010515003F0000ULL, 0x80010515003F00E0ULL,
0x80010515003F0004ULL, 0x80010515003F00E4ULL,
0x801205150D440000ULL, 0x801205150D4400E0ULL,
0x801205150D440004ULL, 0x801205150D4400E4ULL,
0x80020515F2100000ULL, 0x80020515F21000E0ULL,
0x80020515F2100004ULL, 0x80020515F21000E4ULL,
};
/*
* __hal_device_xaui_configure
* @hldev: HAL device handle.
*
* Configure XAUI Interface of Xena.
*
* To Configure the Xena's XAUI, one has to write a series
* of 64 bit values into two registers in a particular
* sequence. Hence a macro 'SWITCH_SIGN' has been defined
* which will be defined in the array of configuration values
* (default_dtx_cfg & default_mdio_cfg) at appropriate places
* to switch writing from one regsiter to another. We continue
* writing these values until we encounter the 'END_SIGN' macro.
* For example, After making a series of 21 writes into
* dtx_control register the 'SWITCH_SIGN' appears and hence we
* start writing into mdio_control until we encounter END_SIGN.
*/
static void
{
} else
do {
dtx_cnt++;
goto mdio_cfg;
}
&bar0->dtx_control);
&bar0->dtx_control);
xge_os_wmb();
xge_os_mdelay(1);
dtx_cnt++;
}
mdio_cnt++;
goto dtx_cfg;
}
&bar0->mdio_control);
&bar0->mdio_control);
xge_os_wmb();
xge_os_mdelay(1);
mdio_cnt++;
}
}
/*
* __hal_device_mac_link_util_set
* @hldev: HAL device handle.
*
* Set sampling rate to calculate link utilization.
*/
static void
{
&bar0->mac_link_util);
"bandwidth link utilization configured");
}
/*
* __hal_device_set_swapper
* @hldev: HAL device handle.
*
* Set the Xframe's byte "swapper" in accordance with
* endianness of the host.
*/
{
/*
* from 32bit errarta:
*
* The SWAPPER_CONTROL register determines how the adapter accesses
* host memory as well as how it responds to read and write requests
* from the host system. Writes to this register should be performed
* carefully, since the byte swappers could reverse the order of bytes.
* When configuring this register keep in mind that writes to the PIF
* read and write swappers could reverse the order of the upper and
* lower 32-bit words. This means that the driver may have to write
* to the upper 32 bits of the SWAPPER_CONTROL twice in order to
* configure the entire register. */
/*
* The device by default set to a big endian format, so a big endian
* driver need not set anything.
*/
#if defined(XGE_HAL_CUSTOM_HW_SWAPPER)
xge_os_wmb();
&bar0->swapper_ctrl);
(unsigned long long)val64);
#elif !defined(XGE_OS_HOST_BIG_ENDIAN)
/*
* Initially we enable all bits to make it accessible by the driver,
* then we selectively enable only those bits that we want to set.
* i.e. force swapper to swap for the first time since second write
* will overwrite with the final settings.
*
* Use only for little endian platforms.
*/
xge_os_wmb();
/*
if (hldev->config.intr_mode == XGE_HAL_INTR_MODE_MSIX) {
val64 |= XGE_HAL_SWAPPER_CTRL_XMSI_SE;
} */
&bar0->swapper_ctrl);
xge_os_wmb();
&bar0->swapper_ctrl);
xge_os_wmb();
&bar0->swapper_ctrl);
#endif
/* Verifying if endian settings are accurate by reading a feedback
* register. */
if (val64 != XGE_HAL_IF_RD_SWAPPER_FB) {
(unsigned long long) val64);
return XGE_HAL_ERR_SWAPPER_CTRL;
}
return XGE_HAL_OK;
}
/*
* __hal_device_rts_mac_configure - Configure RTS steering based on
* destination mac address.
* @hldev: HAL device handle.
*
*/
{
return XGE_HAL_OK;
}
/*
* Set the receive traffic steering mode from default(classic)
* to enhanced.
*/
return XGE_HAL_OK;
}
/*
* __hal_device_rts_qos_configure - Configure RTS steering based on
* qos.
* @hldev: HAL device handle.
*
*/
{
int j;
return XGE_HAL_OK;
}
/* First clear the RTS_DS_MEM_DATA */
val64 = 0;
for (j = 0; j < 64; j++ )
{
/* First clear the value */
val64 = XGE_HAL_RTS_DS_MEM_DATA(0);
&bar0->rts_ds_mem_data);
&bar0->rts_ds_mem_ctrl);
/* poll until done */
&bar0->rts_ds_mem_ctrl, 0,
/* upper layer may require to repeat */
}
}
/* Check for enhanced mode */
/* Check to see if QOS Steering is turned ON and adapter is in classic mode */
if (!(val64 & XGE_HAL_RTS_CTRL_ENHANCED_MODE))
{
/* Set the priority calendar - hard coded as all rings should be enabled */
val64 = 0x0706050407030602;
val64 = 0x0507040601070503;
val64 = 0x0604070205060700;
val64 = 0x0403060705010207;
val64 = 0x0604050300000000;
}
return XGE_HAL_OK;
}
/*
* xge__hal_device_rts_mac_enable
*
* @devh: HAL device handle.
* @index: index number where the MAC addr will be stored
* @macaddr: MAC address
*
* - Enable RTS steering for the given MAC address. This function has to be
* called with lock acquired.
*
* NOTE:
* 1. ULD has to call this function with the index value which
* statisfies the following condition:
* ring_num = (index % 8)
* 2.ULD also needs to make sure that the index is not
* occupied by any MAC address. If that index has any MAC address
* it will be overwritten and HAL will not check for it.
*
*/
{
return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
/*
* Set the MAC address at the given location marked by index.
*/
if (status != XGE_HAL_OK) {
"Not able to set the mac addr");
return status;
}
}
/*
* xge__hal_device_rts_mac_disable
* @hldev: HAL device handle.
* @index: index number where to disable the MAC addr
*
* Disable RTS Steering based on the MAC address.
* This function should be called with lock acquired.
*
*/
{
return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
/*
* Disable MAC address @ given index location
*/
if (status != XGE_HAL_OK) {
"Not able to set the mac addr");
return status;
}
return XGE_HAL_OK;
}
/*
* __hal_device_rth_configure - Configure RTH for the device
* @hldev: HAL device handle.
*
* Using IT (Indirection Table).
*/
{
int rings[XGE_HAL_MAX_RING_NUM]={0};
int rnum;
int rmax;
int buckets_num;
int bucket;
return XGE_HAL_OK;
}
/*
* Set the receive traffic steering mode from default(classic)
* to enhanced.
*/
rmax=0;
}
rnum = 0;
/* for starters: fill in all the buckets with rings "equally" */
rnum = 0;
/* write data */
/* execute */
/* poll until done */
&bar0->rts_rth_map_mem_ctrl, 0,
}
rnum++;
}
&bar0->rts_rth_cfg);
return XGE_HAL_OK;
}
/*
* __hal_spdm_entry_add - Add a new entry to the SPDM table.
*
* Add a new entry to the SPDM table
*
* This function add a new entry to the SPDM table.
*
* Note:
* This function should be called with spdm_lock.
*
* See also: xge_hal_spdm_entry_add , xge_hal_spdm_entry_remove.
*/
static xge_hal_status_e
{
/*
* Clear the SPDM READY bit
*/
&bar0->rxpic_int_reg);
"L4 SP %x:DP %x: hash %x tgt_queue %d \n",
/*
* Construct the SPDM entry.
*/
if (is_ipv4) {
} else {
}
/*
* Add the entry to the SPDM table
*/
(void *)((char *)hldev->spdm_mem_base +
(spdm_entry * 64) +
(line_no * 8)));
}
/*
* Wait for the operation to be completed.
*/
}
/*
* Add this information to a local SPDM table. The purpose of
* maintaining a local SPDM table is to avoid a search in the
* adapter SPDM table for spdm entry lookup which is very costly
* in terms of time.
*/
sizeof(xge_hal_ipaddr_t));
sizeof(xge_hal_ipaddr_t));
return XGE_HAL_OK;
}
/*
* __hal_device_rth_spdm_configure - Configure RTH for the device
* @hldev: HAL device handle.
*
* Using SPDM (Socket-Pair Direct Match).
*/
{
int spdm_table_size;
int i;
return XGE_HAL_OK;
}
/*
* Retrieve the base address of SPDM Table.
*/
/*
* spdm_bar_num specifies the PCI bar num register used to
* address the memory space. spdm_bar_offset specifies the offset
* of the SPDM memory with in the bar num memory space.
*/
switch (spdm_bar_num) {
case 0:
{
(spdm_bar_offset * 8);
break;
}
case 1:
{
break;
}
default:
}
/*
* Retrieve the size of SPDM table(number of entries).
*/
sizeof(xge_hal_spdm_entry_t);
void *mem;
/*
* Allocate memory to hold the copy of SPDM table.
*/
(sizeof(xge_hal_spdm_entry_t *) *
return XGE_HAL_ERR_OUT_OF_MEMORY;
}
{
(sizeof(xge_hal_spdm_entry_t *) *
return XGE_HAL_ERR_OUT_OF_MEMORY;
}
for (i = 0; i < hldev->spdm_max_entries; i++) {
((char *)mem +
i * sizeof(xge_hal_spdm_entry_t));
}
} else {
/*
* We are here because the host driver tries to
* do a soft reset on the device.
* Since the device soft reset clears the SPDM table, copy
* the entries from the local SPDM table to the actual one.
*/
for (i = 0; i < hldev->spdm_max_entries; i++) {
if (spdm_entry->in_use) {
&spdm_entry->src_ip,
&spdm_entry->dst_ip,
!= XGE_HAL_OK) {
/* Log an warning */
"SPDM table update from local"
" memory failed");
}
}
}
}
/*
* Set the receive traffic steering mode from default(classic)
* to enhanced.
*/
/*
* We may not need to configure rts_rth_jhash_cfg register as the
* default values are good enough to calculate the hash.
*/
/*
* As of now, set all the rth mask registers to zero. TODO.
*/
for(i = 0; i < 5; i++) {
0, &bar0->rts_rth_hash_mask[i]);
}
0, &bar0->rts_rth_hash_mask_5);
}
&bar0->rts_rth_cfg);
return XGE_HAL_OK;
}
/*
* __hal_device_pci_init
* @hldev: HAL device handle.
*
* with recommended values. Save config space for future hw resets.
*/
static void
{
int i, pcisize = 0;
/* Set the PErr Repconse bit and SERR in PCI command register. */
cmd |= 0x140;
/* Set user spcecified value for the PCI Latency Timer */
}
/* Read back latency timer to reflect it into user level */
/* Enable Data Parity Error Recovery in PCI-X command register. */
cmd |= 1;
/* Set MMRB count in PCI-X command register. */
cmd &= 0xFFF3;
cmd);
}
/* Read back MMRB count to reflect it into user level */
&cmd);
cmd &= 0x000C;
/* Setting Maximum outstanding splits based on system type. */
&cmd);
cmd &= 0xFF8F;
cmd);
}
/* Read back max split trans to reflect it into user level */
cmd &= 0x0070;
/* Forcibly disabling relaxed ordering capability of the card. */
cmd &= 0xFFFD;
/* Store PCI device ID and revision for future references where in we
* decide Xena revision using PCI sub system ID */
/* save PCI config space for future resets */
for (i = 0; i < pcisize; i++) {
}
#if defined(XGE_HAL_MSI)
/* Upper limit of the MSI number enabled by the system */
return;
* This number's power of 2 is the number
* of MSIs enabled.
*/
/*
* NOTE:
* If 32 MSIs are enabled, then MSI numbers range from 0 - 31.
*/
#endif
}
/*
* __hal_device_pci_info_get - Get PCI bus informations such as width, frequency
* and mode.
* @devh: HAL device handle.
* @pci_mode: pointer to a variable of enumerated type
* xge_hal_pci_mode_e{}.
* @bus_frequency: pointer to a variable of enumerated type
* xge_hal_pci_bus_frequency_e{}.
* @bus_width: pointer to a variable of enumerated type
* xge_hal_pci_bus_width_e{}.
*
* Get pci mode, frequency, and PCI bus width.
*
* Returns: one of the xge_hal_status_e{} enumerated types.
* XGE_HAL_OK - for success.
* XGE_HAL_ERR_INVALID_PCI_INFO - for invalid PCI information from the card.
* XGE_HAL_ERR_BAD_DEVICE_ID - for invalid card.
*
* See Also: xge_hal_pci_mode_e, xge_hal_pci_mode_e, xge_hal_pci_width_e.
*/
static xge_hal_status_e
{
#ifdef XGE_HAL_HERC_EMULATION
#else
if (card_id == XGE_HAL_CARD_HERC) {
if (XGE_HAL_PCI_32_BIT & pci_info)
else
{
case XGE_HAL_PCI_33MHZ_MODE:
break;
case XGE_HAL_PCI_66MHZ_MODE:
break;
break;
break;
break;
break;
break;
break;
case XGE_HAL_PCIX_M1_RESERVED:
case XGE_HAL_PCIX_M1_66MHZ_NS:
case XGE_HAL_PCIX_M2_RESERVED:
default:
"invalid pci info "XGE_OS_LLXFMT,
(unsigned long long)pci_info);
break;
}
}
}
/* for XENA, we report PCI mode, only. PCI bus frequency, and bus width
* are set to unknown */
else if (card_id == XGE_HAL_CARD_XENA) {
/* initialize defaults for XENA */
&pcix_status);
else
/*
* There is no way to detect BUS frequency on Xena,
* so, in case of automatic configuration we hopelessly
* assume 133MHZ.
*/
}
} else{
}
#endif
return rc_status;
}
/*
* __hal_device_handle_link_up_ind
* @hldev: HAL device handle.
*
* Link up indication handler. The function is invoked by HAL when
* Xframe indicates that the link is up for programmable amount of time.
*/
static int
{
/*
* If the previous link state is not down, return.
*/
&bar0->misc_int_mask);
}
#endif
"link up indication while link is up, ignoring..");
return 0;
}
/* Now re-enable it as due to noise, hardware turned it off */
&bar0->adapter_control);
&bar0->adapter_control);
/* Turn on the Laser */
&bar0->adapter_control);
&bar0->adapter_control);
&bar0->adapter_status);
"fail to transition link to up...");
return 0;
}
else {
/*
* Mask the Link Up interrupt and unmask the Link Down
* interrupt.
*/
&bar0->misc_int_mask);
&bar0->misc_int_mask);
/* notify ULD */
}
return 1;
}
}
#endif
xge_os_mdelay(1);
/* notify ULD */
hldev);
/* link is up after been enabled */
return 1;
} else {
"fail to transition link to up...");
return 0;
}
}
/*
* __hal_device_handle_link_down_ind
* @hldev: HAL device handle.
*
* Link down indication handler. The function is invoked by HAL when
* Xframe indicates that the link is down.
*/
static int
{
/*
* If the previous link state is not up, return.
*/
&bar0->misc_int_mask);
}
#endif
"link down indication while link is down, ignoring..");
return 0;
}
xge_os_mdelay(1);
&bar0->adapter_control);
/* try to debounce the link only if the adapter is enabled. */
if (val64 & XGE_HAL_ADAPTER_CNTL_EN) {
"link is actually up (possible noisy link?), ignoring.");
return(0);
}
}
&bar0->adapter_control);
/* turn off LED */
&bar0->adapter_control);
/*
* Mask the Link Down interrupt and unmask the Link up
* interrupt
*/
&bar0->misc_int_mask);
&bar0->misc_int_mask);
/* link is down */
/* notify ULD */
}
return 1;
}
#endif
/* notify ULD */
hldev);
/* link is down */
return 1;
}
/*
* __hal_device_handle_link_state_change
* @hldev: HAL device handle.
*
* Link state change handler. The function is invoked by HAL when
* Xframe indicates link state change condition. The code here makes sure to
* 1) ignore redundant state change indications;
* 2) execute link-up sequence, and handle the failure to bring the link up;
* 3) generate XGE_HAL_LINK_UP/DOWN event for the subsequent handling by
* upper-layer driver (ULD).
*/
static int
{
int hw_link_state;
int retcode;
int i = 0;
&bar0->adapter_control);
/* If the adapter is not enabled but the hal thinks we are in the up
* state then transition to the down state.
*/
if ( !(val64 & XGE_HAL_ADAPTER_CNTL_EN) &&
return(__hal_device_handle_link_down_ind(hldev));
}
do {
xge_os_mdelay(1);
hw_link_state = (hw_status &
/* check if the current link state is still considered
* to be changed. This way we will make sure that this is
* not a noise which needs to be filtered out */
break;
/* If the current link state is same as previous, just return */
retcode = 0;
/* detected state change */
else if (hw_link_state == XGE_HAL_LINK_UP)
else
return retcode;
}
/*
*
*/
static void
{
#ifdef XGE_HAL_USE_MGMT_AUX
(void) xge_hal_aux_device_dump(hldev);
#endif
}
(unsigned long long) value);
}
/*
*
*/
static void
{
#ifdef XGE_HAL_USE_MGMT_AUX
(void) xge_hal_aux_device_dump(hldev);
#endif
}
/* Herc smart enough to recover on its own! */
}
(unsigned long long) value);
}
/*
*
*/
static void
{
#ifdef XGE_HAL_USE_MGMT_AUX
(void) xge_hal_aux_device_dump(hldev);
#endif
}
(unsigned long long) value);
}
/*
*
*/
static void
{
}
/*
* __hal_device_hw_initialize
* @hldev: HAL device handle.
*
* Initialize Xframe hardware.
*/
static xge_hal_status_e
{
/* Set proper endian settings and verify the same by reading the PIF
* Feed-back register. */
if (status != XGE_HAL_OK) {
return status;
}
/* update the pci mode, frequency, and width */
/*
* FIXME: this cannot happen.
* But if it happens we cannot continue just like that
*/
}
/* PCI optimization: set TxReqTimeOut
* register (0x800+0x120) to 0x1ff or
* something close to this.
* Note: not to be used for PCI-X! */
&bar0->txreqtimeout);
&bar0->read_retry_delay);
}
/* added this to set the no of bytes used to update lso_bytes_sent
returned TxD0 */
&bar0->pic_control_2);
&bar0->pic_control_2);
/* added this to clear the EOI_RESET field while leaving XGXS_RESET
* in reset, then a 1-second delay */
xge_os_mdelay(1000);
/* Clear the XGXS_RESET field of the SW_RESET register in order to
* release the XGXS from reset. Its reset value is 0xA5; write 0x00
* to activate the XGXS. The core requires a minimum 500 us reset.*/
xge_os_mdelay(1);
/* read registers in all blocks */
&bar0->mac_int_mask);
&bar0->mc_int_mask);
&bar0->xgxs_int_mask);
/* set default MTU and steer based on length*/
} else {
}
#ifndef XGE_HAL_HERC_EMULATION
#endif
/*
* Keep its PCI REQ# line asserted during a write
* transaction up to the end of the transaction
*/
&bar0->misc_control);
/*
* bimodal interrupts is when all Rx traffic interrupts
* will go to TTI, so we need to adjust RTI settings and
* use adaptive TTI timer. We need to make sure RTI is
* properly configured to sane value which will not
* distrupt bimodal behavior.
*/
int i;
/* force polling_cnt to be "0", otherwise
* IRQ workload statistics will be screwed. This could
* be worked out in TXPIC handler later. */
/* disable all TTI < 56 */
for (i=0; i<XGE_HAL_MAX_FIFO_NUM; i++) {
int j;
continue;
for (j=0; j<XGE_HAL_MAX_FIFO_TTI_NUM; j++) {
}
}
/* now configure bimodal interrupts */
}
if (status != XGE_HAL_OK)
return status;
if (status != XGE_HAL_OK)
return status;
if (status != XGE_HAL_OK)
return status;
if (status != XGE_HAL_OK)
return status;
if (status != XGE_HAL_OK) {
return status;
}
if (status != XGE_HAL_OK) {
return status;
}
/* make sure all interrupts going to be disabled at the moment */
/* SXE-008 Transmit DMA arbitration issue */
&bar0->pcc_enable);
}
}
}
#if defined(XGE_HAL_MSI)
/*
* If MSI is enabled, ensure that One Shot for MSI in PCI_CTRL
* is disabled.
*/
&bar0->pic_control);
&bar0->pic_control);
#endif
hldev->terminating = 0;
return XGE_HAL_OK;
}
/*
* __hal_device_reset - Reset device only.
* @hldev: HAL device handle.
*
* Reset the device, and subsequently restore
* the previously saved PCI configuration space.
*/
#define XGE_HAL_MAX_PCI_CONFIG_SPACE_REINIT 50
static xge_hal_status_e
{
#if defined(XGE_HAL_MSI_X)
/* Restore MSI-X vector table */
// 2 64bit words for each entry
for (i = 0; i < XGE_HAL_MAX_MSIX_MESSAGES * 2; i++) {
}
}
}
#endif
if (swap_done) {
} else {
#if defined(XGE_OS_HOST_LITTLE_ENDIAN) || defined(XGE_OS_PIO_LITTLE_ENDIAN)
/* swap it */
#endif
}
{
/* Poll for no more than 1 second */
for (i = 0; i < XGE_HAL_MAX_PCI_CONFIG_SPACE_REINIT; i++)
{
for (j = 0; j < pcisize; j++) {
}
break;
xge_os_mdelay(20);
}
}
{
return XGE_HAL_ERR_RESET_FAILED;
}
int cnt = 0;
xge_os_mdelay(1);
do {
break;
}
cnt++;
} while(cnt < 20);
}
#if defined(XGE_HAL_MSI_X)
/* Restore MSI-X vector table */
/*
94: MSIXTable 00000004 ( BIR:4 Offset:0x0 )
98: PBATable 00000404 ( BIR:4 Offset:0x400 )
*/
//xge_os_pci_read16(hldev->pdev, hldev->cfgh,
//xge_offsetof(xge_hal_pci_config_le_t, subsystem_id), &subid);
// 2 64bit words for each entry
for (i = 0; i < XGE_HAL_MAX_MSIX_MESSAGES * 2; i++) {
}
}
}
#endif
return XGE_HAL_ERR_RESET_FAILED;
}
hldev->hw_is_initialized = 0;
return XGE_HAL_OK;
}
/*
* __hal_device_poll - General private routine to poll the device.
* @hldev: HAL device handle.
*
* Returns: one of the xge_hal_status_e{} enumerated types.
* XGE_HAL_OK - for success.
* XGE_HAL_ERR_CRITICAL - when encounters critical error.
*/
static xge_hal_status_e
{
/* Handling SERR errors by forcing a H/W reset. */
&bar0->serr_source);
if (err_reg & XGE_HAL_SERR_SOURCE_ANY) {
return XGE_HAL_ERR_CRITICAL;
}
&bar0->misc_int_reg);
if (err_reg & XGE_HAL_MISC_INT_REG_DP_ERR_INT) {
return XGE_HAL_ERR_CRITICAL;
}
#endif
{
/* Handling link status change error Intr */
&bar0->mac_rmac_err_reg);
}
if (hldev->inject_serr != 0) {
hldev->inject_serr = 0;
return XGE_HAL_ERR_CRITICAL;
}
if (hldev->inject_ecc != 0) {
hldev->inject_ecc = 0;
return XGE_HAL_ERR_CRITICAL;
}
if (hldev->inject_bad_tcode != 0) {
if (hldev->inject_bad_tcode_for_chan_type ==
} else {
}
hldev->inject_bad_tcode = 0;
t_code);
else
t_code);
}
return XGE_HAL_OK;
}
/*
* __hal_verify_pcc_idle - Verify All Enbled PCC are IDLE or not
* @hldev: HAL device handle.
* @adp_status: Adapter Status value
* Usage: See xge_hal_device_enable{}.
*/
{
/*
* For Xena 1,2,3 we enable only 4 PCCs Due to
* SXE-008 (Transmit DMA arbitration issue)
*/
"PCC is not IDLE after adapter enabled!");
}
} else {
if ((adp_status & XGE_HAL_ADAPTER_STATUS_RMAC_PCC_IDLE) !=
"PCC is not IDLE after adapter enabled!");
}
}
return XGE_HAL_OK;
}
static void
{
int iwl_cnt, i;
#define _HIST_ADJ_TIMER 1
#define _STEP 2
static int bytes_avg_history[_HIST_SIZE] = {0};
static int d_avg_history[_HIST_SIZE] = {0};
static int history_idx = 0;
static int pstep = 1;
static int hist_adj_timer = 0;
/*
* tval - current value of this bimodal timer
*/
/*
* d - how many interrupts we were getting since last
* bimodal timer tick.
*/
/* advance bimodal interrupt counter */
/*
* iwl_cnt - how many interrupts we've got since last
* bimodal timer tick.
*/
/*
* we need to take hldev->config.isr_polling_cnt into account
* but for some reason this line causing GCC to produce wrong
* code on Solaris. As of now, if bimodal_interrupts is configured
* hldev->config.isr_polling_cnt is forced to be "0".
*
* iwl_cnt = iwl_cnt / (hldev->config.isr_polling_cnt + 1); */
/*
* iwl_avg - how many RXDs on avarage been processed since
* last bimodal timer tick. This indirectly includes
* CPU utilizations.
*/
/*
* len_avg - how many bytes on avarage been processed since
* last bimodal timer tick. i.e. avarage frame size.
*/
if (len_avg < 60)
len_avg = 60;
/* align on low boundary */
/* reset faster */
if (iwl_avg == 1) {
/* reset history */
for (i = 0; i < _HIST_SIZE; i++)
bytes_avg_history[i] = d_avg_history[i] = 0;
history_idx = 0;
pstep = 1;
hist_adj_timer = 0;
}
/* always try to ajust timer to the best throughput value */
d_avg_history[history_idx] = d;
history_idx++;
d_hist = bytes_hist = 0;
for (i = 0; i < _HIST_SIZE; i++) {
/* do not re-configure until history is gathered */
if (!bytes_avg_history[i]) {
goto _end;
}
bytes_hist += bytes_avg_history[i];
d_hist += d_avg_history[i];
}
bytes_hist /= _HIST_SIZE;
d_hist /= _HIST_SIZE;
// xge_os_printf("d %d iwl_avg %d len_avg %d:%d:%d tval %d avg %d hist %d pstep %d",
// d, iwl_avg, len_txavg, len_rxavg, len_avg, tval, d*bytes_avg,
// d_hist*bytes_hist, pstep);
/* make an adaptive step */
hist_adj_timer = 0;
}
if (pstep &&
}
/* enable TTI range A for better latencies */
hldev->bimodal_urange_a_en = 0;
_end:
/* reset workload statistics counters */
/* reconfigure TTI56 + ring_no with new timer value */
}
static void
{
/* urange_a adaptive coalescing */
ufc += 1;
for (i=0; i<XGE_HAL_MAX_RING_NUM; i++)
}
} else {
ufc -= 1;
for (i=0; i<XGE_HAL_MAX_RING_NUM; i++)
}
}
}
hldev->rxufca_lbolt++;
}
/*
* __hal_device_handle_mc - Handle MC interrupt reason
* @hldev: HAL device handle.
* @reason: interrupt reason
*/
{
&isrbar0->mc_int_status);
if (!(val64 & XGE_HAL_MC_INT_STATUS_MC_INT))
return XGE_HAL_OK;
&isrbar0->mc_err_reg);
if (val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_SG_ERR_L ||
}
if (val64 & XGE_HAL_MC_ERR_REG_ETQ_ECC_DB_ERR_L ||
}
if (val64 & XGE_HAL_MC_ERR_REG_SM_ERR) {
}
/* those two should result in device reset */
return XGE_HAL_ERR_CRITICAL;
}
return XGE_HAL_OK;
}
/*
* __hal_device_handle_pic - Handle non-traffic PIC interrupt reason
* @hldev: HAL device handle.
* @reason: interrupt reason
*/
{
if (reason & XGE_HAL_PIC_INT_FLSH) {
&isrbar0->flsh_int_reg);
/* FIXME: handle register */
}
if (reason & XGE_HAL_PIC_INT_MDIO) {
&isrbar0->mdio_int_reg);
/* FIXME: handle register */
}
if (reason & XGE_HAL_PIC_INT_IIC) {
&isrbar0->iic_int_reg);
/* FIXME: handle register */
}
if (reason & XGE_HAL_PIC_INT_MISC) {
* bits are set, clear both and check adapter status
*/
if ((val64 & XGE_HAL_MISC_INT_REG_LINK_UP_INT) &&
"both link up and link down detected "XGE_OS_LLXFMT,
(unsigned long long)val64);
&isrbar0->misc_int_reg);
}
else if (val64 & XGE_HAL_MISC_INT_REG_LINK_UP_INT) {
"link up call request, misc_int "XGE_OS_LLXFMT,
(unsigned long long)val64);
}
else if (val64 & XGE_HAL_MISC_INT_REG_LINK_DOWN_INT){
"link down request, misc_int "XGE_OS_LLXFMT,
(unsigned long long)val64);
}
} else
#endif
{
}
}
return XGE_HAL_OK;
}
/*
* __hal_device_handle_txpic - Handle TxPIC interrupt reason
* @hldev: HAL device handle.
* @reason: interrupt reason
*/
{
if ( val64 & (XGE_HAL_PIC_INT_FLSH |
XGE_HAL_PIC_INT_MISC) ) {
xge_os_wmb();
}
if (!(val64 & XGE_HAL_PIC_INT_TX))
return status;
&isrbar0->txpic_int_reg);
xge_os_wmb();
if (val64 & XGE_HAL_TXPIC_INT_SCHED_INTR) {
int i;
/*
* This feature implements adaptive receive interrupt
* coalecing. It is disabled by default. To enable it
* set hldev->config.rxufca_lo_lim to be not equal to
* hldev->config.rxufca_hi_lim.
*
* We are using HW timer for this feature, so
* use needs to configure hldev->config.rxufca_lbolt_period
* which is essentially a time slice of timer.
*
* For those who familiar with Linux, lbolt means jiffies
* of this timer. I.e. timer tick.
*/
for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
continue;
__hal_update_rxufca(hldev, i);
}
}
/*
* This feature implements adaptive TTI timer re-calculation
* based on host utilization, number of interrupt processed,
* number of RXD per tick and avarage length of packets per
* tick.
*/
for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
continue;
}
}
}
return XGE_HAL_OK;
}
/*
* __hal_device_handle_txdma - Handle TxDMA interrupt reason
* @hldev: HAL device handle.
* @reason: interrupt reason
*/
{
if (val64 & XGE_HAL_TXDMA_PFC_INT) {
&isrbar0->pfc_err_reg);
/* FIXME: handle register */
}
if (val64 & XGE_HAL_TXDMA_TDA_INT) {
&isrbar0->tda_err_reg);
/* FIXME: handle register */
}
if (val64 & XGE_HAL_TXDMA_PCC_INT) {
&isrbar0->pcc_err_reg);
/* FIXME: handle register */
}
if (val64 & XGE_HAL_TXDMA_TTI_INT) {
&isrbar0->tti_err_reg);
/* FIXME: handle register */
}
if (val64 & XGE_HAL_TXDMA_LSO_INT) {
&isrbar0->lso_err_reg);
/* FIXME: handle register */
}
if (val64 & XGE_HAL_TXDMA_TPA_INT) {
&isrbar0->tpa_err_reg);
/* FIXME: handle register */
}
if (val64 & XGE_HAL_TXDMA_SM_INT) {
&isrbar0->sm_err_reg);
/* FIXME: handle register */
}
return XGE_HAL_OK;
}
/*
* __hal_device_handle_txmac - Handle TxMAC interrupt reason
* @hldev: HAL device handle.
* @reason: interrupt reason
*/
{
if (!(val64 & XGE_HAL_MAC_INT_STATUS_TMAC_INT))
return XGE_HAL_OK;
/* FIXME: handle register */
return XGE_HAL_OK;
}
/*
* __hal_device_handle_txxgxs - Handle TxXGXS interrupt reason
* @hldev: HAL device handle.
* @reason: interrupt reason
*/
{
/* FIXME: handle register */
return XGE_HAL_OK;
}
/*
* __hal_device_handle_rxpic - Handle RxPIC interrupt reason
* @hldev: HAL device handle.
* @reason: interrupt reason
*/
{
/* FIXME: handle register */
return XGE_HAL_OK;
}
/*
* __hal_device_handle_rxdma - Handle RxDMA interrupt reason
* @hldev: HAL device handle.
* @reason: interrupt reason
*/
{
if (val64 & XGE_HAL_RXDMA_RC_INT) {
&isrbar0->rc_err_reg);
/* FIXME: handle register */
}
if (val64 & XGE_HAL_RXDMA_RPA_INT) {
&isrbar0->rpa_err_reg);
/* FIXME: handle register */
}
if (val64 & XGE_HAL_RXDMA_RDA_INT) {
&isrbar0->rda_err_reg);
/* FIXME: handle register */
}
if (val64 & XGE_HAL_RXDMA_RTI_INT) {
&isrbar0->rti_err_reg);
/* FIXME: handle register */
}
return XGE_HAL_OK;
}
/*
* __hal_device_handle_rxmac - Handle RxMAC interrupt reason
* @hldev: HAL device handle.
* @reason: interrupt reason
*/
{
if (!(val64 & XGE_HAL_MAC_INT_STATUS_RMAC_INT))
return XGE_HAL_OK;
/* FIXME: handle register */
return XGE_HAL_OK;
}
/*
* __hal_device_handle_rxxgxs - Handle RxXGXS interrupt reason
* @hldev: HAL device handle.
* @reason: interrupt reason
*/
{
/* FIXME: handle register */
return XGE_HAL_OK;
}
/**
* xge_hal_device_enable - Enable device.
* @hldev: HAL device handle.
*
* Returns: XGE_HAL_OK - success.
* XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT - Failed to restore the device
* to a "quiescent" state.
*
* See also: xge_hal_status_e{}.
*
* Usage: See ex_open{}.
*/
{
int i, j;
if (!hldev->hw_is_initialized) {
if (status != XGE_HAL_OK) {
return status;
}
}
/*
* Not needed in most cases, i.e.
* when device_disable() is followed by reset -
* the latter copies back PCI config space, along with
* the bus mastership - see __hal_device_reset().
* However, there are/may-in-future be other cases, and
* does not hurt.
*/
/*
* Configure the link stability period.
*/
&bar0->misc_control);
} else {
/*
* Use the link stability period 1 ms as default
*/
}
/*
* could have popped up just before Enabling the card.
*/
&bar0->misc_int_reg);
if (val64) {
}
/*
* Clearing any possible Link state change interrupts that
* could have popped up just before Enabling the card.
*/
&bar0->mac_rmac_err_reg);
if (val64) {
}
}
}
/* Enabling Laser. */
&bar0->adapter_control);
&bar0->adapter_control);
/* let link establish */
xge_os_mdelay(1);
/* set link down untill poll() routine will set it up (maybe) */
/* If link is UP (adpter is connected) then enable the adapter */
&bar0->adapter_status);
&bar0->adapter_control);
} else {
&bar0->adapter_control);
}
&bar0->adapter_control);
/* We spin here waiting for the Link to come up.
* This is the fix for the Link being unstable after the reset. */
i = 0;
j = 0;
do
{
&bar0->adapter_status);
/* Read the adapter control register for Adapter_enable bit */
&bar0->adapter_control);
(val64 & XGE_HAL_ADAPTER_CNTL_EN)) {
j++;
XGE_HAL_OK) {
adp_status) != XGE_HAL_OK) {
return
}
"adp_status: "XGE_OS_LLXFMT
", link is up on "
"adapter enable!",
(unsigned long long)adp_status);
&bar0->adapter_control);
&bar0->adapter_control);
xge_os_mdelay(1);
&bar0->adapter_control);
break; /* out of for loop */
} else {
return
}
}
} else {
j = 0; /* Reset the count */
/* Turn on the Laser */
&bar0->adapter_control);
xge_os_mdelay(1);
/* Now re-enable it as due to noise, hardware
* turned it off */
&bar0->adapter_control);
&bar0->adapter_control);
}
i++;
#ifndef XGE_HAL_PROCESS_LINK_INT_IN_ISR
/* Here we are performing soft reset on XGXS to force link down.
* Since link is already up, we will get link state change
* poll notificatoin after adapter is enabled */
&bar0->dtx_control);
&bar0->dtx_control);
&bar0->dtx_control);
#else
#endif
{
/*
* With some switches the link state change interrupt does not
* occur even though the xgxs reset is done as per SPN-006. So,
* poll the adapter status register and check if the link state
* is ok.
*/
&bar0->adapter_status);
{
"enable device causing link state change ind..");
}
}
return XGE_HAL_OK;
}
/**
* xge_hal_device_disable - Disable Xframe adapter.
* @hldev: Device handle.
*
* Disable this device. To gracefully reset the adapter, the host should:
*
* - call xge_hal_device_disable();
*
* - call xge_hal_device_intr_disable();
*
* - close all opened channels and clean up outstanding resources;
*
* - do some work (error recovery, change mtu, reset, etc);
*
* - call xge_hal_device_enable();
*
* - open channels, replenish RxDs, etc.
*
* - call xge_hal_device_intr_enable().
*
* Note: Disabling the device does _not_ include disabling of interrupts.
* After disabling the device stops receiving new frames but those frames
* that were already in the pipe will keep coming for some few milliseconds.
*
* Returns: XGE_HAL_OK - success.
* XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT - Failed to restore the device to
* a "quiescent" state.
*
* See also: xge_hal_status_e{}.
*/
{
&bar0->adapter_control);
&bar0->adapter_control);
}
}
#ifdef XGE_DEBUG_ASSERT
else
#endif
#endif
return status;
}
/**
* xge_hal_device_reset - Reset device.
* @hldev: HAL device handle.
*
* Soft-reset the device, reset the device stats except reset_cnt.
*
* After reset is done, will try to re-initialize HW.
*
* Returns: XGE_HAL_OK - success.
* XGE_HAL_ERR_DEVICE_NOT_INITIALIZED - Device is not initialized.
* XGE_HAL_ERR_RESET_FAILED - Reset failed.
*
* See also: xge_hal_status_e{}.
*/
{
/* increment the soft reset counter */
if (!hldev->is_initialized)
/* actual "soft" reset of the adapter */
/* reset all stats including saved */
/* increment reset counter */
/* re-initialize rxufca_intr_thres */
return status;
}
/**
* xge_hal_device_status - Check whether Xframe hardware is ready for
* operation.
* @hldev: HAL device handle.
* @hw_status: Xframe status register. Returned by HAL.
*
* Check whether Xframe hardware is ready for operation.
* The checking includes TDMA, RDMA, PFC, PIC, MC_DRAM, and the rest
* hardware functional blocks.
*
* Returns: XGE_HAL_OK if the device is ready for operation. Otherwise
* returns XGE_HAL_FAIL. Also, fills in adapter status (in @hw_status).
*
* See also: xge_hal_status_e{}.
* Usage: See ex_open{}.
*/
{
&bar0->adapter_status);
if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_TDMA_READY)) {
return XGE_HAL_FAIL;
}
if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_RDMA_READY)) {
return XGE_HAL_FAIL;
}
if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_PFC_READY)) {
return XGE_HAL_FAIL;
}
if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_TMAC_BUF_EMPTY)) {
return XGE_HAL_FAIL;
}
if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_PIC_QUIESCENT)) {
return XGE_HAL_FAIL;
}
if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_MC_DRAM_READY)) {
return XGE_HAL_FAIL;
}
if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_MC_QUEUES_READY)) {
return XGE_HAL_FAIL;
}
if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_M_PLL_LOCK)) {
return XGE_HAL_FAIL;
}
if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_P_PLL_LOCK)) {
return XGE_HAL_FAIL;
}
return XGE_HAL_OK;
}
/**
* xge_hal_device_intr_enable - Enable Xframe interrupts.
* @hldev: HAL device handle.
* @op: One of the xge_hal_device_intr_e enumerated values specifying
* the type(s) of interrupts to enable.
*
* Enable Xframe interrupts. The function is to be executed the last in
* Xframe initialization sequence.
*
* See also: xge_hal_device_intr_disable()
*/
void
{
/* PRC initialization and configuration */
}
/* enable traffic only interrupts */
/*
* make sure all interrupts going to be disabled if MSI
* is enabled.
*/
} else {
/*
* Enable the Tx traffic interrupts only if the TTI feature is
* enabled.
*/
val64 = 0;
if (hldev->tti_enabled)
}
}
/**
* xge_hal_device_intr_disable - Disable Xframe interrupts.
* @hldev: HAL device handle.
* @op: One of the xge_hal_device_intr_e enumerated values specifying
* the type(s) of interrupts to disable.
*
* Disable Xframe interrupts.
*
* See also: xge_hal_device_intr_enable()
*/
void
{
/*
* Disable traffic only interrupts.
* Tx traffic interrupts are used only if the TTI feature is
* enabled.
*/
val64 = 0;
if (hldev->tti_enabled)
XGE_HAL_SCHED_INTR : 0);
0xFFFFFFFFFFFFFFFFULL,
&bar0->general_int_mask);
/* disable all configured PRCs */
}
}
/**
* xge_hal_device_mcast_enable - Enable Xframe multicast addresses.
* @hldev: HAL device handle.
*
* Enable Xframe multicast addresses.
* Returns: XGE_HAL_OK on success.
* XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to enable mcast
* feature within the time(timeout).
*
* See also: xge_hal_device_mcast_disable(), xge_hal_status_e{}.
*/
{
return XGE_HAL_ERR_INVALID_DEVICE;
if (hldev->mcast_refcnt)
return XGE_HAL_OK;
/* Enable all Multicast addresses */
XGE_HAL_RMAC_ADDR_DATA0_MEM_ADDR(0x010203040506ULL),
XGE_HAL_RMAC_ADDR_DATA1_MEM_MASK(0xfeffffffffffULL),
&bar0->rmac_addr_cmd_mem, 0,
/* upper layer may require to repeat */
}
return XGE_HAL_OK;
}
/**
* xge_hal_device_mcast_disable - Disable Xframe multicast addresses.
* @hldev: HAL device handle.
*
* Disable Xframe multicast addresses.
* Returns: XGE_HAL_OK - success.
* XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to disable mcast
* feature within the time(timeout).
*
* See also: xge_hal_device_mcast_enable(), xge_hal_status_e{}.
*/
{
return XGE_HAL_ERR_INVALID_DEVICE;
if (hldev->mcast_refcnt == 0)
return XGE_HAL_OK;
hldev->mcast_refcnt = 0;
/* Disable all Multicast addresses */
XGE_HAL_RMAC_ADDR_DATA0_MEM_ADDR(0xffffffffffffULL),
&bar0->rmac_addr_cmd_mem, 0,
/* upper layer may require to repeat */
}
return XGE_HAL_OK;
}
/**
* xge_hal_device_promisc_enable - Enable promiscuous mode.
* @hldev: HAL device handle.
*
* Enable promiscuous mode of Xframe operation.
*
* See also: xge_hal_device_promisc_disable().
*/
void
{
if (!hldev->is_promisc) {
/* Put the NIC into promiscuous mode */
XGE_HAL_RMAC_CFG_KEY(0x4C0D),
&bar0->rmac_cfg_key);
(unsigned long long)val64);
}
}
/**
* xge_hal_device_promisc_disable - Disable promiscuous mode.
* @hldev: HAL device handle.
*
* Disable promiscuous mode of Xframe operation.
*
* See also: xge_hal_device_promisc_enable().
*/
void
{
if (hldev->is_promisc) {
/* Remove the NIC from promiscuous mode */
XGE_HAL_RMAC_CFG_KEY(0x4C0D),
&bar0->rmac_cfg_key);
hldev->is_promisc = 0;
(unsigned long long)val64);
}
}
/**
* xge_hal_device_macaddr_get - Get MAC addresses.
* @hldev: HAL device handle.
* @index: MAC address index, in the range from 0 to
* XGE_HAL_MAX_MAC_ADDRESSES.
* @macaddr: MAC address. Returned by HAL.
*
* Retrieve one of the stored MAC addresses by reading non-volatile
* memory on the chip.
*
* Up to %XGE_HAL_MAX_MAC_ADDRESSES addresses is supported.
*
* Returns: XGE_HAL_OK - success.
* XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to retrieve the mac
* address within the time(timeout).
* XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES - Invalid MAC address index.
*
* See also: xge_hal_device_macaddr_set(), xge_hal_status_e{}.
*/
{
int i;
return XGE_HAL_ERR_INVALID_DEVICE;
}
if ( index >= XGE_HAL_MAX_MAC_ADDRESSES ) {
return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
}
#ifdef XGE_HAL_HERC_EMULATION
/* poll until done */
&bar0->rmac_addr_cmd_mem, 0,
#endif
/* upper layer may require to repeat */
}
for (i=0; i < XGE_HAL_ETH_ALEN; i++) {
}
#ifdef XGE_HAL_HERC_EMULATION
for (i=0; i < XGE_HAL_ETH_ALEN; i++) {
}
#endif
return XGE_HAL_OK;
}
/**
* xge_hal_device_macaddr_set - Set MAC address.
* @hldev: HAL device handle.
* @index: MAC address index, in the range from 0 to
* XGE_HAL_MAX_MAC_ADDRESSES.
* @macaddr: New MAC address to configure.
*
* Configure one of the available MAC address "slots".
*
* Up to %XGE_HAL_MAX_MAC_ADDRESSES addresses is supported.
*
* Returns: XGE_HAL_OK - success.
* XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to set the new mac
* address within the time(timeout).
* XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES - Invalid MAC address index.
*
* See also: xge_hal_device_macaddr_get(), xge_hal_status_e{}.
*/
{
int i;
if ( index >= XGE_HAL_MAX_MAC_ADDRESSES )
return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
temp64 = 0;
for (i=0; i < XGE_HAL_ETH_ALEN; i++) {
temp64 <<= 8;
}
temp64 >>= 8;
/* upper layer may require to repeat */
}
return XGE_HAL_OK;
}
/**
* xge_hal_device_macaddr_find - Finds index in the rmac table.
* @hldev: HAL device handle.
* @wanted: Wanted MAC address.
*
* See also: xge_hal_device_macaddr_set().
*/
int
{
int i;
return XGE_HAL_ERR_INVALID_DEVICE;
}
for (i=1; i<XGE_HAL_MAX_MAC_ADDRESSES; i++) {
return i;
}
}
return -1;
}
/**
* xge_hal_device_mtu_set - Set MTU.
* @hldev: HAL device handle.
* @new_mtu: New MTU size to configure.
*
* Set new MTU value. Example, to use jumbo frames:
* xge_hal_device_mtu_set(my_device, my_channel, 9600);
*
* Returns: XGE_HAL_OK on success.
* XGE_HAL_ERR_SWAPPER_CTRL - Failed to configure swapper control
* register.
* schemes.
* XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT - Failed to restore the device to
* a "quiescent" state.
*/
{
/*
* reset needed if 1) new MTU differs, and
* 2a) device was closed or
* 2b) device is being upped for first time.
*/
if (hldev->reset_needed_after_close ||
!hldev->mtu_first_time_set) {
if (status != XGE_HAL_OK) {
"fatal: can not reset the device");
return status;
}
}
/* store the new MTU in device, reset will use it */
new_mtu);
}
if (!hldev->mtu_first_time_set)
return XGE_HAL_OK;
}
/**
* xge_hal_device_initialize - Initialize Xframe device.
* @hldev: HAL device handle.
* @attr: pointer to xge_hal_device_attr_t structure
* @device_config: Configuration to be _applied_ to the device,
* For the Xframe configuration "knobs" please
* refer to xge_hal_device_config_t and Xframe
* User Guide.
*
* Initialize Xframe device. Note that all the arguments of this public API
* are 'IN', including @hldev. Upper-layer driver (ULD) cooperates with
* OS to find new Xframe device, locate its PCI and memory spaces.
*
* When done, the ULD allocates sizeof(xge_hal_device_t) bytes for HAL
* to enable the latter to perform Xframe hardware initialization.
*
* Returns: XGE_HAL_OK - success.
* XGE_HAL_ERR_DRIVER_NOT_INITIALIZED - Driver is not initialized.
* XGE_HAL_ERR_BAD_DEVICE_CONFIG - Device configuration params are not
* valid.
* XGE_HAL_ERR_OUT_OF_MEMORY - Memory allocation failed.
* XGE_HAL_ERR_BAD_SUBSYSTEM_ID - Device subsystem id is invalid.
* XGE_HAL_ERR_INVALID_MAC_ADDRESS - Device mac address in not valid.
* XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to retrieve the mac
* XGE_HAL_ERR_SWAPPER_CTRL - Failed to configure swapper control.
* XGE_HAL_ERR_DEVICE_IS_NOT_QUIESCENT -Device is not queiscent.
*
* See also: xge_hal_device_terminate(), xge_hal_status_e{}
* xge_hal_device_attr_t{}.
*/
{
int i;
int total_dram_size_max = 0;
/* sanity check */
if (g_xge_hal_driver == NULL ||
}
/*
* (and run check_card() later, once PCI inited - see below)
*/
if (status != XGE_HAL_OK)
return status;
/* apply config */
sizeof(xge_hal_device_config_t));
/* save original attr */
sizeof(xge_hal_device_attr_t));
/* initialize rxufca_intr_thres */
/* set initial bimodal timer for bimodal adaptive schema */
return XGE_HAL_ERR_OUT_OF_MEMORY;
/*
* initlialize lists to properly handling a potential
* terminate request
*/
#ifdef XGEHAL_RNIC
#endif
/* fixups for xena */
if (status != XGE_HAL_OK) {
return status;
}
/* fixups for herc */
if (status != XGE_HAL_OK) {
return status;
}
} else {
return XGE_HAL_ERR_BAD_DEVICE_ID;
}
#ifdef XGEHAL_RNIC
XGE_HAL_BLOCKPOOL_SIZE) != XGE_HAL_OK) {
"block pool: __hal_blockpool_create failed");
return XGE_HAL_ERR_OUT_OF_MEMORY;
}
#endif
/* allocate and initialize FIFO types of channels according to
* configuration */
for (i = 0; i < XGE_HAL_MAX_FIFO_NUM; i++) {
continue;
"fifo: __hal_channel_allocate failed");
return XGE_HAL_ERR_OUT_OF_MEMORY;
}
/* add new channel to the device */
}
/*
* automatic DRAM adjustment
*/
total_dram_size = 0;
ring_auto_dram_cfg = 0;
for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
continue;
continue;
}
}
if (left_dram_size < 0 ||
"ring config: exceeded DRAM size %d MB",
return XGE_HAL_BADCFG_RING_QUEUE_SIZE;
}
/*
* allocate and initialize RING types of channels according to
* configuration
*/
for (i = 0; i < XGE_HAL_MAX_RING_NUM; i++) {
continue;
}
"ring: __hal_channel_allocate failed");
return XGE_HAL_ERR_OUT_OF_MEMORY;
}
/* add new channel to the device */
}
/* get subsystem IDs */
"subsystem_id %04x:%04x",
/* reset device initially */
(void) __hal_device_reset(hldev);
/* set host endian before, to assure proper action */
if (status != XGE_HAL_OK) {
"__hal_device_set_swapper failed");
(void) __hal_device_reset(hldev);
return status;
}
#ifndef XGE_HAL_HERC_EMULATION
#endif
/* MAC address initialization.
* For now only one mac address will be read and used. */
if (status != XGE_HAL_OK) {
"xge_hal_device_macaddr_get failed");
return status;
}
"xge_hal_device_macaddr_get returns all FFs");
return XGE_HAL_ERR_INVALID_MAC_ADDRESS;
}
"default macaddr: 0x%02x-%02x-%02x-%02x-%02x-%02x",
if (status != XGE_HAL_OK) {
"__hal_stats_initialize failed");
return status;
}
if (status != XGE_HAL_OK) {
"__hal_device_hw_initialize failed");
return status;
}
"__hal_device_hw_initialize failed");
return XGE_HAL_ERR_OUT_OF_MEMORY;
}
/* Xena-only: need to serialize fifo posts across all device fifos */
#if defined(XGE_HAL_TX_MULTI_POST)
#elif defined(XGE_HAL_TX_MULTI_POST_IRQ)
#endif
return XGE_HAL_OK;
}
/**
* xge_hal_device_terminating - Mark the device as 'terminating'.
* @devh: HAL device handle.
*
* Mark the device as 'terminating', going to terminate. Can be used
*
* See also: xge_hal_device_terminate().
*/
void
{
}
/**
* xge_hal_device_terminate - Terminate Xframe device.
* @hldev: HAL device handle.
*
* Terminate HAL device.
*
* See also: xge_hal_device_initialize().
*/
void
{
hldev->is_initialized = 0;
#if defined(XGE_HAL_TX_MULTI_POST)
#elif defined(XGE_HAL_TX_MULTI_POST_IRQ)
#endif
}
/* close if open and free all channels */
}
}
if (hldev->spdm_table) {
hldev->spdm_table[0],
(sizeof(xge_hal_spdm_entry_t) *
(sizeof(xge_hal_spdm_entry_t *) *
}
}
}
/**
* xge_hal_device_handle_tcode - Handle transfer code.
* @channelh: Channel handle.
* @dtrh: Descriptor handle.
* @t_code: One of the enumerated (and documented in the Xframe user guide)
* "transfer codes".
*
* Handle descriptor's transfer code. The latter comes with each completed
* descriptor, see xge_hal_fifo_dtr_next_completed() and
* xge_hal_ring_dtr_next_completed().
* Transfer codes are enumerated in xgehal-fifo.h and xgehal-ring.h.
*
* Returns: one of the xge_hal_status_e{} enumerated types.
* XGE_HAL_OK - for success.
* XGE_HAL_ERR_CRITICAL - when encounters critical error.
*/
{
if (t_code > 15) {
return XGE_HAL_OK;
}
#if defined(XGE_HAL_DEBUG_BAD_TCODE)
txdp->host_control);
#endif
/* handle link "down" immediately without going through
* xge_hal_device_poll() routine. */
if (t_code == XGE_HAL_TXD_T_CODE_LOSS_OF_LINK) {
/* link is down */
/* turn off LED */
&bar0->adapter_control);
}
} else if (t_code == XGE_HAL_TXD_T_CODE_ABORT_BUFFER ||
return XGE_HAL_ERR_CRITICAL;
}
#if defined(XGE_HAL_DEBUG_BAD_TCODE)
rxdp->host_control);
#endif
if (t_code == XGE_HAL_RXD_T_CODE_BAD_ECC) {
return XGE_HAL_ERR_CRITICAL;
} else if (t_code == XGE_HAL_RXD_T_CODE_PARITY ||
return XGE_HAL_ERR_CRITICAL;
}
}
return XGE_HAL_OK;
}
/**
* xge_hal_device_link_state - Get link state.
* @devh: HAL device handle.
* @ls: Link state, see xge_hal_device_link_state_e{}.
*
* Get link state.
* Returns: XGE_HAL_OK.
* See also: xge_hal_device_link_state_e{}.
*/
{
return XGE_HAL_OK;
}
/**
* xge_hal_device_sched_timer - Configure scheduled device interrupt.
* @devh: HAL device handle.
* @interval_us: Time interval, in miscoseconds.
* Unlike transmit and receive interrupts,
* the scheduled interrupt is generated independently of
* traffic, but purely based on time.
* @one_shot: 1 - generate scheduled interrupt only once.
* 0 - generate scheduled interrupt periodically at the specified
* @interval_us interval.
*
* (Re-)configure scheduled interrupt. Can be called at runtime to change
* traffic conditions, other purposes.
* See also: xge_hal_device_config_t{}.
*/
int one_shot)
{
if (interval) {
if (one_shot) {
}
} else {
}
(unsigned long long)val64,
}
/**
* xge_hal_device_check_id - Verify device ID.
* @devh: HAL device handle.
*
* Verify device ID.
* Returns: one of the xge_hal_card_e{} enumerated types.
* See also: xge_hal_card_e{}.
*/
{
case XGE_PCI_DEVICE_ID_XENA_1:
case XGE_PCI_DEVICE_ID_XENA_2:
return XGE_HAL_CARD_XENA;
case XGE_PCI_DEVICE_ID_HERC_1:
case XGE_PCI_DEVICE_ID_HERC_2:
return XGE_HAL_CARD_HERC;
default:
return XGE_HAL_CARD_UNKNOWN;
}
}
/**
* xge_hal_device_pci_info_get - Get PCI bus informations such as width,
* frequency, and mode from previously stored values.
* @devh: HAL device handle.
* @pci_mode: pointer to a variable of enumerated type
* xge_hal_pci_mode_e{}.
* @bus_frequency: pointer to a variable of enumerated type
* xge_hal_pci_bus_frequency_e{}.
* @bus_width: pointer to a variable of enumerated type
* xge_hal_pci_bus_width_e{}.
*
* Get pci mode, frequency, and PCI bus width.
* Returns: one of the xge_hal_status_e{} enumerated types.
* XGE_HAL_OK - for success.
* XGE_HAL_ERR_INVALID_DEVICE - for invalid device handle.
* See Also: xge_hal_pci_mode_e, xge_hal_pci_mode_e, xge_hal_pci_width_e.
*/
{
"xge_hal_device_pci_info_get error, rc %d for device %p",
return rc_status;
}
return rc_status;
}
/**
* xge_hal_reinitialize_hw
* @hldev: private member of the device structure.
*
* This function will soft reset the NIC and re-initalize all the
* I/O registers to the values they had after it's inital initialization
* through the probe function.
*/
{
(void) xge_hal_device_reset(hldev);
(void) __hal_device_reset(hldev);
return 1;
}
return 0;
}
/*
* __hal_read_spdm_entry_line
* @hldev: pointer to xge_hal_device_t structure
* @spdm_line: spdm line in the spdm entry to be read.
* @spdm_entry: spdm entry of the spdm_line in the SPDM table.
* @spdm_line_val: Contains the value stored in the spdm line.
*
* SPDM table contains upto a maximum of 256 spdm entries.
* Each spdm entry contains 8 lines and each line stores 8 bytes.
* This function reads the spdm line(addressed by @spdm_line)
* of the spdm entry(addressed by @spdm_entry) in
* the SPDM table.
*/
{
/* poll until done */
&bar0->rts_rth_spdm_mem_ctrl, 0,
}
return XGE_HAL_OK;
}
/*
* __hal_get_free_spdm_entry
* @hldev: pointer to xge_hal_device_t structure
* @spdm_entry: Contains an index to the unused spdm entry in the SPDM table.
*
* This function returns an index of unused spdm entry in the SPDM
* table.
*/
static xge_hal_status_e
{
u64 spdm_line_val=0;
/*
* Search in the local SPDM table for a free slot.
*/
*spdm_entry = 0;
break;
}
}
return XGE_HAL_ERR_SPDM_TABLE_FULL;
}
/*
* Make sure that the corresponding spdm entry in the SPDM
* table is free.
* Seventh line of the spdm entry contains information about
* whether the entry is free or not.
*/
&spdm_line_val)) != XGE_HAL_OK) {
return status;
}
/* BIT(63) in spdm_line 7 corresponds to entry_enable bit */
/*
* Log a warning
*/
"consistent with the actual one for the spdm "
"entry %d\n", *spdm_entry);
}
return XGE_HAL_OK;
}
/**
* xge_hal_spdm_entry_add - Add a new entry to the SPDM table.
* @devh: HAL device handle.
* @l4_sp: L4 source port.
* @l4_dp: L4 destination port.
* @is_tcp: Set to 1, if the protocol is TCP.
* 0, if the protocol is UDP.
* @is_ipv4: Set to 1, if the protocol is IPv4.
* 0, if the protocol is IPv6.
* @tgt_queue: Target queue to route the receive packet.
*
* This function add a new entry to the SPDM table.
*
* Returns: XGE_HAL_OK - success.
* XGE_HAL_ERR_SPDM_NOT_ENABLED - SPDM support is not enabled.
* XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to add a new entry with in
* the time(timeout).
* XGE_HAL_ERR_SPDM_TABLE_FULL - SPDM table is full.
* XGE_HAL_ERR_SPDM_INVALID_ENTRY - Invalid SPDM entry.
*
* See also: xge_hal_spdm_entry_remove{}.
*/
{
int off;
int ipaddr_len;
return XGE_HAL_ERR_SPDM_NOT_ENABLED;
}
if ((tgt_queue < XGE_HAL_MIN_RING_NUM) ||
(tgt_queue > XGE_HAL_MAX_RING_NUM)) {
return XGE_HAL_ERR_SPDM_INVALID_ENTRY;
}
/*
* Calculate the jenkins hash.
*/
/*
* Create the Jenkins hash algorithm key.
* key = {L3SA, L3DA, L4SP, L4DP}, if SPDM is configured to
* use L4 information. Otherwize key = {L3SA, L3DA}.
*/
if (is_ipv4) {
} else {
ipaddr_len = 16;
}
/*
* Jenkins hash algorithm expects the key in the big endian
* format. Since key is the byte array, memcpy won't work in the
* case of little endian. So, the current code extracts each
* byte starting from MSB and store it in the key.
*/
if (is_ipv4) {
}
} else {
>> shift);
}
}
off += 4;
}
/*
* Calculate jenkins hash for this configuration
*/
/*
* Locate a free slot in the SPDM table. To avoid a seach in the
* actual SPDM table, which is very expensive in terms of time,
* we are maintaining a local copy of the table and the search for
* the free entry is performed in the local table.
*/
!= XGE_HAL_OK) {
return status;
}
/*
* Add this entry to the SPDM table
*/
jhash_value, /* calculated jhash */
return status;
}
/**
* xge_hal_spdm_entry_remove - Remove an entry from the SPDM table.
* @devh: HAL device handle.
* @l4_sp: L4 source port.
* @l4_dp: L4 destination port.
* @is_tcp: Set to 1, if the protocol is TCP.
* 0, if the protocol os UDP.
* @is_ipv4: Set to 1, if the protocol is IPv4.
* 0, if the protocol is IPv6.
*
* This function remove an entry from the SPDM table.
*
* Returns: XGE_HAL_OK - success.
* XGE_HAL_ERR_SPDM_NOT_ENABLED - SPDM support is not enabled.
* XGE_HAL_INF_MEM_STROBE_CMD_EXECUTING - Failed to remove an entry with in
* the time(timeout).
* XGE_HAL_ERR_SPDM_ENTRY_NOT_FOUND - Unable to locate the entry in the SPDM
* table.
*
* See also: xge_hal_spdm_entry_add{}.
*/
{
return XGE_HAL_ERR_SPDM_NOT_ENABLED;
}
/*
* Poll the rxpic_int_reg register until spdm ready bit is set or
* timeout happens.
*/
/* upper layer may require to repeat */
}
/*
* Clear the SPDM READY bit.
*/
&bar0->rxpic_int_reg);
&bar0->rxpic_int_reg);
/*
* Search in the local SPDM table to get the index of the
* corresponding entry in the SPDM table.
*/
spdm_entry = 0;
continue;
}
/*
*/
if (is_ipv4) {
continue;
}
} else {
continue;
}
}
break;
}
return XGE_HAL_ERR_SPDM_ENTRY_NOT_FOUND;
}
/*
* Retrieve the corresponding entry from the SPDM table and
* make sure that the data is consistent.
*/
/*
* SPDM line 2,3,4 are valid only for IPv6 entry.
* SPDM line 5 & 6 are reserved. We don't have to
* read these entries in the above cases.
*/
if (((is_ipv4) &&
(line_no == 5) ||
(line_no == 6)) {
continue;
}
if ((status = __hal_read_spdm_entry_line(
&spdm_line_arr[line_no]))
!= XGE_HAL_OK) {
return status;
}
}
/*
* Seventh line of the spdm entry contains the entry_enable
* bit. Make sure that the entry_enable bit of this spdm entry
* is set.
* To remove an entry from the SPDM table, reset this
* bit.
*/
/*
* Log a warning
*/
"consistent with the actual one for the spdm "
"entry %d \n", spdm_entry);
goto err_exit;
}
/*
* table and do a comparision.
*/
if ((spdm_is_tcp != is_tcp) ||
(spdm_is_ipv4 != is_ipv4) ||
(spdm_l4_sp != l4_sp) ||
(spdm_l4_dp != l4_dp)) {
/*
* Log a warning
*/
"consistent with the actual one for the spdm "
"entry %d \n", spdm_entry);
goto err_exit;
}
if (is_ipv4) {
/* Upper 32 bits of spdm_line(64 bit) contains the
* src IPv4 address. Lower 32 bits of spdm_line
* contains the destination IPv4 address.
*/
"consistent with the actual one for the spdm "
"entry %d \n", spdm_entry);
goto err_exit;
}
} else {
/*
* SPDM line 1 & 2 contains the src IPv6 address.
* SPDM line 3 & 4 contains the dst IPv6 address.
*/
/*
* Log a warning
*/
"consistent with the actual one for the spdm "
"entry %d \n", spdm_entry);
goto err_exit;
}
}
/*
* Reset the entry_enable bit to zero
*/
spdm_line_arr[7],
(void *)((char *)hldev->spdm_mem_base +
/*
* Wait for the operation to be completed.
*/
}
/*
* Make the corresponding spdm entry in the local SPDM table
* available for future use.
*/
return XGE_HAL_OK;
}
/*
* __hal_calc_jhash - Calculate Jenkins hash.
* @msg: Jenkins hash algorithm key.
* @length: Length of the key.
* @golden_ratio: Jenkins hash golden ratio.
* @init_value: Jenkins hash initial value.
*
* This function implements the Jenkins based algorithm used for the
* calculation of the RTH hash.
* Returns: Jenkins hash value.
*
*/
{
/*
* Set up the internal state
*/
a = b = golden_ratio; /* the golden ratio; an arbitrary value */
c = init_value; /* the previous hash value */
/* handle most of the key */
while (len >= 12)
{
mix(a,b,c);
}
/* handle the last 11 bytes */
c += length;
switch(len) /* all the case statements fall through */
{
break;
break;
break;
/* the first byte of c is reserved for the length */
break;
break;
break;
break;
break;
break;
break;
case 1 : a+= msg[0];
break;
/* case 0: nothing left to add */
}
mix(a,b,c);
/* report the result */
return c;
}
#if defined(XGE_HAL_MSI) | defined(XGE_HAL_MSI_X)
/*
* __hal_device_rti_set
* @ring: The post_qid of the ring.
* @channel: HAL channel of the ring.
*
* This function stores the RTI value associated for the MSI and
* also unmasks this particular RTI in the rti_mask register.
*/
{
#if defined(XGE_HAL_MSI)
#endif
&bar0->rx_traffic_mask);
&bar0->rx_traffic_mask);
}
/*
* __hal_device_tti_set
* @ring: The post_qid of the FIFO.
* @channel: HAL channel the FIFO.
*
* This function stores the TTI value associated for the MSI and
* also unmasks this particular TTI in the tti_mask register.
*/
{
#if defined(XGE_HAL_MSI)
#endif
&bar0->tx_traffic_mask);
&bar0->tx_traffic_mask);
}
#endif
#if defined(XGE_HAL_MSI)
/**
* xge_hal_channel_msi_set - Associate a RTI with a ring or TTI with a
* FIFO for a given MSI.
* @channelh: HAL channel handle.
* @msi: MSI Number associated with the channel.
* @msi_msg: The MSI message associated with the MSI number above.
*
* This API will associate a given channel (either Ring or FIFO) with the
* hardware to indicate this association to the hardware.
*/
{
} else {
}
return XGE_HAL_OK;
}
#endif
#if defined(XGE_HAL_MSI_X)
/*
* __hal_set_xmsi_vals
* @devh: HAL device handle.
* @msix_value: 32bit MSI-X value transferred across PCI to @msix_address.
* Filled in by this function.
* @msix_address: 32bit MSI-X DMA address.
* Filled in by this function.
* @msix_idx: index that corresponds to the (@msix_value, @msix_address)
* entry in the table of MSI-X (value, address) pairs.
*
* This function will program the hardware associating the given
*/
int msix_idx)
{
int cnt = 0;
do {
&bar0->xmsi_access);
if (val64 & XGE_HAL_XMSI_STROBE)
break;
cnt++;
xge_os_mdelay(20);
} while(cnt < 5);
&bar0->xmsi_address);
}
/**
* xge_hal_channel_msix_set - Associate MSI-X with a channel.
* @channelh: HAL channel handle.
* @msix_idx: index that corresponds to a particular (@msix_value,
* @msix_address) entry in the MSI-X table.
*
* This API associates a given channel (either Ring or FIFO) with the
* to indicate this association.
*/
{
/* Currently Ring and RTI is one on one. */
}
/*
* To enable MSI-X, MSI also needs to be enabled, due to a bug
* in the herc NIC. (Temp change, needs to be removed later)
*/
/* Enable the MSI-X interrupt */
{
&bar0->xmsi_mask_reg);
&bar0->xmsi_mask_reg);
}
return XGE_HAL_OK;
}
#endif
#if defined(XGE_HAL_CONFIG_LRO)
/**
* xge_hal_lro_terminate - Terminate lro resources.
* @lro_scale: Amount of lro memory.
* @hldev: Hal device structure.
*
*/
void
{
}
/**
* xge_hal_lro_init - Initiate lro resources.
* @lro_scale: Amount of lro memory.
* @hldev: Hal device structure.
* Note: For time being I am using only one LRO per device. Later on size
* will be increased.
*/
{
sizeof(lro_t) * XGE_HAL_LRO_MAX_BUCKETS);
hldev->lro_next_idx = 0;
return XGE_HAL_OK;
}
#endif
/**
* xge_hal_device_poll - HAL device "polling" entry point.
* @devh: HAL device.
*
* HAL "polling" entry point. Note that this is part of HAL public API.
* Upper-Layer driver _must_ periodically poll HAL via
* xge_hal_device_poll().
*
* HAL uses caller's execution context to serially process accumulated
* slow-path events, such as link state changes and hardware error
* indications.
*
* The rate of polling could be somewhere between 500us to 10ms,
* depending on requirements (e.g., the requirement to support fail-over
* could mean that 500us or even 100us polling interval need to be used).
*
* The need and motivation for external polling includes
*
* - remove the error-checking "burden" from the HAL interrupt handler
* (see xge_hal_device_handle_irq());
*
* - remove the potential source of portability issues by _not_
* implementing separate polling thread within HAL itself.
*
* See also: xge_hal_event_e{}, xge_hal_driver_config_t{}.
* Usage: See ex_slow_path{}.
*/
void
{
unsigned char item_buf[sizeof(xge_queue_item_t) +
int i = 0;
int queue_has_critical_event = 0;
if (!hldev->is_initialized ||
hldev->terminating ||
return;
{
/*
* Wait for an Hour
*/
} else {
/*
* Logging Error messages in the excess temperature,
* Bias current, laser ouput for three cycle
*/
}
if (!queue_has_critical_event)
while (i++ < XGE_HAL_DRIVER_QUEUE_CONSUME_MAX || queue_has_critical_event) {
item);
if (qstatus == XGE_QUEUE_IS_EMPTY)
break;
if (!hldev->is_initialized ||
return;
}
switch (item->event_type) {
case XGE_HAL_EVENT_LINK_IS_UP: {
if (!queue_has_critical_event &&
}
} break;
case XGE_HAL_EVENT_LINK_IS_DOWN: {
if (!queue_has_critical_event &&
}
} break;
case XGE_HAL_EVENT_SERR:
case XGE_HAL_EVENT_ECCERR:
case XGE_HAL_EVENT_PARITYERR:
case XGE_HAL_EVENT_SLOT_FREEZE: {
if (event_type != XGE_HAL_EVENT_SLOT_FREEZE)
val64);
/* handle one critical event per poll cycle */
return;
}
} break;
default: {
"got non-HAL event %d",
item->event_type);
} break;
}
/* broadcast this event */
}
hldev) != 0) {
return;
}
}
/*
* handle critical error right away:
* - walk the device queue again
* - drop non-critical events, if any
* - look for the 1st critical
*/
if (hstatus == XGE_HAL_ERR_CRITICAL) {
goto _again;
}
}
/**
* xge_hal_rts_rth_init - Set enhanced mode for RTS hashing.
* @hldev: HAL device handle.
*
* This function is used to set the adapter to enhanced mode.
*
* See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_set().
*/
void
{
/*
* Set the receive traffic steering mode from default(classic)
* to enhanced.
*/
}
/**
* xge_hal_rts_rth_clr - Clear RTS hashing.
* @hldev: HAL device handle.
*
* This function is used to clear all RTS hashing related stuff.
* It brings the adapter out from enhanced mode to classic mode.
* It also clears RTS_RTH_CFG register i.e clears hash type, function etc.
*
* See also: xge_hal_rts_rth_set(), xge_hal_rts_rth_itable_set().
*/
void
{
/*
* Set the receive traffic steering mode from default(classic)
* to enhanced.
*/
val64 = 0;
&bar0->rts_rth_cfg);
}
/**
* @hldev: HAL device handle.
* @def_q: default queue
* @hash_type: hash type i.e TcpIpV4, TcpIpV6 etc.
* @bucket_size: no of least significant bits to be used for hashing.
*
* - set the steering mode to enhanced.
* - set hash function i.e algo selection.
* - set the default queue.
*
* See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_itable_set().
*/
void
{
&bar0->rts_default_q);
&bar0->rts_rth_cfg);
}
/**
* xge_hal_rts_rth_start - Start RTS hashing.
* @hldev: HAL device handle.
*
* Used to Start RTS hashing .
*
* See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_itable_set(), xge_hal_rts_rth_start.
*/
void
{
&bar0->rts_rth_cfg);
&bar0->rts_rth_cfg);
}
/**
* xge_hal_rts_rth_stop - Stop the RTS hashing.
* @hldev: HAL device handle.
*
* Used to Staop RTS hashing .
*
* See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_itable_set(), xge_hal_rts_rth_start.
*/
void
{
&bar0->rts_rth_cfg);
val64 &= ~XGE_HAL_RTS_RTH_EN;
&bar0->rts_rth_cfg);
}
/**
* @hldev: HAL device handle.
* @itable: Pointer to the indirection table
* @itable_size: no of least significant bits to be used for hashing
*
* It enables the required no of entries in the IT.
* It adds entries to the IT.
*
* See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_set().
*/
{
/* execute */
/* poll until done */
&bar0->rts_rth_map_mem_ctrl, 0,
/* upper layer may require to repeat */
}
}
return XGE_HAL_OK;
}
/**
* xge_hal_device_rts_rth_key_set - Configure 40byte secret for hash calc.
*
* @hldev: HAL device handle.
* @KeySize: Number of 64-bit words
* @Key: upto 40-byte array of 8-bit values
* This function configures the 40-byte secret which is used for hash
* calculation.
*
* See also: xge_hal_rts_rth_clr(), xge_hal_rts_rth_set().
*/
void
{
entry = 0;
nreg = 0;
while( KeySize ) {
val64 = 0;
for ( i = 0; i < 8 ; i++) {
/* Prepare 64-bit word for 'nreg' containing 8 keys. */
if (i)
val64 <<= 8;
}
KeySize--;
/* temp64 = XGE_HAL_RTH_HASH_MASK_n(val64, (n<<3), (n<<3)+7);*/
}
while( nreg < 5 ) {
/* Clear the rest if key is less than 40 bytes */
val64 = 0;
}
}
/**
* xge_hal_device_is_closed - Device is closed
*
* @devh: HAL device handle.
*/
int
{
return 1;
return 0;
}
{
int section;
return XGE_HAL_ERR_OUT_OF_MAC_ADDRESSES;
/*
* Calculate the section value
*/
&bar0->rts_mac_cfg);
switch(section)
{
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
default:
, section);
}
return XGE_HAL_OK;
}
#ifdef XGEHAL_RNIC
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8 };
{
u32 i;
return XGE_HAL_FAIL;
{
if(fb < 8){
objdb->id_next_byte = i;
return XGE_HAL_OK;
}
}
objdb->id_inst_number++;
for( i = 0; i < objdb->id_next_byte; i++ )
{
if(fb < 8){
objdb->id_next_byte = i;
return XGE_HAL_OK;
}
}
return XGE_HAL_FAIL;
}
{
u32 i;
return XGE_HAL_FAIL;
return XGE_HAL_OK;
}
#endif