2008-04-27 15:55:59 +04:00
/****************************************************************************
* Driver for Solarflare Solarstorm network controllers and boards
* Copyright 2005 - 2006 Fen Systems Ltd .
* Copyright 2006 - 2008 Solarflare Communications Inc .
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation , incorporated herein by reference .
*/
# include <linux/delay.h>
# include "net_driver.h"
# include "efx.h"
# include "falcon.h"
2009-10-23 12:30:36 +04:00
# include "regs.h"
2009-10-23 12:30:46 +04:00
# include "io.h"
2008-04-27 15:55:59 +04:00
# include "mac.h"
# include "mdio_10g.h"
# include "phy.h"
# include "workarounds.h"
/**************************************************************************
*
* MAC operations
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Configure the XAUI driver that is an output from Falcon */
static void falcon_setup_xaui ( struct efx_nic * efx )
{
2008-09-01 15:48:41 +04:00
efx_oword_t sdctl , txdrv ;
2008-04-27 15:55:59 +04:00
/* Move the XAUI into low power, unless there is no PHY, in
* which case the XAUI will have to drive a cable . */
if ( efx - > phy_type = = PHY_TYPE_NONE )
return ;
2009-10-23 12:30:46 +04:00
efx_reado ( efx , & sdctl , FR_AB_XX_SD_CTL ) ;
2009-10-23 12:30:36 +04:00
EFX_SET_OWORD_FIELD ( sdctl , FRF_AB_XX_HIDRVD , FFE_AB_XX_SD_CTL_DRV_DEF ) ;
EFX_SET_OWORD_FIELD ( sdctl , FRF_AB_XX_LODRVD , FFE_AB_XX_SD_CTL_DRV_DEF ) ;
EFX_SET_OWORD_FIELD ( sdctl , FRF_AB_XX_HIDRVC , FFE_AB_XX_SD_CTL_DRV_DEF ) ;
EFX_SET_OWORD_FIELD ( sdctl , FRF_AB_XX_LODRVC , FFE_AB_XX_SD_CTL_DRV_DEF ) ;
EFX_SET_OWORD_FIELD ( sdctl , FRF_AB_XX_HIDRVB , FFE_AB_XX_SD_CTL_DRV_DEF ) ;
EFX_SET_OWORD_FIELD ( sdctl , FRF_AB_XX_LODRVB , FFE_AB_XX_SD_CTL_DRV_DEF ) ;
EFX_SET_OWORD_FIELD ( sdctl , FRF_AB_XX_HIDRVA , FFE_AB_XX_SD_CTL_DRV_DEF ) ;
EFX_SET_OWORD_FIELD ( sdctl , FRF_AB_XX_LODRVA , FFE_AB_XX_SD_CTL_DRV_DEF ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & sdctl , FR_AB_XX_SD_CTL ) ;
2008-09-01 15:48:41 +04:00
EFX_POPULATE_OWORD_8 ( txdrv ,
2009-10-23 12:30:36 +04:00
FRF_AB_XX_DEQD , FFE_AB_XX_TXDRV_DEQ_DEF ,
FRF_AB_XX_DEQC , FFE_AB_XX_TXDRV_DEQ_DEF ,
FRF_AB_XX_DEQB , FFE_AB_XX_TXDRV_DEQ_DEF ,
FRF_AB_XX_DEQA , FFE_AB_XX_TXDRV_DEQ_DEF ,
FRF_AB_XX_DTXD , FFE_AB_XX_TXDRV_DTX_DEF ,
FRF_AB_XX_DTXC , FFE_AB_XX_TXDRV_DTX_DEF ,
FRF_AB_XX_DTXB , FFE_AB_XX_TXDRV_DTX_DEF ,
FRF_AB_XX_DTXA , FFE_AB_XX_TXDRV_DTX_DEF ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & txdrv , FR_AB_XX_TXDRV_CTL ) ;
2008-04-27 15:55:59 +04:00
}
2008-09-01 15:49:20 +04:00
int falcon_reset_xaui ( struct efx_nic * efx )
2008-04-27 15:55:59 +04:00
{
2009-11-25 19:11:35 +03:00
struct falcon_nic_data * nic_data = efx - > nic_data ;
2008-09-01 15:48:41 +04:00
efx_oword_t reg ;
2008-04-27 15:55:59 +04:00
int count ;
2009-11-25 19:11:35 +03:00
/* Don't fetch MAC statistics over an XMAC reset */
WARN_ON ( nic_data - > stats_disable_count = = 0 ) ;
2009-08-26 12:16:46 +04:00
/* Start reset sequence */
2009-11-25 19:08:41 +03:00
EFX_POPULATE_OWORD_1 ( reg , FRF_AB_XX_RST_XX_EN , 1 ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & reg , FR_AB_XX_PWR_RST ) ;
2008-04-27 15:55:59 +04:00
2009-08-26 12:16:46 +04:00
/* Wait up to 10 ms for completion, then reinitialise */
for ( count = 0 ; count < 1000 ; count + + ) {
2009-10-23 12:30:46 +04:00
efx_reado ( efx , & reg , FR_AB_XX_PWR_RST ) ;
2009-10-23 12:30:36 +04:00
if ( EFX_OWORD_FIELD ( reg , FRF_AB_XX_RST_XX_EN ) = = 0 & &
EFX_OWORD_FIELD ( reg , FRF_AB_XX_SD_RST_ACT ) = = 0 ) {
2008-04-27 15:55:59 +04:00
falcon_setup_xaui ( efx ) ;
return 0 ;
}
udelay ( 10 ) ;
}
EFX_ERR ( efx , " timed out waiting for XAUI/XGXS reset \n " ) ;
return - ETIMEDOUT ;
}
2008-12-13 08:50:08 +03:00
static void falcon_mask_status_intr ( struct efx_nic * efx , bool enable )
2008-04-27 15:55:59 +04:00
{
2008-09-01 15:48:41 +04:00
efx_oword_t reg ;
2008-04-27 15:55:59 +04:00
2009-11-28 08:36:04 +03:00
if ( ( efx_nic_rev ( efx ) ! = EFX_REV_FALCON_B0 ) | | LOOPBACK_INTERNAL ( efx ) )
2008-12-13 08:50:08 +03:00
return ;
2008-04-27 15:55:59 +04:00
2008-12-13 08:50:08 +03:00
/* We expect xgmii faults if the wireside link is up */
2009-11-23 19:06:30 +03:00
if ( ! EFX_WORKAROUND_5147 ( efx ) | | ! efx - > link_state . up )
2008-12-13 08:50:08 +03:00
return ;
2008-04-27 15:55:59 +04:00
2008-12-13 08:50:08 +03:00
/* We can only use this interrupt to signal the negative edge of
* xaui_align [ we have to poll the positive edge ] . */
2009-11-25 19:12:01 +03:00
if ( efx - > xmac_poll_required )
2008-04-27 15:55:59 +04:00
return ;
/* Flush the ISR */
if ( enable )
2009-10-23 12:30:46 +04:00
efx_reado ( efx , & reg , FR_AB_XM_MGT_INT_MSK ) ;
2008-04-27 15:55:59 +04:00
2008-09-01 15:48:41 +04:00
EFX_POPULATE_OWORD_2 ( reg ,
2009-10-23 12:30:36 +04:00
FRF_AB_XM_MSK_RMTFLT , ! enable ,
FRF_AB_XM_MSK_LCLFLT , ! enable ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & reg , FR_AB_XM_MGT_INT_MASK ) ;
2008-04-27 15:55:59 +04:00
}
2008-12-13 08:50:08 +03:00
/* Get status of XAUI link */
2009-11-29 06:42:41 +03:00
static bool falcon_xaui_link_ok ( struct efx_nic * efx )
2008-04-27 15:55:59 +04:00
{
2008-09-01 15:48:41 +04:00
efx_oword_t reg ;
2008-09-01 15:46:50 +04:00
bool align_done , link_ok = false ;
int sync_status ;
2008-04-27 15:55:59 +04:00
2008-05-07 16:36:19 +04:00
if ( LOOPBACK_INTERNAL ( efx ) )
2008-09-01 15:46:50 +04:00
return true ;
2008-05-07 16:36:19 +04:00
2008-04-27 15:55:59 +04:00
/* Read link status */
2009-10-23 12:30:46 +04:00
efx_reado ( efx , & reg , FR_AB_XX_CORE_STAT ) ;
2008-04-27 15:55:59 +04:00
2009-10-23 12:30:36 +04:00
align_done = EFX_OWORD_FIELD ( reg , FRF_AB_XX_ALIGN_DONE ) ;
sync_status = EFX_OWORD_FIELD ( reg , FRF_AB_XX_SYNC_STAT ) ;
if ( align_done & & ( sync_status = = FFE_AB_XX_STAT_ALL_LANES ) )
2008-09-01 15:46:50 +04:00
link_ok = true ;
2008-04-27 15:55:59 +04:00
/* Clear link status ready for next read */
2009-10-23 12:30:36 +04:00
EFX_SET_OWORD_FIELD ( reg , FRF_AB_XX_COMMA_DET , FFE_AB_XX_STAT_ALL_LANES ) ;
EFX_SET_OWORD_FIELD ( reg , FRF_AB_XX_CHAR_ERR , FFE_AB_XX_STAT_ALL_LANES ) ;
EFX_SET_OWORD_FIELD ( reg , FRF_AB_XX_DISPERR , FFE_AB_XX_STAT_ALL_LANES ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & reg , FR_AB_XX_CORE_STAT ) ;
2008-04-27 15:55:59 +04:00
2008-12-13 08:50:08 +03:00
/* If the link is up, then check the phy side of the xaui link */
2009-11-23 19:06:30 +03:00
if ( efx - > link_state . up & & link_ok )
2008-09-01 15:46:50 +04:00
if ( efx - > phy_op - > mmds & ( 1 < < MDIO_MMD_PHYXS ) )
2009-04-29 12:05:08 +04:00
link_ok = efx_mdio_phyxgxs_lane_sync ( efx ) ;
2008-04-27 15:55:59 +04:00
return link_ok ;
}
2009-11-29 06:42:41 +03:00
void falcon_reconfigure_xmac_core ( struct efx_nic * efx )
2008-04-27 15:55:59 +04:00
{
unsigned int max_frame_len ;
2008-09-01 15:48:41 +04:00
efx_oword_t reg ;
2009-11-23 19:06:30 +03:00
bool rx_fc = ! ! ( efx - > link_state . fc & EFX_FC_RX ) ;
2009-11-29 06:42:18 +03:00
bool tx_fc = ! ! ( efx - > link_state . fc & EFX_FC_TX ) ;
2008-04-27 15:55:59 +04:00
/* Configure MAC - cut-thru mode is hard wired on */
2009-11-25 19:08:41 +03:00
EFX_POPULATE_OWORD_3 ( reg ,
2009-10-23 12:30:36 +04:00
FRF_AB_XM_RX_JUMBO_MODE , 1 ,
FRF_AB_XM_TX_STAT_EN , 1 ,
FRF_AB_XM_RX_STAT_EN , 1 ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & reg , FR_AB_XM_GLB_CFG ) ;
2008-04-27 15:55:59 +04:00
/* Configure TX */
2009-11-25 19:08:41 +03:00
EFX_POPULATE_OWORD_6 ( reg ,
2009-10-23 12:30:36 +04:00
FRF_AB_XM_TXEN , 1 ,
FRF_AB_XM_TX_PRMBL , 1 ,
FRF_AB_XM_AUTO_PAD , 1 ,
FRF_AB_XM_TXCRC , 1 ,
2009-11-29 06:42:18 +03:00
FRF_AB_XM_FCNTL , tx_fc ,
2009-10-23 12:30:36 +04:00
FRF_AB_XM_IPG , 0x3 ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & reg , FR_AB_XM_TX_CFG ) ;
2008-04-27 15:55:59 +04:00
/* Configure RX */
2009-11-25 19:08:41 +03:00
EFX_POPULATE_OWORD_5 ( reg ,
2009-10-23 12:30:36 +04:00
FRF_AB_XM_RXEN , 1 ,
FRF_AB_XM_AUTO_DEPAD , 0 ,
FRF_AB_XM_ACPT_ALL_MCAST , 1 ,
FRF_AB_XM_ACPT_ALL_UCAST , efx - > promiscuous ,
FRF_AB_XM_PASS_CRC_ERR , 1 ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & reg , FR_AB_XM_RX_CFG ) ;
2008-04-27 15:55:59 +04:00
/* Set frame length */
max_frame_len = EFX_MAX_FRAME_LEN ( efx - > net_dev - > mtu ) ;
2009-11-25 19:08:41 +03:00
EFX_POPULATE_OWORD_1 ( reg , FRF_AB_XM_MAX_RX_FRM_SIZE , max_frame_len ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & reg , FR_AB_XM_RX_PARAM ) ;
2009-11-25 19:08:41 +03:00
EFX_POPULATE_OWORD_2 ( reg ,
2009-10-23 12:30:36 +04:00
FRF_AB_XM_MAX_TX_FRM_SIZE , max_frame_len ,
FRF_AB_XM_TX_JUMBO_MODE , 1 ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & reg , FR_AB_XM_TX_PARAM ) ;
2008-04-27 15:55:59 +04:00
2009-11-25 19:08:41 +03:00
EFX_POPULATE_OWORD_2 ( reg ,
2009-10-23 12:30:36 +04:00
FRF_AB_XM_PAUSE_TIME , 0xfffe , /* MAX PAUSE TIME */
FRF_AB_XM_DIS_FCNTL , ! rx_fc ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & reg , FR_AB_XM_FC ) ;
2008-04-27 15:55:59 +04:00
/* Set MAC address */
2009-10-23 12:30:36 +04:00
memcpy ( & reg , & efx - > net_dev - > dev_addr [ 0 ] , 4 ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & reg , FR_AB_XM_ADR_LO ) ;
2009-10-23 12:30:36 +04:00
memcpy ( & reg , & efx - > net_dev - > dev_addr [ 4 ] , 2 ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & reg , FR_AB_XM_ADR_HI ) ;
2008-04-27 15:55:59 +04:00
}
2008-05-07 16:36:19 +04:00
static void falcon_reconfigure_xgxs_core ( struct efx_nic * efx )
{
2008-09-01 15:48:41 +04:00
efx_oword_t reg ;
2008-09-01 15:46:50 +04:00
bool xgxs_loopback = ( efx - > loopback_mode = = LOOPBACK_XGXS ) ;
bool xaui_loopback = ( efx - > loopback_mode = = LOOPBACK_XAUI ) ;
bool xgmii_loopback = ( efx - > loopback_mode = = LOOPBACK_XGMII ) ;
2008-05-07 16:36:19 +04:00
/* XGXS block is flaky and will need to be reset if moving
* into our out of XGMII , XGXS or XAUI loopbacks . */
if ( EFX_WORKAROUND_5147 ( efx ) ) {
2008-09-01 15:46:50 +04:00
bool old_xgmii_loopback , old_xgxs_loopback , old_xaui_loopback ;
bool reset_xgxs ;
2008-05-07 16:36:19 +04:00
2009-10-23 12:30:46 +04:00
efx_reado ( efx , & reg , FR_AB_XX_CORE_STAT ) ;
2009-10-23 12:30:36 +04:00
old_xgxs_loopback = EFX_OWORD_FIELD ( reg , FRF_AB_XX_XGXS_LB_EN ) ;
old_xgmii_loopback =
EFX_OWORD_FIELD ( reg , FRF_AB_XX_XGMII_LB_EN ) ;
2008-05-07 16:36:19 +04:00
2009-10-23 12:30:46 +04:00
efx_reado ( efx , & reg , FR_AB_XX_SD_CTL ) ;
2009-10-23 12:30:36 +04:00
old_xaui_loopback = EFX_OWORD_FIELD ( reg , FRF_AB_XX_LPBKA ) ;
2008-05-07 16:36:19 +04:00
/* The PHY driver may have turned XAUI off */
reset_xgxs = ( ( xgxs_loopback ! = old_xgxs_loopback ) | |
( xaui_loopback ! = old_xaui_loopback ) | |
( xgmii_loopback ! = old_xgmii_loopback ) ) ;
2008-09-01 15:49:02 +04:00
if ( reset_xgxs )
falcon_reset_xaui ( efx ) ;
2008-05-07 16:36:19 +04:00
}
2009-10-23 12:30:46 +04:00
efx_reado ( efx , & reg , FR_AB_XX_CORE_STAT ) ;
2009-10-23 12:30:36 +04:00
EFX_SET_OWORD_FIELD ( reg , FRF_AB_XX_FORCE_SIG ,
2008-05-07 16:36:19 +04:00
( xgxs_loopback | | xaui_loopback ) ?
2009-10-23 12:30:36 +04:00
FFE_AB_XX_FORCE_SIG_ALL_LANES : 0 ) ;
EFX_SET_OWORD_FIELD ( reg , FRF_AB_XX_XGXS_LB_EN , xgxs_loopback ) ;
EFX_SET_OWORD_FIELD ( reg , FRF_AB_XX_XGMII_LB_EN , xgmii_loopback ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & reg , FR_AB_XX_CORE_STAT ) ;
2009-10-23 12:30:36 +04:00
2009-10-23 12:30:46 +04:00
efx_reado ( efx , & reg , FR_AB_XX_SD_CTL ) ;
2009-10-23 12:30:36 +04:00
EFX_SET_OWORD_FIELD ( reg , FRF_AB_XX_LPBKD , xaui_loopback ) ;
EFX_SET_OWORD_FIELD ( reg , FRF_AB_XX_LPBKC , xaui_loopback ) ;
EFX_SET_OWORD_FIELD ( reg , FRF_AB_XX_LPBKB , xaui_loopback ) ;
EFX_SET_OWORD_FIELD ( reg , FRF_AB_XX_LPBKA , xaui_loopback ) ;
2009-10-23 12:30:46 +04:00
efx_writeo ( efx , & reg , FR_AB_XX_SD_CTL ) ;
2008-05-07 16:36:19 +04:00
}
2009-11-25 19:12:01 +03:00
/* Try to bring up the Falcon side of the Falcon-Phy XAUI link */
static bool falcon_check_xaui_link_up ( struct efx_nic * efx , int tries )
2008-04-27 15:55:59 +04:00
{
2009-11-25 19:12:01 +03:00
bool mac_up = falcon_xaui_link_ok ( efx ) ;
2008-04-27 15:55:59 +04:00
2008-05-07 16:36:19 +04:00
if ( ( efx - > loopback_mode = = LOOPBACK_NETWORK ) | |
2008-09-01 15:48:17 +04:00
efx_phy_mode_disabled ( efx - > phy_mode ) )
2008-12-13 08:50:08 +03:00
/* XAUI link is expected to be down */
2009-11-25 19:12:01 +03:00
return mac_up ;
2008-04-27 15:55:59 +04:00
2009-11-25 19:11:35 +03:00
falcon_stop_nic_stats ( efx ) ;
2009-11-25 19:12:01 +03:00
while ( ! mac_up & & tries ) {
2008-12-13 08:50:08 +03:00
EFX_LOG ( efx , " bashing xaui \n " ) ;
2008-05-17 00:14:27 +04:00
falcon_reset_xaui ( efx ) ;
2008-04-27 15:55:59 +04:00
udelay ( 200 ) ;
2009-11-25 19:12:01 +03:00
mac_up = falcon_xaui_link_ok ( efx ) ;
2008-12-13 08:50:08 +03:00
- - tries ;
}
2009-11-25 19:11:35 +03:00
falcon_start_nic_stats ( efx ) ;
2009-11-25 19:12:01 +03:00
return mac_up ;
}
static bool falcon_xmac_check_fault ( struct efx_nic * efx )
{
return ! falcon_check_xaui_link_up ( efx , 5 ) ;
2008-04-27 15:55:59 +04:00
}
2009-11-29 06:42:41 +03:00
static int falcon_reconfigure_xmac ( struct efx_nic * efx )
2008-04-27 15:55:59 +04:00
{
2008-09-01 15:46:50 +04:00
falcon_mask_status_intr ( efx , false ) ;
2008-04-27 15:55:59 +04:00
2008-05-07 16:36:19 +04:00
falcon_reconfigure_xgxs_core ( efx ) ;
2008-04-27 15:55:59 +04:00
falcon_reconfigure_xmac_core ( efx ) ;
2008-05-07 16:36:19 +04:00
2008-04-27 15:55:59 +04:00
falcon_reconfigure_mac_wrapper ( efx ) ;
2009-11-25 19:12:01 +03:00
efx - > xmac_poll_required = ! falcon_check_xaui_link_up ( efx , 5 ) ;
2008-12-13 08:50:08 +03:00
falcon_mask_status_intr ( efx , true ) ;
2009-11-29 06:42:41 +03:00
return 0 ;
2008-04-27 15:55:59 +04:00
}
2008-12-13 08:50:08 +03:00
static void falcon_update_stats_xmac ( struct efx_nic * efx )
2008-04-27 15:55:59 +04:00
{
struct efx_mac_stats * mac_stats = & efx - > mac_stats ;
/* Update MAC stats from DMAed values */
FALCON_STAT ( efx , XgRxOctets , rx_bytes ) ;
FALCON_STAT ( efx , XgRxOctetsOK , rx_good_bytes ) ;
FALCON_STAT ( efx , XgRxPkts , rx_packets ) ;
FALCON_STAT ( efx , XgRxPktsOK , rx_good ) ;
FALCON_STAT ( efx , XgRxBroadcastPkts , rx_broadcast ) ;
FALCON_STAT ( efx , XgRxMulticastPkts , rx_multicast ) ;
FALCON_STAT ( efx , XgRxUnicastPkts , rx_unicast ) ;
FALCON_STAT ( efx , XgRxUndersizePkts , rx_lt64 ) ;
FALCON_STAT ( efx , XgRxOversizePkts , rx_gtjumbo ) ;
FALCON_STAT ( efx , XgRxJabberPkts , rx_bad_gtjumbo ) ;
FALCON_STAT ( efx , XgRxUndersizeFCSerrorPkts , rx_bad_lt64 ) ;
FALCON_STAT ( efx , XgRxDropEvents , rx_overflow ) ;
FALCON_STAT ( efx , XgRxFCSerrorPkts , rx_bad ) ;
FALCON_STAT ( efx , XgRxAlignError , rx_align_error ) ;
FALCON_STAT ( efx , XgRxSymbolError , rx_symbol_error ) ;
FALCON_STAT ( efx , XgRxInternalMACError , rx_internal_error ) ;
FALCON_STAT ( efx , XgRxControlPkts , rx_control ) ;
FALCON_STAT ( efx , XgRxPausePkts , rx_pause ) ;
FALCON_STAT ( efx , XgRxPkts64Octets , rx_64 ) ;
FALCON_STAT ( efx , XgRxPkts65to127Octets , rx_65_to_127 ) ;
FALCON_STAT ( efx , XgRxPkts128to255Octets , rx_128_to_255 ) ;
FALCON_STAT ( efx , XgRxPkts256to511Octets , rx_256_to_511 ) ;
FALCON_STAT ( efx , XgRxPkts512to1023Octets , rx_512_to_1023 ) ;
FALCON_STAT ( efx , XgRxPkts1024to15xxOctets , rx_1024_to_15xx ) ;
FALCON_STAT ( efx , XgRxPkts15xxtoMaxOctets , rx_15xx_to_jumbo ) ;
FALCON_STAT ( efx , XgRxLengthError , rx_length_error ) ;
FALCON_STAT ( efx , XgTxPkts , tx_packets ) ;
FALCON_STAT ( efx , XgTxOctets , tx_bytes ) ;
FALCON_STAT ( efx , XgTxMulticastPkts , tx_multicast ) ;
FALCON_STAT ( efx , XgTxBroadcastPkts , tx_broadcast ) ;
FALCON_STAT ( efx , XgTxUnicastPkts , tx_unicast ) ;
FALCON_STAT ( efx , XgTxControlPkts , tx_control ) ;
FALCON_STAT ( efx , XgTxPausePkts , tx_pause ) ;
FALCON_STAT ( efx , XgTxPkts64Octets , tx_64 ) ;
FALCON_STAT ( efx , XgTxPkts65to127Octets , tx_65_to_127 ) ;
FALCON_STAT ( efx , XgTxPkts128to255Octets , tx_128_to_255 ) ;
FALCON_STAT ( efx , XgTxPkts256to511Octets , tx_256_to_511 ) ;
FALCON_STAT ( efx , XgTxPkts512to1023Octets , tx_512_to_1023 ) ;
FALCON_STAT ( efx , XgTxPkts1024to15xxOctets , tx_1024_to_15xx ) ;
FALCON_STAT ( efx , XgTxPkts1519toMaxOctets , tx_15xx_to_jumbo ) ;
FALCON_STAT ( efx , XgTxUndersizePkts , tx_lt64 ) ;
FALCON_STAT ( efx , XgTxOversizePkts , tx_gtjumbo ) ;
FALCON_STAT ( efx , XgTxNonTcpUdpPkt , tx_non_tcpudp ) ;
FALCON_STAT ( efx , XgTxMacSrcErrPkt , tx_mac_src_error ) ;
FALCON_STAT ( efx , XgTxIpSrcErrPkt , tx_ip_src_error ) ;
/* Update derived statistics */
mac_stats - > tx_good_bytes =
2008-09-01 15:46:10 +04:00
( mac_stats - > tx_bytes - mac_stats - > tx_bad_bytes -
mac_stats - > tx_control * 64 ) ;
2008-04-27 15:55:59 +04:00
mac_stats - > rx_bad_bytes =
2008-09-01 15:46:10 +04:00
( mac_stats - > rx_bytes - mac_stats - > rx_good_bytes -
mac_stats - > rx_control * 64 ) ;
2008-04-27 15:55:59 +04:00
}
2009-11-25 19:12:01 +03:00
void falcon_poll_xmac ( struct efx_nic * efx )
2008-12-13 08:59:24 +03:00
{
2009-11-25 19:12:01 +03:00
if ( ! EFX_WORKAROUND_5147 ( efx ) | | ! efx - > link_state . up | |
! efx - > xmac_poll_required )
2008-12-13 08:59:24 +03:00
return ;
2008-05-07 16:36:19 +04:00
2008-09-01 15:46:50 +04:00
falcon_mask_status_intr ( efx , false ) ;
2009-11-25 19:12:01 +03:00
efx - > xmac_poll_required = ! falcon_check_xaui_link_up ( efx , 1 ) ;
2008-12-13 08:59:24 +03:00
falcon_mask_status_intr ( efx , true ) ;
2008-04-27 15:55:59 +04:00
}
2008-12-13 08:50:08 +03:00
struct efx_mac_operations falcon_xmac_operations = {
. reconfigure = falcon_reconfigure_xmac ,
. update_stats = falcon_update_stats_xmac ,
2009-11-25 19:12:01 +03:00
. check_fault = falcon_xmac_check_fault ,
2008-12-13 08:50:08 +03:00
} ;