xgehal-device.c revision da14cebe459d3275048785f25bd869cb09b5307f
/*
* 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.
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#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); \
}
/*
* __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) {
/* Enable all TxDMA interrupts */
} 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,
};
void
{
xge_os_wmb();
xge_os_wmb();
xge_os_mdelay(1);
}
{
reg);
xge_os_mdelay(1);
return val64;
}
/*
* __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 {
return;
}
do {
dtx_cnt++;
goto mdio_cfg;
}
&bar0->dtx_control);
dtx_cnt++;
}
mdio_cnt++;
goto dtx_cfg;
}
&bar0->mdio_control);
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_port_configure - Configure RTS steering based on
* destination or source port number.
* @hldev: HAL device handle.
*
*/
{
int rnum;
return XGE_HAL_OK;
}
/*
* Set the receive traffic steering mode from default(classic)
* to enhanced.
*/
/*
* Initiate port steering according to per-ring configuration
*/
int pnum;
continue;
/*
* Skip and clear empty ports
*/
/*
* Clear CAM memory
*/
&bar0->rts_pn_cam_data);
} else {
/*
* Assign new Port values according
* to configuration
*/
&bar0->rts_pn_cam_data);
}
/* poll until done */
&bar0->rts_pn_cam_ctrl, 0,
XGE_HAL_OK) {
/* upper layer may require to repeat */
}
}
}
return XGE_HAL_OK;
}
/*
* __hal_device_rts_qos_configure - Configure RTS steering based on
* qos.
* @hldev: HAL device handle.
*
*/
{
int j, rx_ring_num;
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 */
}
}
rx_ring_num = 0;
for (j = 0; j < XGE_HAL_MAX_RING_NUM; j++) {
rx_ring_num++;
}
switch (rx_ring_num) {
case 1:
val64 = 0x0;
break;
case 2:
val64 = 0x0001000100010001ULL;
val64 = 0x0001000100000000ULL;
break;
case 3:
val64 = 0x0001020001020001ULL;
val64 = 0x0200010200010200ULL;
val64 = 0x0102000102000102ULL;
val64 = 0x0001020001020001ULL;
val64 = 0x0200010200000000ULL;
break;
case 4:
val64 = 0x0001020300010203ULL;
val64 = 0x0001020300000000ULL;
break;
case 5:
val64 = 0x0001020304000102ULL;
val64 = 0x0304000102030400ULL;
val64 = 0x0102030400010203ULL;
val64 = 0x0400010203040001ULL;
val64 = 0x0203040000000000ULL;
break;
case 6:
val64 = 0x0001020304050001ULL;
val64 = 0x0203040500010203ULL;
val64 = 0x0405000102030405ULL;
val64 = 0x0001020304050001ULL;
val64 = 0x0203040500000000ULL;
break;
case 7:
val64 = 0x0001020304050600ULL;
val64 = 0x0102030405060001ULL;
val64 = 0x0203040506000102ULL;
val64 = 0x0304050600010203ULL;
val64 = 0x0405060000000000ULL;
break;
case 8:
val64 = 0x0001020304050607ULL;
val64 = 0x0001020300000000ULL;
break;
}
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 ",
/*
* 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;
/* Store PCI device ID and revision for future references where in we
* decide Xena revision using PCI sub system ID */
/* save original PCI config space to restore it on device_terminate() */
for (i = 0; i < pcisize; i++) {
}
/* 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;
/* save PCI config space for future resets */
for (i = 0; i < pcisize; i++) {
}
}
/*
* __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 if (card_id == XGE_HAL_CARD_TITAN) {
}
} 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 */
/* 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 */
/* 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);
}
/* Optimizing for PCI-X 266/250 */
&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);
&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;
}
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 MSI is enabled, ensure that One Shot for MSI in PCI_CTRL
* is disabled.
*/
&bar0->pic_control);
&bar0->pic_control);
}
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
{
// 2 64bit words for each entry
for (i = 0; i < XGE_HAL_MAX_MSIX_MESSAGES * 2;
i++) {
hldev->msix_vector_table[i] =
}
}
}
}
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);
}
/* Restore MSI-X vector table */
/*
* 94: MSIXTable 00000004 ( BIR:4 Offset:0x0 )
* 98: PBATable 00000404 ( BIR:4 Offset:0x400 )
*/
/* 2 64bit words for each entry */
for (i = 0; i < XGE_HAL_MAX_MSIX_MESSAGES * 2;
i++) {
hldev->msix_vector_table[i],
&msix_vetor_table[i]);
}
}
}
}
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);
goto reset;
}
if (val64 & XGE_HAL_TXDMA_TDA_INT) {
&isrbar0->tda_err_reg);
goto reset;
}
if (val64 & XGE_HAL_TXDMA_PCC_INT) {
&isrbar0->pcc_err_reg);
goto reset;
}
if (val64 & XGE_HAL_TXDMA_TTI_INT) {
&isrbar0->tti_err_reg);
goto reset;
}
if (val64 & XGE_HAL_TXDMA_LSO_INT) {
&isrbar0->lso_err_reg);
goto reset;
}
if (val64 & XGE_HAL_TXDMA_TPA_INT) {
&isrbar0->tpa_err_reg);
goto reset;
}
if (val64 & XGE_HAL_TXDMA_SM_INT) {
&isrbar0->sm_err_reg);
goto reset;
}
return XGE_HAL_OK;
(void) xge_hal_device_enable(hldev);
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;
(void) xge_hal_device_reset(hldev);
(void) xge_hal_device_enable(hldev);
}
return XGE_HAL_OK;
}
/*
* __hal_device_handle_txxgxs - Handle TxXGXS interrupt reason
* @hldev: HAL device handle.
* @reason: interrupt reason
*/
{
if (!(val64 & XGE_HAL_XGXS_INT_STATUS_TXGXS))
return XGE_HAL_OK;
(void) xge_hal_device_reset(hldev);
(void) xge_hal_device_enable(hldev);
}
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);
goto reset;
}
if (val64 & XGE_HAL_RXDMA_RPA_INT) {
&isrbar0->rpa_err_reg);
goto reset;
}
if (val64 & XGE_HAL_RXDMA_RDA_INT) {
&isrbar0->rda_err_reg);
goto reset;
}
if (val64 & XGE_HAL_RXDMA_RTI_INT) {
&isrbar0->rti_err_reg);
goto reset;
}
return XGE_HAL_OK;
(void) xge_hal_device_enable(hldev);
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;
(void) xge_hal_device_reset(hldev);
(void) xge_hal_device_enable(hldev);
}
return XGE_HAL_OK;
}
/*
* __hal_device_handle_rxxgxs - Handle RxXGXS interrupt reason
* @hldev: HAL device handle.
* @reason: interrupt reason
*/
{
if (!(val64 & XGE_HAL_XGXS_INT_STATUS_RXGXS))
return XGE_HAL_OK;
(void) xge_hal_device_reset(hldev);
(void) xge_hal_device_enable(hldev);
}
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;
}
#ifndef XGE_HAL_HERC_EMULATION
/*
* Andrew: in PCI 33 mode, the P_PLL is not used, and therefore,
* the the P_PLL_LOCK bit in the adapter_status register will
* not be asserted.
*/
if (!(tmp64 & XGE_HAL_ADAPTER_STATUS_P_PLL_LOCK) &&
return XGE_HAL_FAIL;
}
#endif
return XGE_HAL_OK;
}
void
{
if (flag)
msi_control_reg |= 0x1;
else
msi_control_reg &= ~0x1;
}
void
{
&bar0->xmsi_mask_reg);
if (flag)
else
&bar0->xmsi_mask_reg);
}
/**
* 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
#endif
} else {
/*
* Enable the Tx traffic interrupts only if the TTI feature is
* enabled.
*/
val64 = 0;
if (hldev->tti_enabled)
}
/*
* Enable MSI-X interrupts
*/
/*
* To enable MSI-X, MSI also needs to be enabled,
* due to a bug in the herc NIC.
*/
}
/* Enable the MSI-X interrupt for each configured channel */
/* 0 vector is reserved for alarms */
continue;
}
/* 0 vector is reserved for alarms */
continue;
}
}
}
/**
* 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
{
/*
* To disable MSI-X, MSI also needs to be disabled,
* due to a bug in the herc NIC.
*/
}
/* Disable the MSI-X interrupt for each configured channel */
/* 0 vector is reserved for alarms */
continue;
}
&bar0->tx_traffic_mask);
/* 0 vector is reserved for alarms */
continue;
}
&bar0->rx_traffic_mask);
}
/*
* 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_clear - Set MAC address.
* @hldev: HAL device handle.
* @index: MAC address index, in the range from 0 to
* XGE_HAL_MAX_MAC_ADDRESSES.
*
* Clear one of the available MAC address "slots".
*
* 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_set(), xge_hal_status_e{}.
*/
{
if (status != XGE_HAL_OK) {
"Not able to set the mac addr");
return status;
}
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=0; 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
*/
/* 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;
}
/* 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
/* Getting VPD data */
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
{
#if defined(XGE_HAL_TX_MULTI_RESERVE_IRQ)
unsigned long flags = 0;
#endif
/*
* go through each opened tx channel and aquire
* lock, so it will serialize with HAL termination flag
*/
#if defined(XGE_HAL_TX_MULTI_RESERVE)
#elif defined(XGE_HAL_TX_MULTI_RESERVE_IRQ)
#endif
#if defined(XGE_HAL_TX_MULTI_RESERVE)
#elif defined(XGE_HAL_TX_MULTI_RESERVE_IRQ)
#endif
}
}
/**
* 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 *) *
}
}
int j, pcisize;
for (j = 0; j < pcisize; j++) {
}
}
}
/**
* __hal_device_get_vpd_data - Getting vpd_data.
*
* @hldev: HAL device handle.
*
* Getting product name and serial number from vpd capabilites structure
*
*/
void
{
"10 Gigabit Ethernet Adapter",
"not available",
if ( vpd_data == 0 )
return;
xge_os_mdelay(2);
if (data == XGE_HAL_VPD_READ_COMPLETE)
break;
}
if (count >= 5) {
xge_os_printf("ERR, Reading VPD data failed");
fail = 1;
break;
}
}
if(!fail) {
/* read serial number of adapter */
break;
}
}
}
}
}
/**
* 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;
}
return XGE_HAL_ERR_PKT_DROP;
#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;
/* do not drop if detected unknown IPv6 extension */
} else if (t_code != XGE_HAL_RXD_T_CODE_UNKNOWN_PROTO) {
return XGE_HAL_ERR_PKT_DROP;
}
}
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;
return XGE_HAL_CARD_TITAN;
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", *spdm_entry);
}
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.
*
*/
static u32
{
/*
* 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;
}
/**
* 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 ", 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 ", 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 ", 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 ", 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_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.
*/
{
&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.
*/
{
&bar0->tx_traffic_mask);
&bar0->tx_traffic_mask);
}
/**
* 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;
}
/**
* xge_hal_mask_msix - Begin IRQ processing.
* @hldev: HAL device handle.
* @msi_id: MSI ID
*
* The function masks the msix interrupt for the given msi_id
*
* Note:
*
* Returns: 0,
* Otherwise, XGE_HAL_ERR_WRONG_IRQ if the msix index is out of range
* status.
* See also:
*/
{
val32 |= 1;
return status;
}
/**
* xge_hal_mask_msix - Begin IRQ processing.
* @hldev: HAL device handle.
* @msi_id: MSI ID
*
* The function masks the msix interrupt for the given msi_id
*
* Note:
*
* Returns: 0,
* Otherwise, XGE_HAL_ERR_WRONG_IRQ if the msix index is out of range
* status.
* See also:
*/
{
val32 &= ~1;
return status;
}
/*
* __hal_set_msix_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. */
}
return XGE_HAL_OK;
}
#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.
*/
{
int i;
for (i=0; i < XGE_HAL_MAX_RING_NUM; i++)
{
sizeof(lro_t) * XGE_HAL_LRO_MAX_BUCKETS);
}
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;
}
/*
* xge_hal_fix_rldram_ecc_error
* @hldev: private member of the device structure.
*
* SXE-02-010. This function will turn OFF the ECC error reporting for the
* interface bet'n external Micron RLDRAM II device and memory controller.
* The error would have been reported in RLD_ECC_DB_ERR_L and RLD_ECC_DB_ERR_U
* fileds of MC_ERR_REG register. Issue reported by HP-Unix folks during the
* qualification of Herc.
*/
{
// Enter Test Mode.
val64 = 0x0100000000000000ULL;
// Enable RLDRAM configuration.
val64 = 0x0000000000017B00ULL;
&bar0->mc_rldram_mrs);
// Enable RLDRAM queues.
val64 = 0x0000000001017B00ULL;
&bar0->mc_rldram_mrs);
// Setup test ranges.
val64 = 0x00000000001E0100ULL;
val64 = 0x00000100001F0100ULL;
// Start Reads.
val64 = 0x0001000000010000ULL;
}
// Exit test mode.
val64 = 0x0000000000000000ULL;
return XGE_HAL_OK;
}
/*
* xge_hal_device_quiesce
* @hldev: HAL device object
* @devh : HAL device handle
*
* This is called by xge_quiesce to quiesce the device.
*/
void
{
/* Turn off debugging */
/* Disable device */
(void) xge_hal_device_disable(devh);
/* Disable Xframe interrupts */
}