Index: head/sys/dev/sfxge/common/efx.h =================================================================== --- head/sys/dev/sfxge/common/efx.h (revision 291394) +++ head/sys/dev/sfxge/common/efx.h (revision 291395) @@ -1,2300 +1,2300 @@ /*- * Copyright (c) 2006-2015 Solarflare Communications Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the FreeBSD Project. * * $FreeBSD$ */ #ifndef _SYS_EFX_H #define _SYS_EFX_H #include "efsys.h" #include "efx_phy_ids.h" #ifdef __cplusplus extern "C" { #endif #define EFX_STATIC_ASSERT(_cond) ((void)sizeof(char[(_cond) ? 1 : -1])) #define EFX_ARRAY_SIZE(_array) (sizeof(_array) / sizeof((_array)[0])) #define EFX_FIELD_OFFSET(_type, _field) ((size_t) &(((_type *)0)->_field)) typedef enum efx_family_e { EFX_FAMILY_INVALID, EFX_FAMILY_FALCON, EFX_FAMILY_SIENA, EFX_FAMILY_HUNTINGTON, EFX_FAMILY_NTYPES } efx_family_t; extern __checkReturn int efx_family( __in uint16_t venid, __in uint16_t devid, __out efx_family_t *efp); extern __checkReturn int efx_infer_family( __in efsys_bar_t *esbp, __out efx_family_t *efp); #define EFX_PCI_VENID_SFC 0x1924 #define EFX_PCI_DEVID_FALCON 0x0710 /* SFC4000 */ #define EFX_PCI_DEVID_BETHPAGE 0x0803 /* SFC9020 */ #define EFX_PCI_DEVID_SIENA 0x0813 /* SFL9021 */ #define EFX_PCI_DEVID_SIENA_F1_UNINIT 0x0810 #define EFX_PCI_DEVID_HUNTINGTON_PF_UNINIT 0x0901 #define EFX_PCI_DEVID_FARMINGDALE 0x0903 /* SFC9120 PF */ #define EFX_PCI_DEVID_HUNTINGTON 0x0913 /* SFL9122 PF */ #define EFX_PCI_DEVID_GREENPORT 0x0923 /* SFC9140 PF */ #define EFX_PCI_DEVID_FARMINGDALE_VF 0x1903 /* SFC9120 VF */ #define EFX_PCI_DEVID_HUNTINGTON_VF 0x1913 /* SFL9122 VF */ #define EFX_PCI_DEVID_GREENPORT_VF 0x1923 /* SFC9140 VF */ #define EFX_MEM_BAR 2 /* Error codes */ enum { EFX_ERR_INVALID, EFX_ERR_SRAM_OOB, EFX_ERR_BUFID_DC_OOB, EFX_ERR_MEM_PERR, EFX_ERR_RBUF_OWN, EFX_ERR_TBUF_OWN, EFX_ERR_RDESQ_OWN, EFX_ERR_TDESQ_OWN, EFX_ERR_EVQ_OWN, EFX_ERR_EVFF_OFLO, EFX_ERR_ILL_ADDR, EFX_ERR_SRAM_PERR, EFX_ERR_NCODES }; /* Calculate the IEEE 802.3 CRC32 of a MAC addr */ extern __checkReturn uint32_t efx_crc32_calculate( __in uint32_t crc_init, __in_ecount(length) uint8_t const *input, __in int length); /* Type prototypes */ typedef struct efx_rxq_s efx_rxq_t; /* NIC */ typedef struct efx_nic_s efx_nic_t; #define EFX_NIC_FUNC_PRIMARY 0x00000001 #define EFX_NIC_FUNC_LINKCTRL 0x00000002 #define EFX_NIC_FUNC_TRUSTED 0x00000004 extern __checkReturn int efx_nic_create( __in efx_family_t family, __in efsys_identifier_t *esip, __in efsys_bar_t *esbp, __in efsys_lock_t *eslp, __deref_out efx_nic_t **enpp); extern __checkReturn int efx_nic_probe( __in efx_nic_t *enp); #if EFSYS_OPT_PCIE_TUNE extern __checkReturn int efx_nic_pcie_tune( __in efx_nic_t *enp, unsigned int nlanes); extern __checkReturn int efx_nic_pcie_extended_sync( __in efx_nic_t *enp); #endif /* EFSYS_OPT_PCIE_TUNE */ extern __checkReturn int efx_nic_init( __in efx_nic_t *enp); extern __checkReturn int efx_nic_reset( __in efx_nic_t *enp); #if EFSYS_OPT_DIAG extern __checkReturn int efx_nic_register_test( __in efx_nic_t *enp); #endif /* EFSYS_OPT_DIAG */ extern void efx_nic_fini( __in efx_nic_t *enp); extern void efx_nic_unprobe( __in efx_nic_t *enp); extern void efx_nic_destroy( __in efx_nic_t *enp); #if EFSYS_OPT_MCDI #if EFSYS_OPT_HUNTINGTON /* Huntington requires MCDIv2 commands */ #define WITH_MCDI_V2 1 #endif typedef struct efx_mcdi_req_s efx_mcdi_req_t; typedef enum efx_mcdi_exception_e { EFX_MCDI_EXCEPTION_MC_REBOOT, EFX_MCDI_EXCEPTION_MC_BADASSERT, } efx_mcdi_exception_t; typedef struct efx_mcdi_transport_s { void *emt_context; efsys_mem_t *emt_dma_mem; void (*emt_execute)(void *, efx_mcdi_req_t *); void (*emt_ev_cpl)(void *); void (*emt_exception)(void *, efx_mcdi_exception_t); } efx_mcdi_transport_t; extern __checkReturn int efx_mcdi_init( __in efx_nic_t *enp, __in const efx_mcdi_transport_t *mtp); extern __checkReturn int efx_mcdi_reboot( __in efx_nic_t *enp); void efx_mcdi_new_epoch( __in efx_nic_t *enp); extern void efx_mcdi_request_start( __in efx_nic_t *enp, __in efx_mcdi_req_t *emrp, __in boolean_t ev_cpl); extern __checkReturn boolean_t efx_mcdi_request_poll( __in efx_nic_t *enp); extern __checkReturn boolean_t efx_mcdi_request_abort( __in efx_nic_t *enp); extern void efx_mcdi_fini( __in efx_nic_t *enp); #endif /* EFSYS_OPT_MCDI */ /* INTR */ #define EFX_NINTR_FALCON 64 #define EFX_NINTR_SIENA 1024 typedef enum efx_intr_type_e { EFX_INTR_INVALID = 0, EFX_INTR_LINE, EFX_INTR_MESSAGE, EFX_INTR_NTYPES } efx_intr_type_t; #define EFX_INTR_SIZE (sizeof (efx_oword_t)) extern __checkReturn int efx_intr_init( __in efx_nic_t *enp, __in efx_intr_type_t type, __in efsys_mem_t *esmp); extern void efx_intr_enable( __in efx_nic_t *enp); extern void efx_intr_disable( __in efx_nic_t *enp); extern void efx_intr_disable_unlocked( __in efx_nic_t *enp); #define EFX_INTR_NEVQS 32 extern __checkReturn int efx_intr_trigger( __in efx_nic_t *enp, __in unsigned int level); extern void efx_intr_status_line( __in efx_nic_t *enp, __out boolean_t *fatalp, __out uint32_t *maskp); extern void efx_intr_status_message( __in efx_nic_t *enp, __in unsigned int message, __out boolean_t *fatalp); extern void efx_intr_fatal( __in efx_nic_t *enp); extern void efx_intr_fini( __in efx_nic_t *enp); /* MAC */ #if EFSYS_OPT_MAC_STATS /* START MKCONFIG GENERATED EfxHeaderMacBlock e323546097fd7c65 */ typedef enum efx_mac_stat_e { EFX_MAC_RX_OCTETS, EFX_MAC_RX_PKTS, EFX_MAC_RX_UNICST_PKTS, EFX_MAC_RX_MULTICST_PKTS, EFX_MAC_RX_BRDCST_PKTS, EFX_MAC_RX_PAUSE_PKTS, EFX_MAC_RX_LE_64_PKTS, EFX_MAC_RX_65_TO_127_PKTS, EFX_MAC_RX_128_TO_255_PKTS, EFX_MAC_RX_256_TO_511_PKTS, EFX_MAC_RX_512_TO_1023_PKTS, EFX_MAC_RX_1024_TO_15XX_PKTS, EFX_MAC_RX_GE_15XX_PKTS, EFX_MAC_RX_ERRORS, EFX_MAC_RX_FCS_ERRORS, EFX_MAC_RX_DROP_EVENTS, EFX_MAC_RX_FALSE_CARRIER_ERRORS, EFX_MAC_RX_SYMBOL_ERRORS, EFX_MAC_RX_ALIGN_ERRORS, EFX_MAC_RX_INTERNAL_ERRORS, EFX_MAC_RX_JABBER_PKTS, EFX_MAC_RX_LANE0_CHAR_ERR, EFX_MAC_RX_LANE1_CHAR_ERR, EFX_MAC_RX_LANE2_CHAR_ERR, EFX_MAC_RX_LANE3_CHAR_ERR, EFX_MAC_RX_LANE0_DISP_ERR, EFX_MAC_RX_LANE1_DISP_ERR, EFX_MAC_RX_LANE2_DISP_ERR, EFX_MAC_RX_LANE3_DISP_ERR, EFX_MAC_RX_MATCH_FAULT, EFX_MAC_RX_NODESC_DROP_CNT, EFX_MAC_TX_OCTETS, EFX_MAC_TX_PKTS, EFX_MAC_TX_UNICST_PKTS, EFX_MAC_TX_MULTICST_PKTS, EFX_MAC_TX_BRDCST_PKTS, EFX_MAC_TX_PAUSE_PKTS, EFX_MAC_TX_LE_64_PKTS, EFX_MAC_TX_65_TO_127_PKTS, EFX_MAC_TX_128_TO_255_PKTS, EFX_MAC_TX_256_TO_511_PKTS, EFX_MAC_TX_512_TO_1023_PKTS, EFX_MAC_TX_1024_TO_15XX_PKTS, EFX_MAC_TX_GE_15XX_PKTS, EFX_MAC_TX_ERRORS, EFX_MAC_TX_SGL_COL_PKTS, EFX_MAC_TX_MULT_COL_PKTS, EFX_MAC_TX_EX_COL_PKTS, EFX_MAC_TX_LATE_COL_PKTS, EFX_MAC_TX_DEF_PKTS, EFX_MAC_TX_EX_DEF_PKTS, EFX_MAC_PM_TRUNC_BB_OVERFLOW, EFX_MAC_PM_DISCARD_BB_OVERFLOW, EFX_MAC_PM_TRUNC_VFIFO_FULL, EFX_MAC_PM_DISCARD_VFIFO_FULL, EFX_MAC_PM_TRUNC_QBB, EFX_MAC_PM_DISCARD_QBB, EFX_MAC_PM_DISCARD_MAPPING, EFX_MAC_RXDP_Q_DISABLED_PKTS, EFX_MAC_RXDP_DI_DROPPED_PKTS, EFX_MAC_RXDP_STREAMING_PKTS, EFX_MAC_RXDP_HLB_FETCH, EFX_MAC_RXDP_HLB_WAIT, EFX_MAC_VADAPTER_RX_UNICAST_PACKETS, EFX_MAC_VADAPTER_RX_UNICAST_BYTES, EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS, EFX_MAC_VADAPTER_RX_MULTICAST_BYTES, EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS, EFX_MAC_VADAPTER_RX_BROADCAST_BYTES, EFX_MAC_VADAPTER_RX_BAD_PACKETS, EFX_MAC_VADAPTER_RX_BAD_BYTES, EFX_MAC_VADAPTER_RX_OVERFLOW, EFX_MAC_VADAPTER_TX_UNICAST_PACKETS, EFX_MAC_VADAPTER_TX_UNICAST_BYTES, EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS, EFX_MAC_VADAPTER_TX_MULTICAST_BYTES, EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS, EFX_MAC_VADAPTER_TX_BROADCAST_BYTES, EFX_MAC_VADAPTER_TX_BAD_PACKETS, EFX_MAC_VADAPTER_TX_BAD_BYTES, EFX_MAC_VADAPTER_TX_OVERFLOW, EFX_MAC_NSTATS } efx_mac_stat_t; /* END MKCONFIG GENERATED EfxHeaderMacBlock */ #endif /* EFSYS_OPT_MAC_STATS */ typedef enum efx_link_mode_e { EFX_LINK_UNKNOWN = 0, EFX_LINK_DOWN, EFX_LINK_10HDX, EFX_LINK_10FDX, EFX_LINK_100HDX, EFX_LINK_100FDX, EFX_LINK_1000HDX, EFX_LINK_1000FDX, EFX_LINK_10000FDX, EFX_LINK_40000FDX, EFX_LINK_NMODES } efx_link_mode_t; #define EFX_MAC_ADDR_LEN 6 #define EFX_MAC_ADDR_IS_MULTICAST(_address) (((uint8_t*)_address)[0] & 0x01) #define EFX_MAC_MULTICAST_LIST_MAX 256 #define EFX_MAC_SDU_MAX 9202 #define EFX_MAC_PDU(_sdu) \ P2ROUNDUP(((_sdu) \ + /* EtherII */ 14 \ + /* VLAN */ 4 \ + /* CRC */ 4 \ + /* bug16011 */ 16), \ (1 << 3)) #define EFX_MAC_PDU_MIN 60 #define EFX_MAC_PDU_MAX EFX_MAC_PDU(EFX_MAC_SDU_MAX) extern __checkReturn int efx_mac_pdu_set( __in efx_nic_t *enp, __in size_t pdu); extern __checkReturn int efx_mac_addr_set( __in efx_nic_t *enp, __in uint8_t *addr); extern __checkReturn int efx_mac_filter_set( __in efx_nic_t *enp, __in boolean_t all_unicst, __in boolean_t mulcst, __in boolean_t all_mulcst, __in boolean_t brdcst); extern __checkReturn int efx_mac_multicast_list_set( __in efx_nic_t *enp, __in_ecount(6*count) uint8_t const *addrs, __in int count); extern __checkReturn int efx_mac_filter_default_rxq_set( __in efx_nic_t *enp, __in efx_rxq_t *erp, __in boolean_t using_rss); extern void efx_mac_filter_default_rxq_clear( __in efx_nic_t *enp); extern __checkReturn int efx_mac_drain( __in efx_nic_t *enp, __in boolean_t enabled); extern __checkReturn int efx_mac_up( __in efx_nic_t *enp, __out boolean_t *mac_upp); #define EFX_FCNTL_RESPOND 0x00000001 #define EFX_FCNTL_GENERATE 0x00000002 extern __checkReturn int efx_mac_fcntl_set( __in efx_nic_t *enp, __in unsigned int fcntl, __in boolean_t autoneg); extern void efx_mac_fcntl_get( __in efx_nic_t *enp, __out unsigned int *fcntl_wantedp, __out unsigned int *fcntl_linkp); #define EFX_MAC_HASH_BITS (1 << 8) extern __checkReturn int efx_pktfilter_init( __in efx_nic_t *enp); extern void efx_pktfilter_fini( __in efx_nic_t *enp); extern __checkReturn int efx_pktfilter_set( __in efx_nic_t *enp, __in boolean_t unicst, __in boolean_t brdcst); extern __checkReturn int efx_mac_hash_set( __in efx_nic_t *enp, __in_ecount(EFX_MAC_HASH_BITS) unsigned int const *bucket); #if EFSYS_OPT_MCAST_FILTER_LIST extern __checkReturn int efx_pktfilter_mcast_list_set( __in efx_nic_t *enp, __in uint8_t const *addrs, __in int count); #endif /* EFSYS_OPT_MCAST_FILTER_LIST */ extern __checkReturn int efx_pktfilter_mcast_all( __in efx_nic_t *enp); #if EFSYS_OPT_MAC_STATS #if EFSYS_OPT_NAMES extern __checkReturn const char * efx_mac_stat_name( __in efx_nic_t *enp, __in unsigned int id); #endif /* EFSYS_OPT_NAMES */ #define EFX_MAC_STATS_SIZE 0x400 /* * Upload mac statistics supported by the hardware into the given buffer. * * The reference buffer must be at least %EFX_MAC_STATS_SIZE bytes, * and page aligned. * * The hardware will only DMA statistics that it understands (of course). * Drivers should not make any assumptions about which statistics are * supported, especially when the statistics are generated by firmware. * * Thus, drivers should zero this buffer before use, so that not-understood * statistics read back as zero. */ extern __checkReturn int efx_mac_stats_upload( __in efx_nic_t *enp, __in efsys_mem_t *esmp); extern __checkReturn int efx_mac_stats_periodic( __in efx_nic_t *enp, __in efsys_mem_t *esmp, __in uint16_t period_ms, __in boolean_t events); extern __checkReturn int efx_mac_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, __out_opt uint32_t *generationp); #endif /* EFSYS_OPT_MAC_STATS */ /* MON */ typedef enum efx_mon_type_e { EFX_MON_INVALID = 0, EFX_MON_NULL, EFX_MON_LM87, EFX_MON_MAX6647, EFX_MON_SFC90X0, EFX_MON_SFC91X0, EFX_MON_NTYPES } efx_mon_type_t; #if EFSYS_OPT_NAMES extern const char * efx_mon_name( __in efx_nic_t *enp); #endif /* EFSYS_OPT_NAMES */ extern __checkReturn int efx_mon_init( __in efx_nic_t *enp); #if EFSYS_OPT_MON_STATS #define EFX_MON_STATS_PAGE_SIZE 0x100 #define EFX_MON_MASK_ELEMENT_SIZE 32 /* START MKCONFIG GENERATED MonitorHeaderStatsBlock c79c86b62a144846 */ typedef enum efx_mon_stat_e { EFX_MON_STAT_2_5V, EFX_MON_STAT_VCCP1, EFX_MON_STAT_VCC, EFX_MON_STAT_5V, EFX_MON_STAT_12V, EFX_MON_STAT_VCCP2, EFX_MON_STAT_EXT_TEMP, EFX_MON_STAT_INT_TEMP, EFX_MON_STAT_AIN1, EFX_MON_STAT_AIN2, EFX_MON_STAT_INT_COOLING, EFX_MON_STAT_EXT_COOLING, EFX_MON_STAT_1V, EFX_MON_STAT_1_2V, EFX_MON_STAT_1_8V, EFX_MON_STAT_3_3V, EFX_MON_STAT_1_2VA, EFX_MON_STAT_VREF, EFX_MON_STAT_VAOE, EFX_MON_STAT_AOE_TEMP, EFX_MON_STAT_PSU_AOE_TEMP, EFX_MON_STAT_PSU_TEMP, EFX_MON_STAT_FAN0, EFX_MON_STAT_FAN1, EFX_MON_STAT_FAN2, EFX_MON_STAT_FAN3, EFX_MON_STAT_FAN4, EFX_MON_STAT_VAOE_IN, EFX_MON_STAT_IAOE, EFX_MON_STAT_IAOE_IN, EFX_MON_STAT_NIC_POWER, EFX_MON_STAT_0_9V, EFX_MON_STAT_I0_9V, EFX_MON_STAT_I1_2V, EFX_MON_STAT_0_9V_ADC, EFX_MON_STAT_INT_TEMP2, EFX_MON_STAT_VREG_TEMP, EFX_MON_STAT_VREG_0_9V_TEMP, EFX_MON_STAT_VREG_1_2V_TEMP, EFX_MON_STAT_INT_VPTAT, EFX_MON_STAT_INT_ADC_TEMP, EFX_MON_STAT_EXT_VPTAT, EFX_MON_STAT_EXT_ADC_TEMP, EFX_MON_STAT_AMBIENT_TEMP, EFX_MON_STAT_AIRFLOW, EFX_MON_STAT_VDD08D_VSS08D_CSR, EFX_MON_STAT_VDD08D_VSS08D_CSR_EXTADC, EFX_MON_STAT_HOTPOINT_TEMP, EFX_MON_STAT_PHY_POWER_SWITCH_PORT0, EFX_MON_STAT_PHY_POWER_SWITCH_PORT1, EFX_MON_STAT_MUM_VCC, EFX_MON_STAT_0V9_A, EFX_MON_STAT_I0V9_A, EFX_MON_STAT_0V9_A_TEMP, EFX_MON_STAT_0V9_B, EFX_MON_STAT_I0V9_B, EFX_MON_STAT_0V9_B_TEMP, EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY, EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXT_ADC, EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY, EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXT_ADC, EFX_MON_STAT_CONTROLLER_MASTER_VPTAT, EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP, EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXT_ADC, EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXT_ADC, EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT, EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP, EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXT_ADC, EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXT_ADC, EFX_MON_NSTATS } efx_mon_stat_t; /* END MKCONFIG GENERATED MonitorHeaderStatsBlock */ typedef enum efx_mon_stat_state_e { EFX_MON_STAT_STATE_OK = 0, EFX_MON_STAT_STATE_WARNING = 1, EFX_MON_STAT_STATE_FATAL = 2, EFX_MON_STAT_STATE_BROKEN = 3, EFX_MON_STAT_STATE_NO_READING = 4, } efx_mon_stat_state_t; typedef struct efx_mon_stat_value_s { uint16_t emsv_value; uint16_t emsv_state; } efx_mon_stat_value_t; #if EFSYS_OPT_NAMES extern const char * efx_mon_stat_name( __in efx_nic_t *enp, __in efx_mon_stat_t id); #endif /* EFSYS_OPT_NAMES */ extern __checkReturn int efx_mon_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values); + __inout_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values); #endif /* EFSYS_OPT_MON_STATS */ extern void efx_mon_fini( __in efx_nic_t *enp); /* PHY */ #define PMA_PMD_MMD 1 #define PCS_MMD 3 #define PHY_XS_MMD 4 #define DTE_XS_MMD 5 #define AN_MMD 7 #define CL22EXT_MMD 29 #define MAXMMD ((1 << 5) - 1) extern __checkReturn int efx_phy_verify( __in efx_nic_t *enp); #if EFSYS_OPT_PHY_LED_CONTROL typedef enum efx_phy_led_mode_e { EFX_PHY_LED_DEFAULT = 0, EFX_PHY_LED_OFF, EFX_PHY_LED_ON, EFX_PHY_LED_FLASH, EFX_PHY_LED_NMODES } efx_phy_led_mode_t; extern __checkReturn int efx_phy_led_set( __in efx_nic_t *enp, __in efx_phy_led_mode_t mode); #endif /* EFSYS_OPT_PHY_LED_CONTROL */ extern __checkReturn int efx_port_init( __in efx_nic_t *enp); #if EFSYS_OPT_LOOPBACK typedef enum efx_loopback_type_e { EFX_LOOPBACK_OFF = 0, EFX_LOOPBACK_DATA = 1, EFX_LOOPBACK_GMAC = 2, EFX_LOOPBACK_XGMII = 3, EFX_LOOPBACK_XGXS = 4, EFX_LOOPBACK_XAUI = 5, EFX_LOOPBACK_GMII = 6, EFX_LOOPBACK_SGMII = 7, EFX_LOOPBACK_XGBR = 8, EFX_LOOPBACK_XFI = 9, EFX_LOOPBACK_XAUI_FAR = 10, EFX_LOOPBACK_GMII_FAR = 11, EFX_LOOPBACK_SGMII_FAR = 12, EFX_LOOPBACK_XFI_FAR = 13, EFX_LOOPBACK_GPHY = 14, EFX_LOOPBACK_PHY_XS = 15, EFX_LOOPBACK_PCS = 16, EFX_LOOPBACK_PMA_PMD = 17, EFX_LOOPBACK_XPORT = 18, EFX_LOOPBACK_XGMII_WS = 19, EFX_LOOPBACK_XAUI_WS = 20, EFX_LOOPBACK_XAUI_WS_FAR = 21, EFX_LOOPBACK_XAUI_WS_NEAR = 22, EFX_LOOPBACK_GMII_WS = 23, EFX_LOOPBACK_XFI_WS = 24, EFX_LOOPBACK_XFI_WS_FAR = 25, EFX_LOOPBACK_PHYXS_WS = 26, EFX_LOOPBACK_PMA_INT = 27, EFX_LOOPBACK_SD_NEAR = 28, EFX_LOOPBACK_SD_FAR = 29, EFX_LOOPBACK_PMA_INT_WS = 30, EFX_LOOPBACK_SD_FEP2_WS = 31, EFX_LOOPBACK_SD_FEP1_5_WS = 32, EFX_LOOPBACK_SD_FEP_WS = 33, EFX_LOOPBACK_SD_FES_WS = 34, EFX_LOOPBACK_NTYPES } efx_loopback_type_t; typedef enum efx_loopback_kind_e { EFX_LOOPBACK_KIND_OFF = 0, EFX_LOOPBACK_KIND_ALL, EFX_LOOPBACK_KIND_MAC, EFX_LOOPBACK_KIND_PHY, EFX_LOOPBACK_NKINDS } efx_loopback_kind_t; extern void efx_loopback_mask( __in efx_loopback_kind_t loopback_kind, __out efx_qword_t *maskp); extern __checkReturn int efx_port_loopback_set( __in efx_nic_t *enp, __in efx_link_mode_t link_mode, __in efx_loopback_type_t type); #if EFSYS_OPT_NAMES extern __checkReturn const char * efx_loopback_type_name( __in efx_nic_t *enp, __in efx_loopback_type_t type); #endif /* EFSYS_OPT_NAMES */ #endif /* EFSYS_OPT_LOOPBACK */ extern __checkReturn int efx_port_poll( __in efx_nic_t *enp, __out_opt efx_link_mode_t *link_modep); extern void efx_port_fini( __in efx_nic_t *enp); typedef enum efx_phy_cap_type_e { EFX_PHY_CAP_INVALID = 0, EFX_PHY_CAP_10HDX, EFX_PHY_CAP_10FDX, EFX_PHY_CAP_100HDX, EFX_PHY_CAP_100FDX, EFX_PHY_CAP_1000HDX, EFX_PHY_CAP_1000FDX, EFX_PHY_CAP_10000FDX, EFX_PHY_CAP_PAUSE, EFX_PHY_CAP_ASYM, EFX_PHY_CAP_AN, EFX_PHY_CAP_40000FDX, EFX_PHY_CAP_NTYPES } efx_phy_cap_type_t; #define EFX_PHY_CAP_CURRENT 0x00000000 #define EFX_PHY_CAP_DEFAULT 0x00000001 #define EFX_PHY_CAP_PERM 0x00000002 extern void efx_phy_adv_cap_get( __in efx_nic_t *enp, __in uint32_t flag, __out uint32_t *maskp); extern __checkReturn int efx_phy_adv_cap_set( __in efx_nic_t *enp, __in uint32_t mask); extern void efx_phy_lp_cap_get( __in efx_nic_t *enp, __out uint32_t *maskp); extern __checkReturn int efx_phy_oui_get( __in efx_nic_t *enp, __out uint32_t *ouip); typedef enum efx_phy_media_type_e { EFX_PHY_MEDIA_INVALID = 0, EFX_PHY_MEDIA_XAUI, EFX_PHY_MEDIA_CX4, EFX_PHY_MEDIA_KX4, EFX_PHY_MEDIA_XFP, EFX_PHY_MEDIA_SFP_PLUS, EFX_PHY_MEDIA_BASE_T, EFX_PHY_MEDIA_QSFP_PLUS, EFX_PHY_MEDIA_NTYPES } efx_phy_media_type_t; /* Get the type of medium currently used. If the board has ports for * modules, a module is present, and we recognise the media type of * the module, then this will be the media type of the module. * Otherwise it will be the media type of the port. */ extern void efx_phy_media_type_get( __in efx_nic_t *enp, __out efx_phy_media_type_t *typep); #if EFSYS_OPT_PHY_STATS /* START MKCONFIG GENERATED PhyHeaderStatsBlock 30ed56ad501f8e36 */ typedef enum efx_phy_stat_e { EFX_PHY_STAT_OUI, EFX_PHY_STAT_PMA_PMD_LINK_UP, EFX_PHY_STAT_PMA_PMD_RX_FAULT, EFX_PHY_STAT_PMA_PMD_TX_FAULT, EFX_PHY_STAT_PMA_PMD_REV_A, EFX_PHY_STAT_PMA_PMD_REV_B, EFX_PHY_STAT_PMA_PMD_REV_C, EFX_PHY_STAT_PMA_PMD_REV_D, EFX_PHY_STAT_PCS_LINK_UP, EFX_PHY_STAT_PCS_RX_FAULT, EFX_PHY_STAT_PCS_TX_FAULT, EFX_PHY_STAT_PCS_BER, EFX_PHY_STAT_PCS_BLOCK_ERRORS, EFX_PHY_STAT_PHY_XS_LINK_UP, EFX_PHY_STAT_PHY_XS_RX_FAULT, EFX_PHY_STAT_PHY_XS_TX_FAULT, EFX_PHY_STAT_PHY_XS_ALIGN, EFX_PHY_STAT_PHY_XS_SYNC_A, EFX_PHY_STAT_PHY_XS_SYNC_B, EFX_PHY_STAT_PHY_XS_SYNC_C, EFX_PHY_STAT_PHY_XS_SYNC_D, EFX_PHY_STAT_AN_LINK_UP, EFX_PHY_STAT_AN_MASTER, EFX_PHY_STAT_AN_LOCAL_RX_OK, EFX_PHY_STAT_AN_REMOTE_RX_OK, EFX_PHY_STAT_CL22EXT_LINK_UP, EFX_PHY_STAT_SNR_A, EFX_PHY_STAT_SNR_B, EFX_PHY_STAT_SNR_C, EFX_PHY_STAT_SNR_D, EFX_PHY_STAT_PMA_PMD_SIGNAL_A, EFX_PHY_STAT_PMA_PMD_SIGNAL_B, EFX_PHY_STAT_PMA_PMD_SIGNAL_C, EFX_PHY_STAT_PMA_PMD_SIGNAL_D, EFX_PHY_STAT_AN_COMPLETE, EFX_PHY_STAT_PMA_PMD_REV_MAJOR, EFX_PHY_STAT_PMA_PMD_REV_MINOR, EFX_PHY_STAT_PMA_PMD_REV_MICRO, EFX_PHY_STAT_PCS_FW_VERSION_0, EFX_PHY_STAT_PCS_FW_VERSION_1, EFX_PHY_STAT_PCS_FW_VERSION_2, EFX_PHY_STAT_PCS_FW_VERSION_3, EFX_PHY_STAT_PCS_FW_BUILD_YY, EFX_PHY_STAT_PCS_FW_BUILD_MM, EFX_PHY_STAT_PCS_FW_BUILD_DD, EFX_PHY_STAT_PCS_OP_MODE, EFX_PHY_NSTATS } efx_phy_stat_t; /* END MKCONFIG GENERATED PhyHeaderStatsBlock */ #if EFSYS_OPT_NAMES extern const char * efx_phy_stat_name( __in efx_nic_t *enp, __in efx_phy_stat_t stat); #endif /* EFSYS_OPT_NAMES */ #define EFX_PHY_STATS_SIZE 0x100 extern __checkReturn int efx_phy_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __out_ecount(EFX_PHY_NSTATS) uint32_t *stat); + __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat); #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES extern const char * efx_phy_prop_name( __in efx_nic_t *enp, __in unsigned int id); #endif /* EFSYS_OPT_NAMES */ #define EFX_PHY_PROP_DEFAULT 0x00000001 extern __checkReturn int efx_phy_prop_get( __in efx_nic_t *enp, __in unsigned int id, __in uint32_t flags, __out uint32_t *valp); extern __checkReturn int efx_phy_prop_set( __in efx_nic_t *enp, __in unsigned int id, __in uint32_t val); #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_BIST typedef enum efx_bist_type_e { EFX_BIST_TYPE_UNKNOWN, EFX_BIST_TYPE_PHY_NORMAL, EFX_BIST_TYPE_PHY_CABLE_SHORT, EFX_BIST_TYPE_PHY_CABLE_LONG, EFX_BIST_TYPE_MC_MEM, /* Test the MC DMEM and IMEM */ EFX_BIST_TYPE_SAT_MEM, /* Test the DMEM and IMEM of satellite cpus*/ EFX_BIST_TYPE_REG, /* Test the register memories */ EFX_BIST_TYPE_NTYPES, } efx_bist_type_t; typedef enum efx_bist_result_e { EFX_BIST_RESULT_UNKNOWN, EFX_BIST_RESULT_RUNNING, EFX_BIST_RESULT_PASSED, EFX_BIST_RESULT_FAILED, } efx_bist_result_t; typedef enum efx_phy_cable_status_e { EFX_PHY_CABLE_STATUS_OK, EFX_PHY_CABLE_STATUS_INVALID, EFX_PHY_CABLE_STATUS_OPEN, EFX_PHY_CABLE_STATUS_INTRAPAIRSHORT, EFX_PHY_CABLE_STATUS_INTERPAIRSHORT, EFX_PHY_CABLE_STATUS_BUSY, } efx_phy_cable_status_t; typedef enum efx_bist_value_e { EFX_BIST_PHY_CABLE_LENGTH_A, EFX_BIST_PHY_CABLE_LENGTH_B, EFX_BIST_PHY_CABLE_LENGTH_C, EFX_BIST_PHY_CABLE_LENGTH_D, EFX_BIST_PHY_CABLE_STATUS_A, EFX_BIST_PHY_CABLE_STATUS_B, EFX_BIST_PHY_CABLE_STATUS_C, EFX_BIST_PHY_CABLE_STATUS_D, EFX_BIST_FAULT_CODE, /* Memory BIST specific values. These match to the MC_CMD_BIST_POLL * response. */ EFX_BIST_MEM_TEST, EFX_BIST_MEM_ADDR, EFX_BIST_MEM_BUS, EFX_BIST_MEM_EXPECT, EFX_BIST_MEM_ACTUAL, EFX_BIST_MEM_ECC, EFX_BIST_MEM_ECC_PARITY, EFX_BIST_MEM_ECC_FATAL, EFX_BIST_NVALUES, } efx_bist_value_t; extern __checkReturn int efx_bist_enable_offline( __in efx_nic_t *enp); extern __checkReturn int efx_bist_start( __in efx_nic_t *enp, __in efx_bist_type_t type); extern __checkReturn int efx_bist_poll( __in efx_nic_t *enp, __in efx_bist_type_t type, __out efx_bist_result_t *resultp, __out_opt uint32_t *value_maskp, __out_ecount_opt(count) unsigned long *valuesp, __in size_t count); extern void efx_bist_stop( __in efx_nic_t *enp, __in efx_bist_type_t type); #endif /* EFSYS_OPT_BIST */ #define EFX_FEATURE_IPV6 0x00000001 #define EFX_FEATURE_LFSR_HASH_INSERT 0x00000002 #define EFX_FEATURE_LINK_EVENTS 0x00000004 #define EFX_FEATURE_PERIODIC_MAC_STATS 0x00000008 #define EFX_FEATURE_WOL 0x00000010 #define EFX_FEATURE_MCDI 0x00000020 #define EFX_FEATURE_LOOKAHEAD_SPLIT 0x00000040 #define EFX_FEATURE_MAC_HEADER_FILTERS 0x00000080 #define EFX_FEATURE_TURBO 0x00000100 #define EFX_FEATURE_MCDI_DMA 0x00000200 #define EFX_FEATURE_TX_SRC_FILTERS 0x00000400 #define EFX_FEATURE_PIO_BUFFERS 0x00000800 #define EFX_FEATURE_FW_ASSISTED_TSO 0x00001000 typedef struct efx_nic_cfg_s { uint32_t enc_board_type; uint32_t enc_phy_type; #if EFSYS_OPT_NAMES char enc_phy_name[21]; #endif char enc_phy_revision[21]; efx_mon_type_t enc_mon_type; #if EFSYS_OPT_MON_STATS uint32_t enc_mon_stat_dma_buf_size; uint32_t enc_mon_stat_mask[(EFX_MON_NSTATS + 31) / 32]; #endif unsigned int enc_features; uint8_t enc_mac_addr[6]; uint8_t enc_port; /* PHY port number */ uint32_t enc_func_flags; uint32_t enc_intr_vec_base; uint32_t enc_intr_limit; uint32_t enc_evq_limit; uint32_t enc_txq_limit; uint32_t enc_rxq_limit; uint32_t enc_buftbl_limit; uint32_t enc_piobuf_limit; uint32_t enc_piobuf_size; uint32_t enc_evq_timer_quantum_ns; uint32_t enc_evq_timer_max_us; uint32_t enc_clk_mult; uint32_t enc_rx_prefix_size; uint32_t enc_rx_buf_align_start; uint32_t enc_rx_buf_align_end; #if EFSYS_OPT_LOOPBACK efx_qword_t enc_loopback_types[EFX_LINK_NMODES]; #endif /* EFSYS_OPT_LOOPBACK */ #if EFSYS_OPT_PHY_FLAGS uint32_t enc_phy_flags_mask; #endif /* EFSYS_OPT_PHY_FLAGS */ #if EFSYS_OPT_PHY_LED_CONTROL uint32_t enc_led_mask; #endif /* EFSYS_OPT_PHY_LED_CONTROL */ #if EFSYS_OPT_PHY_STATS uint64_t enc_phy_stat_mask; #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS unsigned int enc_phy_nprops; #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_SIENA uint8_t enc_mcdi_mdio_channel; #if EFSYS_OPT_PHY_STATS uint32_t enc_mcdi_phy_stat_mask; #endif /* EFSYS_OPT_PHY_STATS */ #endif /* EFSYS_OPT_SIENA */ #if (EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON) #if EFSYS_OPT_MON_STATS uint32_t *enc_mcdi_sensor_maskp; uint32_t enc_mcdi_sensor_mask_size; #endif /* EFSYS_OPT_MON_STATS */ #endif /* (EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON) */ #if EFSYS_OPT_BIST uint32_t enc_bist_mask; #endif /* EFSYS_OPT_BIST */ #if EFSYS_OPT_HUNTINGTON uint32_t enc_pf; uint32_t enc_vf; uint32_t enc_privilege_mask; #endif /* EFSYS_OPT_HUNTINGTON */ boolean_t enc_bug26807_workaround; boolean_t enc_bug35388_workaround; boolean_t enc_bug41750_workaround; boolean_t enc_rx_batching_enabled; /* Maximum number of descriptors completed in an rx event. */ uint32_t enc_rx_batch_max; /* Number of rx descriptors the hardware requires for a push. */ uint32_t enc_rx_push_align; /* * Maximum number of bytes into the packet the TCP header can start for * the hardware to apply TSO packet edits. */ uint32_t enc_tx_tso_tcp_header_offset_limit; boolean_t enc_fw_assisted_tso_enabled; boolean_t enc_hw_tx_insert_vlan_enabled; /* Datapath firmware vadapter/vport/vswitch support */ boolean_t enc_datapath_cap_evb; /* External port identifier */ uint8_t enc_external_port; } efx_nic_cfg_t; #define EFX_PCI_FUNCTION_IS_PF(_encp) ((_encp)->enc_vf == 0xffff) #define EFX_PCI_FUNCTION_IS_VF(_encp) ((_encp)->enc_vf != 0xffff) #define EFX_PCI_FUNCTION(_encp) \ (EFX_PCI_FUNCTION_IS_PF(_encp) ? (_encp)->enc_pf : (_encp)->enc_vf) #define EFX_PCI_VF_PARENT(_encp) ((_encp)->enc_pf) extern const efx_nic_cfg_t * efx_nic_cfg_get( __in efx_nic_t *enp); /* Driver resource limits (minimum required/maximum usable). */ typedef struct efx_drv_limits_s { uint32_t edl_min_evq_count; uint32_t edl_max_evq_count; uint32_t edl_min_rxq_count; uint32_t edl_max_rxq_count; uint32_t edl_min_txq_count; uint32_t edl_max_txq_count; /* PIO blocks (sub-allocated from piobuf) */ uint32_t edl_min_pio_alloc_size; uint32_t edl_max_pio_alloc_count; } efx_drv_limits_t; extern __checkReturn int efx_nic_set_drv_limits( __inout efx_nic_t *enp, __in efx_drv_limits_t *edlp); typedef enum efx_nic_region_e { EFX_REGION_VI, /* Memory BAR UC mapping */ EFX_REGION_PIO_WRITE_VI, /* Memory BAR WC mapping */ } efx_nic_region_t; extern __checkReturn int efx_nic_get_bar_region( __in efx_nic_t *enp, __in efx_nic_region_t region, __out uint32_t *offsetp, __out size_t *sizep); extern __checkReturn int efx_nic_get_vi_pool( __in efx_nic_t *enp, __out uint32_t *evq_countp, __out uint32_t *rxq_countp, __out uint32_t *txq_countp); #if EFSYS_OPT_VPD typedef enum efx_vpd_tag_e { EFX_VPD_ID = 0x02, EFX_VPD_END = 0x0f, EFX_VPD_RO = 0x10, EFX_VPD_RW = 0x11, } efx_vpd_tag_t; typedef uint16_t efx_vpd_keyword_t; typedef struct efx_vpd_value_s { efx_vpd_tag_t evv_tag; efx_vpd_keyword_t evv_keyword; uint8_t evv_length; uint8_t evv_value[0x100]; } efx_vpd_value_t; #define EFX_VPD_KEYWORD(x, y) ((x) | ((y) << 8)) extern __checkReturn int efx_vpd_init( __in efx_nic_t *enp); extern __checkReturn int efx_vpd_size( __in efx_nic_t *enp, __out size_t *sizep); extern __checkReturn int efx_vpd_read( __in efx_nic_t *enp, __out_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int efx_vpd_verify( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int efx_vpd_reinit( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int efx_vpd_get( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size, __inout efx_vpd_value_t *evvp); extern __checkReturn int efx_vpd_set( __in efx_nic_t *enp, __inout_bcount(size) caddr_t data, __in size_t size, __in efx_vpd_value_t *evvp); extern __checkReturn int efx_vpd_next( __in efx_nic_t *enp, __inout_bcount(size) caddr_t data, __in size_t size, __out efx_vpd_value_t *evvp, __inout unsigned int *contp); extern __checkReturn int efx_vpd_write( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size); extern void efx_vpd_fini( __in efx_nic_t *enp); #endif /* EFSYS_OPT_VPD */ /* NVRAM */ #if EFSYS_OPT_NVRAM typedef enum efx_nvram_type_e { EFX_NVRAM_INVALID = 0, EFX_NVRAM_BOOTROM, EFX_NVRAM_BOOTROM_CFG, EFX_NVRAM_MC_FIRMWARE, EFX_NVRAM_MC_GOLDEN, EFX_NVRAM_PHY, EFX_NVRAM_NULLPHY, EFX_NVRAM_FPGA, EFX_NVRAM_FCFW, EFX_NVRAM_CPLD, EFX_NVRAM_FPGA_BACKUP, EFX_NVRAM_DYNAMIC_CFG, EFX_NVRAM_NTYPES, } efx_nvram_type_t; extern __checkReturn int efx_nvram_init( __in efx_nic_t *enp); #if EFSYS_OPT_DIAG extern __checkReturn int efx_nvram_test( __in efx_nic_t *enp); #endif /* EFSYS_OPT_DIAG */ extern __checkReturn int efx_nvram_size( __in efx_nic_t *enp, __in efx_nvram_type_t type, __out size_t *sizep); extern __checkReturn int efx_nvram_rw_start( __in efx_nic_t *enp, __in efx_nvram_type_t type, __out_opt size_t *pref_chunkp); extern void efx_nvram_rw_finish( __in efx_nic_t *enp, __in efx_nvram_type_t type); extern __checkReturn int efx_nvram_get_version( __in efx_nic_t *enp, __in efx_nvram_type_t type, __out uint32_t *subtypep, __out_ecount(4) uint16_t version[4]); extern __checkReturn int efx_nvram_read_chunk( __in efx_nic_t *enp, __in efx_nvram_type_t type, __in unsigned int offset, __out_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int efx_nvram_set_version( __in efx_nic_t *enp, __in efx_nvram_type_t type, __in_ecount(4) uint16_t version[4]); /* Validate contents of TLV formatted partition */ extern __checkReturn int efx_nvram_tlv_validate( __in efx_nic_t *enp, __in uint32_t partn, __in_bcount(partn_size) caddr_t partn_data, __in size_t partn_size); extern __checkReturn int efx_nvram_erase( __in efx_nic_t *enp, __in efx_nvram_type_t type); extern __checkReturn int efx_nvram_write_chunk( __in efx_nic_t *enp, __in efx_nvram_type_t type, __in unsigned int offset, __in_bcount(size) caddr_t data, __in size_t size); extern void efx_nvram_fini( __in efx_nic_t *enp); #endif /* EFSYS_OPT_NVRAM */ #if EFSYS_OPT_BOOTCFG extern int efx_bootcfg_read( __in efx_nic_t *enp, __out_bcount(size) caddr_t data, __in size_t size); extern int efx_bootcfg_write( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size); #endif /* EFSYS_OPT_BOOTCFG */ #if EFSYS_OPT_WOL typedef enum efx_wol_type_e { EFX_WOL_TYPE_INVALID, EFX_WOL_TYPE_MAGIC, EFX_WOL_TYPE_BITMAP, EFX_WOL_TYPE_LINK, EFX_WOL_NTYPES, } efx_wol_type_t; typedef enum efx_lightsout_offload_type_e { EFX_LIGHTSOUT_OFFLOAD_TYPE_INVALID, EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP, EFX_LIGHTSOUT_OFFLOAD_TYPE_NS, } efx_lightsout_offload_type_t; #define EFX_WOL_BITMAP_MASK_SIZE (48) #define EFX_WOL_BITMAP_VALUE_SIZE (128) typedef union efx_wol_param_u { struct { uint8_t mac_addr[6]; } ewp_magic; struct { uint8_t mask[EFX_WOL_BITMAP_MASK_SIZE]; /* 1 bit per byte */ uint8_t value[EFX_WOL_BITMAP_VALUE_SIZE]; /* value to match */ uint8_t value_len; } ewp_bitmap; } efx_wol_param_t; typedef union efx_lightsout_offload_param_u { struct { uint8_t mac_addr[6]; uint32_t ip; } elop_arp; struct { uint8_t mac_addr[6]; uint32_t solicited_node[4]; uint32_t ip[4]; } elop_ns; } efx_lightsout_offload_param_t; extern __checkReturn int efx_wol_init( __in efx_nic_t *enp); extern __checkReturn int efx_wol_filter_clear( __in efx_nic_t *enp); extern __checkReturn int efx_wol_filter_add( __in efx_nic_t *enp, __in efx_wol_type_t type, __in efx_wol_param_t *paramp, __out uint32_t *filter_idp); extern __checkReturn int efx_wol_filter_remove( __in efx_nic_t *enp, __in uint32_t filter_id); extern __checkReturn int efx_lightsout_offload_add( __in efx_nic_t *enp, __in efx_lightsout_offload_type_t type, __in efx_lightsout_offload_param_t *paramp, __out uint32_t *filter_idp); extern __checkReturn int efx_lightsout_offload_remove( __in efx_nic_t *enp, __in efx_lightsout_offload_type_t type, __in uint32_t filter_id); extern void efx_wol_fini( __in efx_nic_t *enp); #endif /* EFSYS_OPT_WOL */ #if EFSYS_OPT_DIAG typedef enum efx_pattern_type_t { EFX_PATTERN_BYTE_INCREMENT = 0, EFX_PATTERN_ALL_THE_SAME, EFX_PATTERN_BIT_ALTERNATE, EFX_PATTERN_BYTE_ALTERNATE, EFX_PATTERN_BYTE_CHANGING, EFX_PATTERN_BIT_SWEEP, EFX_PATTERN_NTYPES } efx_pattern_type_t; typedef void (*efx_sram_pattern_fn_t)( __in size_t row, __in boolean_t negate, __out efx_qword_t *eqp); extern __checkReturn int efx_sram_test( __in efx_nic_t *enp, __in efx_pattern_type_t type); #endif /* EFSYS_OPT_DIAG */ extern __checkReturn int efx_sram_buf_tbl_set( __in efx_nic_t *enp, __in uint32_t id, __in efsys_mem_t *esmp, __in size_t n); extern void efx_sram_buf_tbl_clear( __in efx_nic_t *enp, __in uint32_t id, __in size_t n); #define EFX_BUF_TBL_SIZE 0x20000 #define EFX_BUF_SIZE 4096 /* EV */ typedef struct efx_evq_s efx_evq_t; #if EFSYS_OPT_QSTATS /* START MKCONFIG GENERATED EfxHeaderEventQueueBlock 6f3843f5fe7cc843 */ typedef enum efx_ev_qstat_e { EV_ALL, EV_RX, EV_RX_OK, EV_RX_FRM_TRUNC, EV_RX_TOBE_DISC, EV_RX_PAUSE_FRM_ERR, EV_RX_BUF_OWNER_ID_ERR, EV_RX_IPV4_HDR_CHKSUM_ERR, EV_RX_TCP_UDP_CHKSUM_ERR, EV_RX_ETH_CRC_ERR, EV_RX_IP_FRAG_ERR, EV_RX_MCAST_PKT, EV_RX_MCAST_HASH_MATCH, EV_RX_TCP_IPV4, EV_RX_TCP_IPV6, EV_RX_UDP_IPV4, EV_RX_UDP_IPV6, EV_RX_OTHER_IPV4, EV_RX_OTHER_IPV6, EV_RX_NON_IP, EV_RX_BATCH, EV_TX, EV_TX_WQ_FF_FULL, EV_TX_PKT_ERR, EV_TX_PKT_TOO_BIG, EV_TX_UNEXPECTED, EV_GLOBAL, EV_GLOBAL_MNT, EV_DRIVER, EV_DRIVER_SRM_UPD_DONE, EV_DRIVER_TX_DESCQ_FLS_DONE, EV_DRIVER_RX_DESCQ_FLS_DONE, EV_DRIVER_RX_DESCQ_FLS_FAILED, EV_DRIVER_RX_DSC_ERROR, EV_DRIVER_TX_DSC_ERROR, EV_DRV_GEN, EV_MCDI_RESPONSE, EV_NQSTATS } efx_ev_qstat_t; /* END MKCONFIG GENERATED EfxHeaderEventQueueBlock */ #endif /* EFSYS_OPT_QSTATS */ extern __checkReturn int efx_ev_init( __in efx_nic_t *enp); extern void efx_ev_fini( __in efx_nic_t *enp); #define EFX_EVQ_MAXNEVS 32768 #define EFX_EVQ_MINNEVS 512 #define EFX_EVQ_SIZE(_nevs) ((_nevs) * sizeof (efx_qword_t)) #define EFX_EVQ_NBUFS(_nevs) (EFX_EVQ_SIZE(_nevs) / EFX_BUF_SIZE) extern __checkReturn int efx_ev_qcreate( __in efx_nic_t *enp, __in unsigned int index, __in efsys_mem_t *esmp, __in size_t n, __in uint32_t id, __deref_out efx_evq_t **eepp); extern void efx_ev_qpost( __in efx_evq_t *eep, __in uint16_t data); typedef __checkReturn boolean_t (*efx_initialized_ev_t)( __in_opt void *arg); #define EFX_PKT_UNICAST 0x0004 #define EFX_PKT_START 0x0008 #define EFX_PKT_VLAN_TAGGED 0x0010 #define EFX_CKSUM_TCPUDP 0x0020 #define EFX_CKSUM_IPV4 0x0040 #define EFX_PKT_CONT 0x0080 #define EFX_CHECK_VLAN 0x0100 #define EFX_PKT_TCP 0x0200 #define EFX_PKT_UDP 0x0400 #define EFX_PKT_IPV4 0x0800 #define EFX_PKT_IPV6 0x1000 #define EFX_PKT_PREFIX_LEN 0x2000 #define EFX_ADDR_MISMATCH 0x4000 #define EFX_DISCARD 0x8000 #define EFX_EV_RX_NLABELS 32 #define EFX_EV_TX_NLABELS 32 typedef __checkReturn boolean_t (*efx_rx_ev_t)( __in_opt void *arg, __in uint32_t label, __in uint32_t id, __in uint32_t size, __in uint16_t flags); typedef __checkReturn boolean_t (*efx_tx_ev_t)( __in_opt void *arg, __in uint32_t label, __in uint32_t id); #define EFX_EXCEPTION_RX_RECOVERY 0x00000001 #define EFX_EXCEPTION_RX_DSC_ERROR 0x00000002 #define EFX_EXCEPTION_TX_DSC_ERROR 0x00000003 #define EFX_EXCEPTION_UNKNOWN_SENSOREVT 0x00000004 #define EFX_EXCEPTION_FWALERT_SRAM 0x00000005 #define EFX_EXCEPTION_UNKNOWN_FWALERT 0x00000006 #define EFX_EXCEPTION_RX_ERROR 0x00000007 #define EFX_EXCEPTION_TX_ERROR 0x00000008 #define EFX_EXCEPTION_EV_ERROR 0x00000009 typedef __checkReturn boolean_t (*efx_exception_ev_t)( __in_opt void *arg, __in uint32_t label, __in uint32_t data); typedef __checkReturn boolean_t (*efx_rxq_flush_done_ev_t)( __in_opt void *arg, __in uint32_t rxq_index); typedef __checkReturn boolean_t (*efx_rxq_flush_failed_ev_t)( __in_opt void *arg, __in uint32_t rxq_index); typedef __checkReturn boolean_t (*efx_txq_flush_done_ev_t)( __in_opt void *arg, __in uint32_t txq_index); typedef __checkReturn boolean_t (*efx_software_ev_t)( __in_opt void *arg, __in uint16_t magic); typedef __checkReturn boolean_t (*efx_sram_ev_t)( __in_opt void *arg, __in uint32_t code); #define EFX_SRAM_CLEAR 0 #define EFX_SRAM_UPDATE 1 #define EFX_SRAM_ILLEGAL_CLEAR 2 typedef __checkReturn boolean_t (*efx_wake_up_ev_t)( __in_opt void *arg, __in uint32_t label); typedef __checkReturn boolean_t (*efx_timer_ev_t)( __in_opt void *arg, __in uint32_t label); typedef __checkReturn boolean_t (*efx_link_change_ev_t)( __in_opt void *arg, __in efx_link_mode_t link_mode); #if EFSYS_OPT_MON_STATS typedef __checkReturn boolean_t (*efx_monitor_ev_t)( __in_opt void *arg, __in efx_mon_stat_t id, __in efx_mon_stat_value_t value); #endif /* EFSYS_OPT_MON_STATS */ #if EFSYS_OPT_MAC_STATS typedef __checkReturn boolean_t (*efx_mac_stats_ev_t)( __in_opt void *arg, __in uint32_t generation ); #endif /* EFSYS_OPT_MAC_STATS */ typedef struct efx_ev_callbacks_s { efx_initialized_ev_t eec_initialized; efx_rx_ev_t eec_rx; efx_tx_ev_t eec_tx; efx_exception_ev_t eec_exception; efx_rxq_flush_done_ev_t eec_rxq_flush_done; efx_rxq_flush_failed_ev_t eec_rxq_flush_failed; efx_txq_flush_done_ev_t eec_txq_flush_done; efx_software_ev_t eec_software; efx_sram_ev_t eec_sram; efx_wake_up_ev_t eec_wake_up; efx_timer_ev_t eec_timer; efx_link_change_ev_t eec_link_change; #if EFSYS_OPT_MON_STATS efx_monitor_ev_t eec_monitor; #endif /* EFSYS_OPT_MON_STATS */ #if EFSYS_OPT_MAC_STATS efx_mac_stats_ev_t eec_mac_stats; #endif /* EFSYS_OPT_MAC_STATS */ } efx_ev_callbacks_t; extern __checkReturn boolean_t efx_ev_qpending( __in efx_evq_t *eep, __in unsigned int count); #if EFSYS_OPT_EV_PREFETCH extern void efx_ev_qprefetch( __in efx_evq_t *eep, __in unsigned int count); #endif /* EFSYS_OPT_EV_PREFETCH */ extern void efx_ev_qpoll( __in efx_evq_t *eep, __inout unsigned int *countp, __in const efx_ev_callbacks_t *eecp, __in_opt void *arg); extern __checkReturn int efx_ev_qmoderate( __in efx_evq_t *eep, __in unsigned int us); extern __checkReturn int efx_ev_qprime( __in efx_evq_t *eep, __in unsigned int count); #if EFSYS_OPT_QSTATS #if EFSYS_OPT_NAMES extern const char * efx_ev_qstat_name( __in efx_nic_t *enp, __in unsigned int id); #endif /* EFSYS_OPT_NAMES */ extern void efx_ev_qstats_update( __in efx_evq_t *eep, __inout_ecount(EV_NQSTATS) efsys_stat_t *stat); #endif /* EFSYS_OPT_QSTATS */ extern void efx_ev_qdestroy( __in efx_evq_t *eep); /* RX */ extern __checkReturn int efx_rx_init( __inout efx_nic_t *enp); extern void efx_rx_fini( __in efx_nic_t *enp); #if EFSYS_OPT_RX_HDR_SPLIT __checkReturn int efx_rx_hdr_split_enable( __in efx_nic_t *enp, __in unsigned int hdr_buf_size, __in unsigned int pld_buf_size); #endif /* EFSYS_OPT_RX_HDR_SPLIT */ #if EFSYS_OPT_RX_SCATTER __checkReturn int efx_rx_scatter_enable( __in efx_nic_t *enp, __in unsigned int buf_size); #endif /* EFSYS_OPT_RX_SCATTER */ #if EFSYS_OPT_RX_SCALE typedef enum efx_rx_hash_alg_e { EFX_RX_HASHALG_LFSR = 0, EFX_RX_HASHALG_TOEPLITZ } efx_rx_hash_alg_t; typedef enum efx_rx_hash_type_e { EFX_RX_HASH_IPV4 = 0, EFX_RX_HASH_TCPIPV4, EFX_RX_HASH_IPV6, EFX_RX_HASH_TCPIPV6, } efx_rx_hash_type_t; typedef enum efx_rx_hash_support_e { EFX_RX_HASH_UNAVAILABLE = 0, /* Hardware hash not inserted */ EFX_RX_HASH_AVAILABLE /* Insert hash with/without RSS */ } efx_rx_hash_support_t; #define EFX_RSS_TBL_SIZE 128 /* Rows in RX indirection table */ #define EFX_MAXRSS 64 /* RX indirection entry range */ #define EFX_MAXRSS_LEGACY 16 /* See bug16611 and bug17213 */ typedef enum efx_rx_scale_support_e { EFX_RX_SCALE_UNAVAILABLE = 0, /* Not supported */ EFX_RX_SCALE_EXCLUSIVE, /* Writable key/indirection table */ EFX_RX_SCALE_SHARED /* Read-only key/indirection table */ } efx_rx_scale_support_t; extern __checkReturn int efx_rx_hash_support_get( __in efx_nic_t *enp, __out efx_rx_hash_support_t *supportp); extern __checkReturn int efx_rx_scale_support_get( __in efx_nic_t *enp, __out efx_rx_scale_support_t *supportp); extern __checkReturn int efx_rx_scale_mode_set( __in efx_nic_t *enp, __in efx_rx_hash_alg_t alg, __in efx_rx_hash_type_t type, __in boolean_t insert); extern __checkReturn int efx_rx_scale_tbl_set( __in efx_nic_t *enp, __in_ecount(n) unsigned int *table, __in size_t n); extern __checkReturn int efx_rx_scale_key_set( __in efx_nic_t *enp, __in_ecount(n) uint8_t *key, __in size_t n); extern uint32_t efx_psuedo_hdr_hash_get( __in efx_nic_t *enp, __in efx_rx_hash_alg_t func, __in uint8_t *buffer); #endif /* EFSYS_OPT_RX_SCALE */ extern __checkReturn int efx_psuedo_hdr_pkt_length_get( __in efx_nic_t *enp, __in uint8_t *buffer, __out uint16_t *pkt_lengthp); #define EFX_RXQ_MAXNDESCS 4096 #define EFX_RXQ_MINNDESCS 512 #define EFX_RXQ_SIZE(_ndescs) ((_ndescs) * sizeof (efx_qword_t)) #define EFX_RXQ_NBUFS(_ndescs) (EFX_RXQ_SIZE(_ndescs) / EFX_BUF_SIZE) #define EFX_RXQ_LIMIT(_ndescs) ((_ndescs) - 16) #define EFX_RXQ_DC_NDESCS(_dcsize) (8 << _dcsize) typedef enum efx_rxq_type_e { EFX_RXQ_TYPE_DEFAULT, EFX_RXQ_TYPE_SPLIT_HEADER, EFX_RXQ_TYPE_SPLIT_PAYLOAD, EFX_RXQ_TYPE_SCATTER, EFX_RXQ_NTYPES } efx_rxq_type_t; extern __checkReturn int efx_rx_qcreate( __in efx_nic_t *enp, __in unsigned int index, __in unsigned int label, __in efx_rxq_type_t type, __in efsys_mem_t *esmp, __in size_t n, __in uint32_t id, __in efx_evq_t *eep, __deref_out efx_rxq_t **erpp); typedef struct efx_buffer_s { efsys_dma_addr_t eb_addr; size_t eb_size; boolean_t eb_eop; } efx_buffer_t; typedef struct efx_desc_s { efx_qword_t ed_eq; } efx_desc_t; extern void efx_rx_qpost( __in efx_rxq_t *erp, __in_ecount(n) efsys_dma_addr_t *addrp, __in size_t size, __in unsigned int n, __in unsigned int completed, __in unsigned int added); extern void efx_rx_qpush( __in efx_rxq_t *erp, __in unsigned int added, __inout unsigned int *pushedp); extern __checkReturn int efx_rx_qflush( __in efx_rxq_t *erp); extern void efx_rx_qenable( __in efx_rxq_t *erp); extern void efx_rx_qdestroy( __in efx_rxq_t *erp); /* TX */ typedef struct efx_txq_s efx_txq_t; #if EFSYS_OPT_QSTATS /* START MKCONFIG GENERATED EfxHeaderTransmitQueueBlock 12dff8778598b2db */ typedef enum efx_tx_qstat_e { TX_POST, TX_POST_PIO, TX_NQSTATS } efx_tx_qstat_t; /* END MKCONFIG GENERATED EfxHeaderTransmitQueueBlock */ #endif /* EFSYS_OPT_QSTATS */ extern __checkReturn int efx_tx_init( __in efx_nic_t *enp); extern void efx_tx_fini( __in efx_nic_t *enp); #define EFX_BUG35388_WORKAROUND(_encp) \ (((_encp) == NULL) ? 1 : ((_encp)->enc_bug35388_workaround != 0)) #define EFX_TXQ_MAXNDESCS(_encp) \ ((EFX_BUG35388_WORKAROUND(_encp)) ? 2048 : 4096) #define EFX_TXQ_MINNDESCS 512 #define EFX_TXQ_SIZE(_ndescs) ((_ndescs) * sizeof (efx_qword_t)) #define EFX_TXQ_NBUFS(_ndescs) (EFX_TXQ_SIZE(_ndescs) / EFX_BUF_SIZE) #define EFX_TXQ_LIMIT(_ndescs) ((_ndescs) - 16) #define EFX_TXQ_DC_NDESCS(_dcsize) (8 << _dcsize) #define EFX_TXQ_MAX_BUFS 8 /* Maximum independent of EFX_BUG35388_WORKAROUND. */ extern __checkReturn int efx_tx_qcreate( __in efx_nic_t *enp, __in unsigned int index, __in unsigned int label, __in efsys_mem_t *esmp, __in size_t n, __in uint32_t id, __in uint16_t flags, __in efx_evq_t *eep, __deref_out efx_txq_t **etpp, __out unsigned int *addedp); extern __checkReturn int efx_tx_qpost( __in efx_txq_t *etp, __in_ecount(n) efx_buffer_t *eb, __in unsigned int n, __in unsigned int completed, __inout unsigned int *addedp); extern __checkReturn int efx_tx_qpace( __in efx_txq_t *etp, __in unsigned int ns); extern void efx_tx_qpush( __in efx_txq_t *etp, __in unsigned int added, __in unsigned int pushed); extern __checkReturn int efx_tx_qflush( __in efx_txq_t *etp); extern void efx_tx_qenable( __in efx_txq_t *etp); extern __checkReturn int efx_tx_qpio_enable( __in efx_txq_t *etp); extern void efx_tx_qpio_disable( __in efx_txq_t *etp); extern __checkReturn int efx_tx_qpio_write( __in efx_txq_t *etp, __in_ecount(buf_length) uint8_t *buffer, __in size_t buf_length, __in size_t pio_buf_offset); extern __checkReturn int efx_tx_qpio_post( __in efx_txq_t *etp, __in size_t pkt_length, __in unsigned int completed, __inout unsigned int *addedp); extern __checkReturn int efx_tx_qdesc_post( __in efx_txq_t *etp, __in_ecount(n) efx_desc_t *ed, __in unsigned int n, __in unsigned int completed, __inout unsigned int *addedp); extern void efx_tx_qdesc_dma_create( __in efx_txq_t *etp, __in efsys_dma_addr_t addr, __in size_t size, __in boolean_t eop, __out efx_desc_t *edp); extern void efx_tx_qdesc_tso_create( __in efx_txq_t *etp, __in uint16_t ipv4_id, __in uint32_t tcp_seq, __in uint8_t tcp_flags, __out efx_desc_t *edp); extern void efx_tx_qdesc_vlantci_create( __in efx_txq_t *etp, __in uint16_t tci, __out efx_desc_t *edp); #if EFSYS_OPT_QSTATS #if EFSYS_OPT_NAMES extern const char * efx_tx_qstat_name( __in efx_nic_t *etp, __in unsigned int id); #endif /* EFSYS_OPT_NAMES */ extern void efx_tx_qstats_update( __in efx_txq_t *etp, __inout_ecount(TX_NQSTATS) efsys_stat_t *stat); #endif /* EFSYS_OPT_QSTATS */ extern void efx_tx_qdestroy( __in efx_txq_t *etp); /* FILTER */ #if EFSYS_OPT_FILTER #define EFX_ETHER_TYPE_IPV4 0x0800 #define EFX_ETHER_TYPE_IPV6 0x86DD #define EFX_IPPROTO_TCP 6 #define EFX_IPPROTO_UDP 17 typedef enum efx_filter_flag_e { EFX_FILTER_FLAG_RX_RSS = 0x01, /* use RSS to spread across * multiple queues */ EFX_FILTER_FLAG_RX_SCATTER = 0x02, /* enable RX scatter */ EFX_FILTER_FLAG_RX_OVER_AUTO = 0x04, /* Override an automatic filter * (priority EFX_FILTER_PRI_AUTO). * May only be set by the filter * implementation for each type. * A removal request will * restore the automatic filter * in its place. */ EFX_FILTER_FLAG_RX = 0x08, /* Filter is for RX */ EFX_FILTER_FLAG_TX = 0x10, /* Filter is for TX */ } efx_filter_flag_t; typedef enum efx_filter_match_flags_e { EFX_FILTER_MATCH_REM_HOST = 0x0001, /* Match by remote IP host * address */ EFX_FILTER_MATCH_LOC_HOST = 0x0002, /* Match by local IP host * address */ EFX_FILTER_MATCH_REM_MAC = 0x0004, /* Match by remote MAC address */ EFX_FILTER_MATCH_REM_PORT = 0x0008, /* Match by remote TCP/UDP port */ EFX_FILTER_MATCH_LOC_MAC = 0x0010, /* Match by remote TCP/UDP port */ EFX_FILTER_MATCH_LOC_PORT = 0x0020, /* Match by local TCP/UDP port */ EFX_FILTER_MATCH_ETHER_TYPE = 0x0040, /* Match by Ether-type */ EFX_FILTER_MATCH_INNER_VID = 0x0080, /* Match by inner VLAN ID */ EFX_FILTER_MATCH_OUTER_VID = 0x0100, /* Match by outer VLAN ID */ EFX_FILTER_MATCH_IP_PROTO = 0x0200, /* Match by IP transport * protocol */ EFX_FILTER_MATCH_LOC_MAC_IG = 0x0400, /* Match by local MAC address * I/G bit. Used for RX default * unicast and multicast/ * broadcast filters. */ } efx_filter_match_flags_t; typedef enum efx_filter_priority_s { EFX_FILTER_PRI_HINT = 0, /* Performance hint */ EFX_FILTER_PRI_AUTO, /* Automatic filter based on device * address list or hardware * requirements. This may only be used * by the filter implementation for * each NIC type. */ EFX_FILTER_PRI_MANUAL, /* Manually configured filter */ EFX_FILTER_PRI_REQUIRED, /* Required for correct behaviour of the * client (e.g. SR-IOV, HyperV VMQ etc.) */ } efx_filter_priority_t; /* * FIXME: All these fields are assumed to be in little-endian byte order. * It may be better for some to be big-endian. See bug42804. */ typedef struct efx_filter_spec_s { uint32_t efs_match_flags:12; uint32_t efs_priority:2; uint32_t efs_flags:6; uint32_t efs_dmaq_id:12; uint32_t efs_rss_context; uint16_t efs_outer_vid; uint16_t efs_inner_vid; uint8_t efs_loc_mac[EFX_MAC_ADDR_LEN]; uint8_t efs_rem_mac[EFX_MAC_ADDR_LEN]; uint16_t efs_ether_type; uint8_t efs_ip_proto; uint16_t efs_loc_port; uint16_t efs_rem_port; efx_oword_t efs_rem_host; efx_oword_t efs_loc_host; } efx_filter_spec_t; /* Default values for use in filter specifications */ #define EFX_FILTER_SPEC_RSS_CONTEXT_DEFAULT 0xffffffff #define EFX_FILTER_SPEC_RX_DMAQ_ID_DROP 0xfff #define EFX_FILTER_SPEC_VID_UNSPEC 0xffff extern __checkReturn int efx_filter_init( __in efx_nic_t *enp); extern void efx_filter_fini( __in efx_nic_t *enp); extern __checkReturn int efx_filter_insert( __in efx_nic_t *enp, __inout efx_filter_spec_t *spec); extern __checkReturn int efx_filter_remove( __in efx_nic_t *enp, __inout efx_filter_spec_t *spec); extern __checkReturn int efx_filter_restore( __in efx_nic_t *enp); extern __checkReturn int efx_filter_supported_filters( __in efx_nic_t *enp, __out uint32_t *list, __out size_t *length); extern void efx_filter_spec_init_rx( __inout efx_filter_spec_t *spec, __in efx_filter_priority_t priority, __in efx_filter_flag_t flags, __in efx_rxq_t *erp); extern void efx_filter_spec_init_tx( __inout efx_filter_spec_t *spec, __in efx_txq_t *etp); extern __checkReturn int efx_filter_spec_set_ipv4_local( __inout efx_filter_spec_t *spec, __in uint8_t proto, __in uint32_t host, __in uint16_t port); extern __checkReturn int efx_filter_spec_set_ipv4_full( __inout efx_filter_spec_t *spec, __in uint8_t proto, __in uint32_t lhost, __in uint16_t lport, __in uint32_t rhost, __in uint16_t rport); extern __checkReturn int efx_filter_spec_set_eth_local( __inout efx_filter_spec_t *spec, __in uint16_t vid, __in const uint8_t *addr); extern __checkReturn int efx_filter_spec_set_uc_def( __inout efx_filter_spec_t *spec); extern __checkReturn int efx_filter_spec_set_mc_def( __inout efx_filter_spec_t *spec); #endif /* EFSYS_OPT_FILTER */ /* HASH */ extern __checkReturn uint32_t efx_hash_dwords( __in_ecount(count) uint32_t const *input, __in size_t count, __in uint32_t init); extern __checkReturn uint32_t efx_hash_bytes( __in_ecount(length) uint8_t const *input, __in size_t length, __in uint32_t init); #ifdef __cplusplus } #endif #endif /* _SYS_EFX_H */ Index: head/sys/dev/sfxge/common/efx_mon.c =================================================================== --- head/sys/dev/sfxge/common/efx_mon.c (revision 291394) +++ head/sys/dev/sfxge/common/efx_mon.c (revision 291395) @@ -1,346 +1,346 @@ /*- * Copyright (c) 2007-2015 Solarflare Communications Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the FreeBSD Project. */ #include __FBSDID("$FreeBSD$"); #include "efsys.h" #include "efx.h" #include "efx_types.h" #include "efx_regs.h" #include "efx_impl.h" #if EFSYS_OPT_MON_NULL #include "nullmon.h" #endif #if EFSYS_OPT_MON_LM87 #include "lm87.h" #endif #if EFSYS_OPT_MON_MAX6647 #include "max6647.h" #endif #if EFSYS_OPT_MON_MCDI #include "mcdi_mon.h" #endif #if EFSYS_OPT_NAMES static const char *__efx_mon_name[] = { "", "nullmon", "lm87", "max6647", "sfx90x0", "sfx91x0" }; const char * efx_mon_name( __in efx_nic_t *enp) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT(encp->enc_mon_type != EFX_MON_INVALID); EFSYS_ASSERT3U(encp->enc_mon_type, <, EFX_MON_NTYPES); return (__efx_mon_name[encp->enc_mon_type]); } #endif /* EFSYS_OPT_NAMES */ #if EFSYS_OPT_MON_NULL static efx_mon_ops_t __efx_mon_null_ops = { nullmon_reset, /* emo_reset */ nullmon_reconfigure, /* emo_reconfigure */ #if EFSYS_OPT_MON_STATS nullmon_stats_update /* emo_stats_update */ #endif /* EFSYS_OPT_MON_STATS */ }; #endif #if EFSYS_OPT_MON_LM87 static efx_mon_ops_t __efx_mon_lm87_ops = { lm87_reset, /* emo_reset */ lm87_reconfigure, /* emo_reconfigure */ #if EFSYS_OPT_MON_STATS lm87_stats_update /* emo_stats_update */ #endif /* EFSYS_OPT_MON_STATS */ }; #endif #if EFSYS_OPT_MON_MAX6647 static efx_mon_ops_t __efx_mon_max6647_ops = { max6647_reset, /* emo_reset */ max6647_reconfigure, /* emo_reconfigure */ #if EFSYS_OPT_MON_STATS max6647_stats_update /* emo_stats_update */ #endif /* EFSYS_OPT_MON_STATS */ }; #endif #if EFSYS_OPT_MON_MCDI static efx_mon_ops_t __efx_mon_mcdi_ops = { NULL, /* emo_reset */ NULL, /* emo_reconfigure */ #if EFSYS_OPT_MON_STATS mcdi_mon_stats_update /* emo_stats_update */ #endif /* EFSYS_OPT_MON_STATS */ }; #endif static efx_mon_ops_t *__efx_mon_ops[] = { NULL, #if EFSYS_OPT_MON_NULL &__efx_mon_null_ops, #else NULL, #endif #if EFSYS_OPT_MON_LM87 &__efx_mon_lm87_ops, #else NULL, #endif #if EFSYS_OPT_MON_MAX6647 &__efx_mon_max6647_ops, #else NULL, #endif #if EFSYS_OPT_MON_MCDI &__efx_mon_mcdi_ops, #else NULL, #endif #if EFSYS_OPT_MON_MCDI &__efx_mon_mcdi_ops #else NULL #endif }; __checkReturn int efx_mon_init( __in efx_nic_t *enp) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); efx_mon_t *emp = &(enp->en_mon); efx_mon_ops_t *emop; int rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); if (enp->en_mod_flags & EFX_MOD_MON) { rc = EINVAL; goto fail1; } enp->en_mod_flags |= EFX_MOD_MON; emp->em_type = encp->enc_mon_type; EFSYS_ASSERT(encp->enc_mon_type != EFX_MON_INVALID); EFSYS_ASSERT3U(emp->em_type, <, EFX_MON_NTYPES); if ((emop = (efx_mon_ops_t *)__efx_mon_ops[emp->em_type]) == NULL) { rc = ENOTSUP; goto fail2; } if (emop->emo_reset != NULL) { if ((rc = emop->emo_reset(enp)) != 0) goto fail3; } if (emop->emo_reconfigure != NULL) { if ((rc = emop->emo_reconfigure(enp)) != 0) goto fail4; } emp->em_emop = emop; return (0); fail4: EFSYS_PROBE(fail5); if (emop->emo_reset != NULL) (void) emop->emo_reset(enp); fail3: EFSYS_PROBE(fail4); fail2: EFSYS_PROBE(fail3); emp->em_type = EFX_MON_INVALID; enp->en_mod_flags &= ~EFX_MOD_MON; fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } #if EFSYS_OPT_MON_STATS #if EFSYS_OPT_NAMES /* START MKCONFIG GENERATED MonitorStatNamesBlock b9328f15438c4d01 */ static const char *__mon_stat_name[] = { "value_2_5v", "value_vccp1", "value_vcc", "value_5v", "value_12v", "value_vccp2", "value_ext_temp", "value_int_temp", "value_ain1", "value_ain2", "controller_cooling", "ext_cooling", "1v", "1_2v", "1_8v", "3_3v", "1_2va", "vref", "vaoe", "aoe_temperature", "psu_aoe_temperature", "psu_temperature", "fan0", "fan1", "fan2", "fan3", "fan4", "vaoe_in", "iaoe", "iaoe_in", "nic_power", "0_9v", "i0_9v", "i1_2v", "0_9v_adc", "controller_temperature2", "vreg_temperature", "vreg_0_9v_temperature", "vreg_1_2v_temperature", "int_vptat", "controller_internal_adc_temperature", "ext_vptat", "controller_external_adc_temperature", "ambient_temperature", "airflow", "vdd08d_vss08d_csr", "vdd08d_vss08d_csr_extadc", "hotpoint_temperature", "phy_power_switch_port0", "phy_power_switch_port1", "mum_vcc", "0v9_a", "i0v9_a", "0v9_a_temp", "0v9_b", "i0v9_b", "0v9_b_temp", "ccom_avreg_1v2_supply", "ccom_avreg_1v2_supply_ext_adc", "ccom_avreg_1v8_supply", "ccom_avreg_1v8_supply_ext_adc", "controller_master_vptat", "controller_master_internal_temp", "controller_master_vptat_ext_adc", "controller_master_internal_temp_ext_adc", "controller_slave_vptat", "controller_slave_internal_temp", "controller_slave_vptat_ext_adc", "controller_slave_internal_temp_ext_adc", }; /* END MKCONFIG GENERATED MonitorStatNamesBlock */ extern const char * efx_mon_stat_name( __in efx_nic_t *enp, __in efx_mon_stat_t id) { _NOTE(ARGUNUSED(enp)) EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(id, <, EFX_MON_NSTATS); return (__mon_stat_name[id]); } #endif /* EFSYS_OPT_NAMES */ __checkReturn int efx_mon_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values) + __inout_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values) { efx_mon_t *emp = &(enp->en_mon); efx_mon_ops_t *emop = emp->em_emop; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MON); return (emop->emo_stats_update(enp, esmp, values)); } #endif /* EFSYS_OPT_MON_STATS */ void efx_mon_fini( __in efx_nic_t *enp) { efx_mon_t *emp = &(enp->en_mon); efx_mon_ops_t *emop = emp->em_emop; int rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MON); emp->em_emop = NULL; if (emop->emo_reset != NULL) { rc = emop->emo_reset(enp); if (rc != 0) EFSYS_PROBE1(fail1, int, rc); } emp->em_type = EFX_MON_INVALID; enp->en_mod_flags &= ~EFX_MOD_MON; } Index: head/sys/dev/sfxge/common/efx_phy.c =================================================================== --- head/sys/dev/sfxge/common/efx_phy.c (revision 291394) +++ head/sys/dev/sfxge/common/efx_phy.c (revision 291395) @@ -1,839 +1,839 @@ /*- * Copyright (c) 2007-2015 Solarflare Communications Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the FreeBSD Project. */ #include __FBSDID("$FreeBSD$"); #include "efsys.h" #include "efx.h" #include "efx_types.h" #include "efx_regs.h" #include "efx_impl.h" #if EFSYS_OPT_FALCON #include "falcon_nvram.h" #endif #if EFSYS_OPT_MAC_FALCON_XMAC #include "falcon_xmac.h" #endif #if EFSYS_OPT_MAC_FALCON_GMAC #include "falcon_gmac.h" #endif #if EFSYS_OPT_PHY_NULL #include "nullphy.h" #endif #if EFSYS_OPT_PHY_QT2022C2 #include "qt2022c2.h" #endif #if EFSYS_OPT_PHY_SFX7101 #include "sfx7101.h" #endif #if EFSYS_OPT_PHY_TXC43128 #include "txc43128.h" #endif #if EFSYS_OPT_PHY_SFT9001 #include "sft9001.h" #endif #if EFSYS_OPT_PHY_QT2025C #include "qt2025c.h" #endif #if EFSYS_OPT_PHY_NULL static efx_phy_ops_t __efx_phy_null_ops = { NULL, /* epo_power */ nullphy_reset, /* epo_reset */ nullphy_reconfigure, /* epo_reconfigure */ nullphy_verify, /* epo_verify */ NULL, /* epo_uplink_check */ nullphy_downlink_check, /* epo_downlink_check */ nullphy_oui_get, /* epo_oui_get */ #if EFSYS_OPT_PHY_STATS nullphy_stats_update, /* epo_stats_update */ #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES nullphy_prop_name, /* epo_prop_name */ #endif nullphy_prop_get, /* epo_prop_get */ nullphy_prop_set, /* epo_prop_set */ #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_BIST NULL, /* epo_bist_enable_offline */ NULL, /* epo_bist_start */ NULL, /* epo_bist_poll */ NULL, /* epo_bist_stop */ #endif /* EFSYS_OPT_BIST */ }; #endif /* EFSYS_OPT_PHY_NULL */ #if EFSYS_OPT_PHY_QT2022C2 static efx_phy_ops_t __efx_phy_qt2022c2_ops = { NULL, /* epo_power */ qt2022c2_reset, /* epo_reset */ qt2022c2_reconfigure, /* epo_reconfigure */ qt2022c2_verify, /* epo_verify */ qt2022c2_uplink_check, /* epo_uplink_check */ qt2022c2_downlink_check, /* epo_downlink_check */ qt2022c2_oui_get, /* epo_oui_get */ #if EFSYS_OPT_PHY_STATS qt2022c2_stats_update, /* epo_stats_update */ #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES qt2022c2_prop_name, /* epo_prop_name */ #endif qt2022c2_prop_get, /* epo_prop_get */ qt2022c2_prop_set, /* epo_prop_set */ #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_BIST NULL, /* epo_bist_enable_offline */ NULL, /* epo_bist_start */ NULL, /* epo_bist_poll */ NULL, /* epo_bist_stop */ #endif /* EFSYS_OPT_BIST */ }; #endif /* EFSYS_OPT_PHY_QT2022C2 */ #if EFSYS_OPT_PHY_SFX7101 static efx_phy_ops_t __efx_phy_sfx7101_ops = { sfx7101_power, /* epo_power */ sfx7101_reset, /* epo_reset */ sfx7101_reconfigure, /* epo_reconfigure */ sfx7101_verify, /* epo_verify */ sfx7101_uplink_check, /* epo_uplink_check */ sfx7101_downlink_check, /* epo_downlink_check */ sfx7101_oui_get, /* epo_oui_get */ #if EFSYS_OPT_PHY_STATS sfx7101_stats_update, /* epo_stats_update */ #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES sfx7101_prop_name, /* epo_prop_name */ #endif sfx7101_prop_get, /* epo_prop_get */ sfx7101_prop_set, /* epo_prop_set */ #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_BIST NULL, /* epo_bist_enable_offline */ NULL, /* epo_bist_start */ NULL, /* epo_bist_poll */ NULL, /* epo_bist_stop */ #endif /* EFSYS_OPT_BIST */ }; #endif /* EFSYS_OPT_PHY_SFX7101 */ #if EFSYS_OPT_PHY_TXC43128 static efx_phy_ops_t __efx_phy_txc43128_ops = { NULL, /* epo_power */ txc43128_reset, /* epo_reset */ txc43128_reconfigure, /* epo_reconfigure */ txc43128_verify, /* epo_verify */ txc43128_uplink_check, /* epo_uplink_check */ txc43128_downlink_check, /* epo_downlink_check */ txc43128_oui_get, /* epo_oui_get */ #if EFSYS_OPT_PHY_STATS txc43128_stats_update, /* epo_stats_update */ #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES txc43128_prop_name, /* epo_prop_name */ #endif txc43128_prop_get, /* epo_prop_get */ txc43128_prop_set, /* epo_prop_set */ #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_BIST NULL, /* epo_bist_enable_offline */ NULL, /* epo_bist_start */ NULL, /* epo_bist_poll */ NULL, /* epo_bist_stop */ #endif /* EFSYS_OPT_BIST */ }; #endif /* EFSYS_OPT_PHY_TXC43128 */ #if EFSYS_OPT_PHY_SFT9001 static efx_phy_ops_t __efx_phy_sft9001_ops = { NULL, /* epo_power */ sft9001_reset, /* epo_reset */ sft9001_reconfigure, /* epo_reconfigure */ sft9001_verify, /* epo_verify */ sft9001_uplink_check, /* epo_uplink_check */ sft9001_downlink_check, /* epo_downlink_check */ sft9001_oui_get, /* epo_oui_get */ #if EFSYS_OPT_PHY_STATS sft9001_stats_update, /* epo_stats_update */ #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES sft9001_prop_name, /* epo_prop_name */ #endif sft9001_prop_get, /* epo_prop_get */ sft9001_prop_set, /* epo_prop_set */ #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_BIST NULL, /* epo_bist_enable_offline */ sft9001_bist_start, /* epo_bist_start */ sft9001_bist_poll, /* epo_bist_poll */ sft9001_bist_stop, /* epo_bist_stop */ #endif /* EFSYS_OPT_BIST */ }; #endif /* EFSYS_OPT_PHY_SFT9001 */ #if EFSYS_OPT_PHY_QT2025C static efx_phy_ops_t __efx_phy_qt2025c_ops = { NULL, /* epo_power */ qt2025c_reset, /* epo_reset */ qt2025c_reconfigure, /* epo_reconfigure */ qt2025c_verify, /* epo_verify */ qt2025c_uplink_check, /* epo_uplink_check */ qt2025c_downlink_check, /* epo_downlink_check */ qt2025c_oui_get, /* epo_oui_get */ #if EFSYS_OPT_PHY_STATS qt2025c_stats_update, /* epo_stats_update */ #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES qt2025c_prop_name, /* epo_prop_name */ #endif qt2025c_prop_get, /* epo_prop_get */ qt2025c_prop_set, /* epo_prop_set */ #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_BIST NULL, /* epo_bist_enable_offline */ NULL, /* epo_bist_start */ NULL, /* epo_bist_poll */ NULL, /* epo_bist_stop */ #endif /* EFSYS_OPT_BIST */ }; #endif /* EFSYS_OPT_PHY_QT2025C */ #if EFSYS_OPT_SIENA static efx_phy_ops_t __efx_phy_siena_ops = { siena_phy_power, /* epo_power */ NULL, /* epo_reset */ siena_phy_reconfigure, /* epo_reconfigure */ siena_phy_verify, /* epo_verify */ NULL, /* epo_uplink_check */ NULL, /* epo_downlink_check */ siena_phy_oui_get, /* epo_oui_get */ #if EFSYS_OPT_PHY_STATS siena_phy_stats_update, /* epo_stats_update */ #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES siena_phy_prop_name, /* epo_prop_name */ #endif siena_phy_prop_get, /* epo_prop_get */ siena_phy_prop_set, /* epo_prop_set */ #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_BIST NULL, /* epo_bist_enable_offline */ siena_phy_bist_start, /* epo_bist_start */ siena_phy_bist_poll, /* epo_bist_poll */ siena_phy_bist_stop, /* epo_bist_stop */ #endif /* EFSYS_OPT_BIST */ }; #endif /* EFSYS_OPT_SIENA */ #if EFSYS_OPT_HUNTINGTON static efx_phy_ops_t __efx_phy_hunt_ops = { hunt_phy_power, /* epo_power */ NULL, /* epo_reset */ hunt_phy_reconfigure, /* epo_reconfigure */ hunt_phy_verify, /* epo_verify */ NULL, /* epo_uplink_check */ NULL, /* epo_downlink_check */ hunt_phy_oui_get, /* epo_oui_get */ #if EFSYS_OPT_PHY_STATS hunt_phy_stats_update, /* epo_stats_update */ #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES hunt_phy_prop_name, /* epo_prop_name */ #endif hunt_phy_prop_get, /* epo_prop_get */ hunt_phy_prop_set, /* epo_prop_set */ #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_BIST hunt_bist_enable_offline, /* epo_bist_enable_offline */ hunt_bist_start, /* epo_bist_start */ hunt_bist_poll, /* epo_bist_poll */ hunt_bist_stop, /* epo_bist_stop */ #endif /* EFSYS_OPT_BIST */ }; #endif /* EFSYS_OPT_HUNTINGTON */ __checkReturn int efx_phy_probe( __in efx_nic_t *enp) { efx_port_t *epp = &(enp->en_port); efx_nic_cfg_t *encp = &(enp->en_nic_cfg); efx_phy_ops_t *epop; int rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); epp->ep_port = encp->enc_port; epp->ep_phy_type = encp->enc_phy_type; /* Hook in operations structure */ switch (enp->en_family) { #if EFSYS_OPT_FALCON case EFX_FAMILY_FALCON: switch (epp->ep_phy_type) { #if EFSYS_OPT_PHY_NULL case PHY_TYPE_NONE_DECODE: epop = (efx_phy_ops_t *)&__efx_phy_null_ops; break; #endif #if EFSYS_OPT_PHY_QT2022C2 case PHY_TYPE_QT2022C2_DECODE: epop = (efx_phy_ops_t *)&__efx_phy_qt2022c2_ops; break; #endif #if EFSYS_OPT_PHY_SFX7101 case PHY_TYPE_SFX7101_DECODE: epop = (efx_phy_ops_t *)&__efx_phy_sfx7101_ops; break; #endif #if EFSYS_OPT_PHY_TXC43128 case PHY_TYPE_TXC43128_DECODE: epop = (efx_phy_ops_t *)&__efx_phy_txc43128_ops; break; #endif #if EFSYS_OPT_PHY_SFT9001 case PHY_TYPE_SFT9001A_DECODE: case PHY_TYPE_SFT9001B_DECODE: epop = (efx_phy_ops_t *)&__efx_phy_sft9001_ops; break; #endif #if EFSYS_OPT_PHY_QT2025C case EFX_PHY_QT2025C: epop = (efx_phy_ops_t *)&__efx_phy_qt2025c_ops; break; #endif default: rc = ENOTSUP; goto fail1; } break; #endif /* EFSYS_OPT_FALCON */ #if EFSYS_OPT_SIENA case EFX_FAMILY_SIENA: epop = (efx_phy_ops_t *)&__efx_phy_siena_ops; break; #endif /* EFSYS_OPT_SIENA */ #if EFSYS_OPT_HUNTINGTON case EFX_FAMILY_HUNTINGTON: epop = (efx_phy_ops_t *)&__efx_phy_hunt_ops; break; #endif /* EFSYS_OPT_HUNTINGTON */ default: rc = ENOTSUP; goto fail1; } epp->ep_epop = epop; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); epp->ep_port = 0; epp->ep_phy_type = 0; return (rc); } __checkReturn int efx_phy_verify( __in efx_nic_t *enp) { efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); return (epop->epo_verify(enp)); } #if EFSYS_OPT_PHY_LED_CONTROL __checkReturn int efx_phy_led_set( __in efx_nic_t *enp, __in efx_phy_led_mode_t mode) { efx_nic_cfg_t *encp = (&enp->en_nic_cfg); efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; uint32_t mask; int rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); if (epp->ep_phy_led_mode == mode) goto done; mask = (1 << EFX_PHY_LED_DEFAULT); mask |= encp->enc_led_mask; if (!((1 << mode) & mask)) { rc = ENOTSUP; goto fail1; } EFSYS_ASSERT3U(mode, <, EFX_PHY_LED_NMODES); epp->ep_phy_led_mode = mode; if ((rc = epop->epo_reconfigure(enp)) != 0) goto fail2; done: return (0); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } #endif /* EFSYS_OPT_PHY_LED_CONTROL */ void efx_phy_adv_cap_get( __in efx_nic_t *enp, __in uint32_t flag, __out uint32_t *maskp) { efx_port_t *epp = &(enp->en_port); EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); switch (flag) { case EFX_PHY_CAP_CURRENT: *maskp = epp->ep_adv_cap_mask; break; case EFX_PHY_CAP_DEFAULT: *maskp = epp->ep_default_adv_cap_mask; break; case EFX_PHY_CAP_PERM: *maskp = epp->ep_phy_cap_mask; break; default: EFSYS_ASSERT(B_FALSE); break; } } __checkReturn int efx_phy_adv_cap_set( __in efx_nic_t *enp, __in uint32_t mask) { efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; uint32_t old_mask; int rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); if ((mask & ~epp->ep_phy_cap_mask) != 0) { rc = ENOTSUP; goto fail1; } if (epp->ep_adv_cap_mask == mask) goto done; old_mask = epp->ep_adv_cap_mask; epp->ep_adv_cap_mask = mask; if ((rc = epop->epo_reconfigure(enp)) != 0) goto fail2; done: return (0); fail2: EFSYS_PROBE(fail2); epp->ep_adv_cap_mask = old_mask; /* Reconfigure for robustness */ if (epop->epo_reconfigure(enp) != 0) { /* * We may have an inconsistent view of our advertised speed * capabilities. */ EFSYS_ASSERT(0); } fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } void efx_phy_lp_cap_get( __in efx_nic_t *enp, __out uint32_t *maskp) { efx_port_t *epp = &(enp->en_port); EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); *maskp = epp->ep_lp_cap_mask; } __checkReturn int efx_phy_oui_get( __in efx_nic_t *enp, __out uint32_t *ouip) { efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); return (epop->epo_oui_get(enp, ouip)); } void efx_phy_media_type_get( __in efx_nic_t *enp, __out efx_phy_media_type_t *typep) { efx_port_t *epp = &(enp->en_port); EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID) *typep = epp->ep_module_type; else *typep = epp->ep_fixed_port_type; } #if EFSYS_OPT_PHY_STATS #if EFSYS_OPT_NAMES /* START MKCONFIG GENERATED PhyStatNamesBlock d5f79b4bc2c050fe */ static const char *__efx_phy_stat_name[] = { "oui", "pma_pmd_link_up", "pma_pmd_rx_fault", "pma_pmd_tx_fault", "pma_pmd_rev_a", "pma_pmd_rev_b", "pma_pmd_rev_c", "pma_pmd_rev_d", "pcs_link_up", "pcs_rx_fault", "pcs_tx_fault", "pcs_ber", "pcs_block_errors", "phy_xs_link_up", "phy_xs_rx_fault", "phy_xs_tx_fault", "phy_xs_align", "phy_xs_sync_a", "phy_xs_sync_b", "phy_xs_sync_c", "phy_xs_sync_d", "an_link_up", "an_master", "an_local_rx_ok", "an_remote_rx_ok", "cl22ext_link_up", "snr_a", "snr_b", "snr_c", "snr_d", "pma_pmd_signal_a", "pma_pmd_signal_b", "pma_pmd_signal_c", "pma_pmd_signal_d", "an_complete", "pma_pmd_rev_major", "pma_pmd_rev_minor", "pma_pmd_rev_micro", "pcs_fw_version_0", "pcs_fw_version_1", "pcs_fw_version_2", "pcs_fw_version_3", "pcs_fw_build_yy", "pcs_fw_build_mm", "pcs_fw_build_dd", "pcs_op_mode", }; /* END MKCONFIG GENERATED PhyStatNamesBlock */ const char * efx_phy_stat_name( __in efx_nic_t *enp, __in efx_phy_stat_t type) { _NOTE(ARGUNUSED(enp)) EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS); return (__efx_phy_stat_name[type]); } #endif /* EFSYS_OPT_NAMES */ __checkReturn int efx_phy_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __out_ecount(EFX_PHY_NSTATS) uint32_t *stat) + __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat) { efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); return (epop->epo_stats_update(enp, esmp, stat)); } #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES const char * efx_phy_prop_name( __in efx_nic_t *enp, __in unsigned int id) { efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); return (epop->epo_prop_name(enp, id)); } #endif /* EFSYS_OPT_NAMES */ __checkReturn int efx_phy_prop_get( __in efx_nic_t *enp, __in unsigned int id, __in uint32_t flags, __out uint32_t *valp) { efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); return (epop->epo_prop_get(enp, id, flags, valp)); } __checkReturn int efx_phy_prop_set( __in efx_nic_t *enp, __in unsigned int id, __in uint32_t val) { efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); return (epop->epo_prop_set(enp, id, val)); } #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_BIST __checkReturn int efx_bist_enable_offline( __in efx_nic_t *enp) { efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; int rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); if (epop->epo_bist_enable_offline == NULL) { rc = ENOTSUP; goto fail1; } if ((rc = epop->epo_bist_enable_offline(enp)) != 0) goto fail2; return (0); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int efx_bist_start( __in efx_nic_t *enp, __in efx_bist_type_t type) { efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; int rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN); EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES); EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_BIST_TYPE_UNKNOWN); if (epop->epo_bist_start == NULL) { rc = ENOTSUP; goto fail1; } if ((rc = epop->epo_bist_start(enp, type)) != 0) goto fail2; epp->ep_current_bist = type; return (0); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int efx_bist_poll( __in efx_nic_t *enp, __in efx_bist_type_t type, __out efx_bist_result_t *resultp, __out_opt uint32_t *value_maskp, __out_ecount_opt(count) unsigned long *valuesp, __in size_t count) { efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; int rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN); EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES); EFSYS_ASSERT3U(epp->ep_current_bist, ==, type); EFSYS_ASSERT(epop->epo_bist_poll != NULL); if (epop->epo_bist_poll == NULL) { rc = ENOTSUP; goto fail1; } if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp, valuesp, count)) != 0) goto fail2; return (0); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } void efx_bist_stop( __in efx_nic_t *enp, __in efx_bist_type_t type) { efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN); EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES); EFSYS_ASSERT3U(epp->ep_current_bist, ==, type); EFSYS_ASSERT(epop->epo_bist_stop != NULL); if (epop->epo_bist_stop != NULL) epop->epo_bist_stop(enp, type); epp->ep_current_bist = EFX_BIST_TYPE_UNKNOWN; } #endif /* EFSYS_OPT_BIST */ void efx_phy_unprobe( __in efx_nic_t *enp) { efx_port_t *epp = &(enp->en_port); EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); epp->ep_epop = NULL; epp->ep_adv_cap_mask = 0; epp->ep_port = 0; epp->ep_phy_type = 0; } Index: head/sys/dev/sfxge/common/hunt_impl.h =================================================================== --- head/sys/dev/sfxge/common/hunt_impl.h (revision 291394) +++ head/sys/dev/sfxge/common/hunt_impl.h (revision 291395) @@ -1,1030 +1,1030 @@ /*- * Copyright (c) 2012-2015 Solarflare Communications Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the FreeBSD Project. * * $FreeBSD$ */ #ifndef _SYS_HUNT_IMPL_H #define _SYS_HUNT_IMPL_H #include "efx.h" #include "efx_regs.h" #include "efx_regs_ef10.h" #include "efx_mcdi.h" #ifdef __cplusplus extern "C" { #endif #define HUNTINGTON_NVRAM_CHUNK 0x80 /* Alignment requirement for value written to RX WPTR: * the WPTR must be aligned to an 8 descriptor boundary */ #define HUNTINGTON_RX_WPTR_ALIGN 8 /* Invalid RSS context handle */ #define HUNTINGTON_RSS_CONTEXT_INVALID (0xffffffff) /* EV */ __checkReturn int hunt_ev_init( __in efx_nic_t *enp); void hunt_ev_fini( __in efx_nic_t *enp); __checkReturn int hunt_ev_qcreate( __in efx_nic_t *enp, __in unsigned int index, __in efsys_mem_t *esmp, __in size_t n, __in uint32_t id, __in efx_evq_t *eep); void hunt_ev_qdestroy( __in efx_evq_t *eep); __checkReturn int hunt_ev_qprime( __in efx_evq_t *eep, __in unsigned int count); void hunt_ev_qpost( __in efx_evq_t *eep, __in uint16_t data); __checkReturn int hunt_ev_qmoderate( __in efx_evq_t *eep, __in unsigned int us); #if EFSYS_OPT_QSTATS void hunt_ev_qstats_update( __in efx_evq_t *eep, __inout_ecount(EV_NQSTATS) efsys_stat_t *stat); #endif /* EFSYS_OPT_QSTATS */ void hunt_ev_rxlabel_init( __in efx_evq_t *eep, __in efx_rxq_t *erp, __in unsigned int label); void hunt_ev_rxlabel_fini( __in efx_evq_t *eep, __in unsigned int label); /* INTR */ __checkReturn int hunt_intr_init( __in efx_nic_t *enp, __in efx_intr_type_t type, __in efsys_mem_t *esmp); void hunt_intr_enable( __in efx_nic_t *enp); void hunt_intr_disable( __in efx_nic_t *enp); void hunt_intr_disable_unlocked( __in efx_nic_t *enp); __checkReturn int hunt_intr_trigger( __in efx_nic_t *enp, __in unsigned int level); void hunt_intr_fini( __in efx_nic_t *enp); /* NIC */ extern __checkReturn int hunt_nic_probe( __in efx_nic_t *enp); extern __checkReturn int hunt_nic_set_drv_limits( __inout efx_nic_t *enp, __in efx_drv_limits_t *edlp); extern __checkReturn int hunt_nic_get_vi_pool( __in efx_nic_t *enp, __out uint32_t *vi_countp); extern __checkReturn int hunt_nic_get_bar_region( __in efx_nic_t *enp, __in efx_nic_region_t region, __out uint32_t *offsetp, __out size_t *sizep); extern __checkReturn int hunt_nic_reset( __in efx_nic_t *enp); extern __checkReturn int hunt_nic_init( __in efx_nic_t *enp); #if EFSYS_OPT_DIAG extern __checkReturn int hunt_nic_register_test( __in efx_nic_t *enp); #endif /* EFSYS_OPT_DIAG */ extern void hunt_nic_fini( __in efx_nic_t *enp); extern void hunt_nic_unprobe( __in efx_nic_t *enp); /* MAC */ extern __checkReturn int hunt_mac_poll( __in efx_nic_t *enp, __out efx_link_mode_t *link_modep); extern __checkReturn int hunt_mac_up( __in efx_nic_t *enp, __out boolean_t *mac_upp); extern __checkReturn int hunt_mac_addr_set( __in efx_nic_t *enp); extern __checkReturn int hunt_mac_reconfigure( __in efx_nic_t *enp); extern __checkReturn int hunt_mac_multicast_list_set( __in efx_nic_t *enp); extern __checkReturn int hunt_mac_filter_default_rxq_set( __in efx_nic_t *enp, __in efx_rxq_t *erp, __in boolean_t using_rss); extern void hunt_mac_filter_default_rxq_clear( __in efx_nic_t *enp); #if EFSYS_OPT_LOOPBACK extern __checkReturn int hunt_mac_loopback_set( __in efx_nic_t *enp, __in efx_link_mode_t link_mode, __in efx_loopback_type_t loopback_type); #endif /* EFSYS_OPT_LOOPBACK */ #if EFSYS_OPT_MAC_STATS extern __checkReturn int hunt_mac_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __out_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, + __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, __out_opt uint32_t *generationp); #endif /* EFSYS_OPT_MAC_STATS */ /* MCDI */ #if EFSYS_OPT_MCDI extern __checkReturn int hunt_mcdi_init( __in efx_nic_t *enp, __in const efx_mcdi_transport_t *mtp); extern void hunt_mcdi_fini( __in efx_nic_t *enp); extern void hunt_mcdi_request_copyin( __in efx_nic_t *enp, __in efx_mcdi_req_t *emrp, __in unsigned int seq, __in boolean_t ev_cpl, __in boolean_t new_epoch); extern __checkReturn boolean_t hunt_mcdi_request_poll( __in efx_nic_t *enp); extern void hunt_mcdi_request_copyout( __in efx_nic_t *enp, __in efx_mcdi_req_t *emrp); extern int hunt_mcdi_poll_reboot( __in efx_nic_t *enp); extern __checkReturn int hunt_mcdi_fw_update_supported( __in efx_nic_t *enp, __out boolean_t *supportedp); extern __checkReturn int hunt_mcdi_macaddr_change_supported( __in efx_nic_t *enp, __out boolean_t *supportedp); #endif /* EFSYS_OPT_MCDI */ /* NVRAM */ #if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD extern __checkReturn int hunt_nvram_buf_read_tlv( __in efx_nic_t *enp, __in_bcount(partn_size) caddr_t partn_data, __in size_t partn_size, __in uint32_t tag, __deref_out_bcount_opt(*sizep) caddr_t *datap, __out size_t *sizep); extern __checkReturn int hunt_nvram_buf_write_tlv( __inout_bcount(partn_size) caddr_t partn_data, __in size_t partn_size, __in uint32_t tag, __in_bcount(tag_size) caddr_t tag_data, __in size_t tag_size, __out size_t *total_lengthp); extern __checkReturn int hunt_nvram_partn_read_tlv( __in efx_nic_t *enp, __in uint32_t partn, __in uint32_t tag, __deref_out_bcount_opt(*sizep) caddr_t *datap, __out size_t *sizep); extern __checkReturn int hunt_nvram_partn_write_tlv( __in efx_nic_t *enp, __in uint32_t partn, __in uint32_t tag, __in_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int hunt_nvram_partn_size( __in efx_nic_t *enp, __in unsigned int partn, __out size_t *sizep); extern __checkReturn int hunt_nvram_partn_lock( __in efx_nic_t *enp, __in unsigned int partn); extern __checkReturn int hunt_nvram_partn_read( __in efx_nic_t *enp, __in unsigned int partn, __in unsigned int offset, __out_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int hunt_nvram_partn_erase( __in efx_nic_t *enp, __in unsigned int partn, __in unsigned int offset, __in size_t size); extern __checkReturn int hunt_nvram_partn_write( __in efx_nic_t *enp, __in unsigned int partn, __in unsigned int offset, __out_bcount(size) caddr_t data, __in size_t size); extern void hunt_nvram_partn_unlock( __in efx_nic_t *enp, __in unsigned int partn); #endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */ #if EFSYS_OPT_NVRAM #if EFSYS_OPT_DIAG extern __checkReturn int hunt_nvram_test( __in efx_nic_t *enp); #endif /* EFSYS_OPT_DIAG */ extern __checkReturn int hunt_nvram_size( __in efx_nic_t *enp, __in efx_nvram_type_t type, __out size_t *sizep); extern __checkReturn int hunt_nvram_get_version( __in efx_nic_t *enp, __in efx_nvram_type_t type, __out uint32_t *subtypep, __out_ecount(4) uint16_t version[4]); extern __checkReturn int hunt_nvram_rw_start( __in efx_nic_t *enp, __in efx_nvram_type_t type, __out size_t *pref_chunkp); extern __checkReturn int hunt_nvram_read_chunk( __in efx_nic_t *enp, __in efx_nvram_type_t type, __in unsigned int offset, __out_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int hunt_nvram_erase( __in efx_nic_t *enp, __in efx_nvram_type_t type); extern __checkReturn int hunt_nvram_write_chunk( __in efx_nic_t *enp, __in efx_nvram_type_t type, __in unsigned int offset, __in_bcount(size) caddr_t data, __in size_t size); extern void hunt_nvram_rw_finish( __in efx_nic_t *enp, __in efx_nvram_type_t type); extern __checkReturn int hunt_nvram_partn_set_version( __in efx_nic_t *enp, __in unsigned int partn, __in_ecount(4) uint16_t version[4]); extern __checkReturn int hunt_nvram_set_version( __in efx_nic_t *enp, __in efx_nvram_type_t type, __in_ecount(4) uint16_t version[4]); #endif /* EFSYS_OPT_NVRAM */ /* PHY */ typedef struct hunt_link_state_s { uint32_t hls_adv_cap_mask; uint32_t hls_lp_cap_mask; unsigned int hls_fcntl; efx_link_mode_t hls_link_mode; #if EFSYS_OPT_LOOPBACK efx_loopback_type_t hls_loopback; #endif boolean_t hls_mac_up; } hunt_link_state_t; extern void hunt_phy_link_ev( __in efx_nic_t *enp, __in efx_qword_t *eqp, __out efx_link_mode_t *link_modep); extern __checkReturn int hunt_phy_get_link( __in efx_nic_t *enp, __out hunt_link_state_t *hlsp); extern __checkReturn int hunt_phy_power( __in efx_nic_t *enp, __in boolean_t on); extern __checkReturn int hunt_phy_reconfigure( __in efx_nic_t *enp); extern __checkReturn int hunt_phy_verify( __in efx_nic_t *enp); extern __checkReturn int hunt_phy_oui_get( __in efx_nic_t *enp, __out uint32_t *ouip); #if EFSYS_OPT_PHY_STATS extern __checkReturn int hunt_phy_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __out_ecount(EFX_PHY_NSTATS) uint32_t *stat); + __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat); #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES extern const char * hunt_phy_prop_name( __in efx_nic_t *enp, __in unsigned int id); #endif /* EFSYS_OPT_NAMES */ extern __checkReturn int hunt_phy_prop_get( __in efx_nic_t *enp, __in unsigned int id, __in uint32_t flags, __out uint32_t *valp); extern __checkReturn int hunt_phy_prop_set( __in efx_nic_t *enp, __in unsigned int id, __in uint32_t val); #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_BIST extern __checkReturn int hunt_bist_enable_offline( __in efx_nic_t *enp); extern __checkReturn int hunt_bist_start( __in efx_nic_t *enp, __in efx_bist_type_t type); extern __checkReturn int hunt_bist_poll( __in efx_nic_t *enp, __in efx_bist_type_t type, __out efx_bist_result_t *resultp, __out_opt __drv_when(count > 0, __notnull) uint32_t *value_maskp, __out_ecount_opt(count) __drv_when(count > 0, __notnull) unsigned long *valuesp, __in size_t count); extern void hunt_bist_stop( __in efx_nic_t *enp, __in efx_bist_type_t type); #endif /* EFSYS_OPT_BIST */ /* SRAM */ #if EFSYS_OPT_DIAG extern __checkReturn int hunt_sram_test( __in efx_nic_t *enp, __in efx_sram_pattern_fn_t func); #endif /* EFSYS_OPT_DIAG */ /* TX */ extern __checkReturn int hunt_tx_init( __in efx_nic_t *enp); extern void hunt_tx_fini( __in efx_nic_t *enp); extern __checkReturn int hunt_tx_qcreate( __in efx_nic_t *enp, __in unsigned int index, __in unsigned int label, __in efsys_mem_t *esmp, __in size_t n, __in uint32_t id, __in uint16_t flags, __in efx_evq_t *eep, __in efx_txq_t *etp, __out unsigned int *addedp); extern void hunt_tx_qdestroy( __in efx_txq_t *etp); extern __checkReturn int hunt_tx_qpost( __in efx_txq_t *etp, __in_ecount(n) efx_buffer_t *eb, __in unsigned int n, __in unsigned int completed, __inout unsigned int *addedp); extern void hunt_tx_qpush( __in efx_txq_t *etp, __in unsigned int added, __in unsigned int pushed); extern __checkReturn int hunt_tx_qpace( __in efx_txq_t *etp, __in unsigned int ns); extern __checkReturn int hunt_tx_qflush( __in efx_txq_t *etp); extern void hunt_tx_qenable( __in efx_txq_t *etp); extern __checkReturn int hunt_tx_qpio_enable( __in efx_txq_t *etp); extern void hunt_tx_qpio_disable( __in efx_txq_t *etp); extern __checkReturn int hunt_tx_qpio_write( __in efx_txq_t *etp, __in_ecount(buf_length) uint8_t *buffer, __in size_t buf_length, __in size_t pio_buf_offset); extern __checkReturn int hunt_tx_qpio_post( __in efx_txq_t *etp, __in size_t pkt_length, __in unsigned int completed, __inout unsigned int *addedp); extern __checkReturn int hunt_tx_qdesc_post( __in efx_txq_t *etp, __in_ecount(n) efx_desc_t *ed, __in unsigned int n, __in unsigned int completed, __inout unsigned int *addedp); extern void hunt_tx_qdesc_dma_create( __in efx_txq_t *etp, __in efsys_dma_addr_t addr, __in size_t size, __in boolean_t eop, __out efx_desc_t *edp); extern void hunt_tx_qdesc_tso_create( __in efx_txq_t *etp, __in uint16_t ipv4_id, __in uint32_t tcp_seq, __in uint8_t tcp_flags, __out efx_desc_t *edp); extern void hunt_tx_qdesc_vlantci_create( __in efx_txq_t *etp, __in uint16_t vlan_tci, __out efx_desc_t *edp); #if EFSYS_OPT_QSTATS extern void hunt_tx_qstats_update( __in efx_txq_t *etp, __inout_ecount(TX_NQSTATS) efsys_stat_t *stat); #endif /* EFSYS_OPT_QSTATS */ /* PIO */ /* Missing register definitions */ #ifndef ER_DZ_TX_PIOBUF_OFST #define ER_DZ_TX_PIOBUF_OFST 0x00001000 #endif #ifndef ER_DZ_TX_PIOBUF_STEP #define ER_DZ_TX_PIOBUF_STEP 8192 #endif #ifndef ER_DZ_TX_PIOBUF_ROWS #define ER_DZ_TX_PIOBUF_ROWS 2048 #endif #ifndef ER_DZ_TX_PIOBUF_SIZE #define ER_DZ_TX_PIOBUF_SIZE 2048 #endif #define HUNT_PIOBUF_NBUFS (16) #define HUNT_PIOBUF_SIZE (ER_DZ_TX_PIOBUF_SIZE) #define HUNT_MIN_PIO_ALLOC_SIZE (HUNT_PIOBUF_SIZE / 32) #define HUNT_LEGACY_PF_PRIVILEGE_MASK \ (MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN | \ MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK | \ MC_CMD_PRIVILEGE_MASK_IN_GRP_ONLOAD | \ MC_CMD_PRIVILEGE_MASK_IN_GRP_PTP | \ MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE_FILTERS | \ MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING | \ MC_CMD_PRIVILEGE_MASK_IN_GRP_UNICAST | \ MC_CMD_PRIVILEGE_MASK_IN_GRP_MULTICAST | \ MC_CMD_PRIVILEGE_MASK_IN_GRP_BROADCAST | \ MC_CMD_PRIVILEGE_MASK_IN_GRP_ALL_MULTICAST | \ MC_CMD_PRIVILEGE_MASK_IN_GRP_PROMISCUOUS) #define HUNT_LEGACY_VF_PRIVILEGE_MASK 0 typedef uint32_t efx_piobuf_handle_t; #define EFX_PIOBUF_HANDLE_INVALID ((efx_piobuf_handle_t) -1) extern __checkReturn int hunt_nic_pio_alloc( __inout efx_nic_t *enp, __out uint32_t *bufnump, __out efx_piobuf_handle_t *handlep, __out uint32_t *blknump, __out uint32_t *offsetp, __out size_t *sizep); extern __checkReturn int hunt_nic_pio_free( __inout efx_nic_t *enp, __in uint32_t bufnum, __in uint32_t blknum); extern __checkReturn int hunt_nic_pio_link( __inout efx_nic_t *enp, __in uint32_t vi_index, __in efx_piobuf_handle_t handle); extern __checkReturn int hunt_nic_pio_unlink( __inout efx_nic_t *enp, __in uint32_t vi_index); /* VPD */ #if EFSYS_OPT_VPD extern __checkReturn int hunt_vpd_init( __in efx_nic_t *enp); extern __checkReturn int hunt_vpd_size( __in efx_nic_t *enp, __out size_t *sizep); extern __checkReturn int hunt_vpd_read( __in efx_nic_t *enp, __out_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int hunt_vpd_verify( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int hunt_vpd_reinit( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int hunt_vpd_get( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size, __inout efx_vpd_value_t *evvp); extern __checkReturn int hunt_vpd_set( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size, __in efx_vpd_value_t *evvp); extern __checkReturn int hunt_vpd_next( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size, __out efx_vpd_value_t *evvp, __inout unsigned int *contp); extern __checkReturn int hunt_vpd_write( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size); extern void hunt_vpd_fini( __in efx_nic_t *enp); #endif /* EFSYS_OPT_VPD */ /* RX */ extern __checkReturn int hunt_rx_init( __in efx_nic_t *enp); #if EFSYS_OPT_RX_HDR_SPLIT extern __checkReturn int hunt_rx_hdr_split_enable( __in efx_nic_t *enp, __in unsigned int hdr_buf_size, __in unsigned int pld_buf_size); #endif /* EFSYS_OPT_RX_HDR_SPLIT */ #if EFSYS_OPT_RX_SCATTER extern __checkReturn int hunt_rx_scatter_enable( __in efx_nic_t *enp, __in unsigned int buf_size); #endif /* EFSYS_OPT_RX_SCATTER */ #if EFSYS_OPT_RX_SCALE extern __checkReturn int hunt_rx_scale_mode_set( __in efx_nic_t *enp, __in efx_rx_hash_alg_t alg, __in efx_rx_hash_type_t type, __in boolean_t insert); extern __checkReturn int hunt_rx_scale_key_set( __in efx_nic_t *enp, __in_ecount(n) uint8_t *key, __in size_t n); extern __checkReturn int hunt_rx_scale_tbl_set( __in efx_nic_t *enp, __in_ecount(n) unsigned int *table, __in size_t n); #endif /* EFSYS_OPT_RX_SCALE */ extern void hunt_rx_qpost( __in efx_rxq_t *erp, __in_ecount(n) efsys_dma_addr_t *addrp, __in size_t size, __in unsigned int n, __in unsigned int completed, __in unsigned int added); extern void hunt_rx_qpush( __in efx_rxq_t *erp, __in unsigned int added, __inout unsigned int *pushedp); extern __checkReturn int hunt_rx_qflush( __in efx_rxq_t *erp); extern void hunt_rx_qenable( __in efx_rxq_t *erp); extern __checkReturn int hunt_rx_qcreate( __in efx_nic_t *enp, __in unsigned int index, __in unsigned int label, __in efx_rxq_type_t type, __in efsys_mem_t *esmp, __in size_t n, __in uint32_t id, __in efx_evq_t *eep, __in efx_rxq_t *erp); extern void hunt_rx_qdestroy( __in efx_rxq_t *erp); extern void hunt_rx_fini( __in efx_nic_t *enp); #if EFSYS_OPT_FILTER typedef struct hunt_filter_handle_s { uint32_t hfh_lo; uint32_t hfh_hi; } hunt_filter_handle_t; typedef struct hunt_filter_entry_s { uintptr_t hfe_spec; /* pointer to filter spec plus busy bit */ hunt_filter_handle_t hfe_handle; } hunt_filter_entry_t; /* * BUSY flag indicates that an update is in progress. * AUTO_OLD flag is used to mark and sweep MAC packet filters. */ #define EFX_HUNT_FILTER_FLAG_BUSY 1U #define EFX_HUNT_FILTER_FLAG_AUTO_OLD 2U #define EFX_HUNT_FILTER_FLAGS 3U #define EFX_HUNT_FILTER_TBL_ROWS 8192 /* Allow for the broadcast address to be added to the multicast list */ #define EFX_HUNT_FILTER_MULTICAST_FILTERS_MAX (EFX_MAC_MULTICAST_LIST_MAX + 1) typedef struct hunt_filter_table_s { hunt_filter_entry_t hft_entry[EFX_HUNT_FILTER_TBL_ROWS]; efx_rxq_t * hft_default_rxq; boolean_t hft_using_rss; uint32_t hft_unicst_filter_index; boolean_t hft_unicst_filter_set; uint32_t hft_mulcst_filter_indexes[ EFX_HUNT_FILTER_MULTICAST_FILTERS_MAX]; uint32_t hft_mulcst_filter_count; } hunt_filter_table_t; __checkReturn int hunt_filter_init( __in efx_nic_t *enp); void hunt_filter_fini( __in efx_nic_t *enp); __checkReturn int hunt_filter_restore( __in efx_nic_t *enp); __checkReturn int hunt_filter_add( __in efx_nic_t *enp, __inout efx_filter_spec_t *spec, __in boolean_t may_replace); __checkReturn int hunt_filter_delete( __in efx_nic_t *enp, __inout efx_filter_spec_t *spec); extern __checkReturn int hunt_filter_supported_filters( __in efx_nic_t *enp, __out uint32_t *list, __out size_t *length); extern __checkReturn int hunt_filter_reconfigure( __in efx_nic_t *enp, __in_ecount(6) uint8_t const *mac_addr, __in boolean_t all_unicst, __in boolean_t mulcst, __in boolean_t all_mulcst, __in boolean_t brdcst, __in_ecount(6*count) uint8_t const *addrs, __in int count); extern void hunt_filter_get_default_rxq( __in efx_nic_t *enp, __out efx_rxq_t **erpp, __out boolean_t *using_rss); extern void hunt_filter_default_rxq_set( __in efx_nic_t *enp, __in efx_rxq_t *erp, __in boolean_t using_rss); extern void hunt_filter_default_rxq_clear( __in efx_nic_t *enp); #endif /* EFSYS_OPT_FILTER */ extern __checkReturn int hunt_pktfilter_set( __in efx_nic_t *enp, __in boolean_t unicst, __in boolean_t brdcst); #if EFSYS_OPT_MCAST_FILTER_LIST extern __checkReturn int hunt_pktfilter_mcast_set( __in efx_nic_t *enp, __in uint8_t const *addrs, __in int count); #endif /* EFSYS_OPT_MCAST_FILTER_LIST */ extern __checkReturn int hunt_pktfilter_mcast_all( __in efx_nic_t *enp); extern __checkReturn int efx_mcdi_get_function_info( __in efx_nic_t *enp, __out uint32_t *pfp, __out_opt uint32_t *vfp); extern __checkReturn int efx_mcdi_privilege_mask( __in efx_nic_t *enp, __in uint32_t pf, __in uint32_t vf, __out uint32_t *maskp); #ifdef __cplusplus } #endif #endif /* _SYS_HUNT_IMPL_H */ Index: head/sys/dev/sfxge/common/hunt_mac.c =================================================================== --- head/sys/dev/sfxge/common/hunt_mac.c (revision 291394) +++ head/sys/dev/sfxge/common/hunt_mac.c (revision 291395) @@ -1,696 +1,696 @@ /*- * Copyright (c) 2012-2015 Solarflare Communications Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the FreeBSD Project. */ #include __FBSDID("$FreeBSD$"); #include "efsys.h" #include "efx.h" #include "efx_impl.h" #if EFSYS_OPT_HUNTINGTON __checkReturn int hunt_mac_poll( __in efx_nic_t *enp, __out efx_link_mode_t *link_modep) { /* * TBD: Consider a common Siena/Huntington function. The code is * essentially identical. */ efx_port_t *epp = &(enp->en_port); hunt_link_state_t hls; int rc; if ((rc = hunt_phy_get_link(enp, &hls)) != 0) goto fail1; epp->ep_adv_cap_mask = hls.hls_adv_cap_mask; epp->ep_fcntl = hls.hls_fcntl; *link_modep = hls.hls_link_mode; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); *link_modep = EFX_LINK_UNKNOWN; return (rc); } __checkReturn int hunt_mac_up( __in efx_nic_t *enp, __out boolean_t *mac_upp) { /* * TBD: Consider a common Siena/Huntington function. The code is * essentially identical. */ hunt_link_state_t hls; int rc; /* * Because Huntington doesn't *require* polling, we can't rely on * hunt_mac_poll() being executed to populate epp->ep_mac_up. */ if ((rc = hunt_phy_get_link(enp, &hls)) != 0) goto fail1; *mac_upp = hls.hls_mac_up; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } /* * Huntington uses MC_CMD_VADAPTOR_SET_MAC to set the * MAC address; the address field in MC_CMD_SET_MAC has no * effect. * MC_CMD_VADAPTOR_SET_MAC requires mac-spoofing privilege and * the port to have no filters or queues active. */ static __checkReturn int efx_mcdi_vadapter_set_mac( __in efx_nic_t *enp) { efx_port_t *epp = &(enp->en_port); efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_VADAPTOR_SET_MAC_IN_LEN, MC_CMD_VADAPTOR_SET_MAC_OUT_LEN)]; int rc; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_VADAPTOR_SET_MAC; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_VADAPTOR_SET_MAC_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_VADAPTOR_SET_MAC_OUT_LEN; MCDI_IN_SET_DWORD(req, VADAPTOR_SET_MAC_IN_UPSTREAM_PORT_ID, enp->en_vport_id); EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, VADAPTOR_SET_MAC_IN_MACADDR), epp->ep_mac_addr); efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int hunt_mac_addr_set( __in efx_nic_t *enp) { int rc; if ((rc = efx_mcdi_vadapter_set_mac(enp)) != 0) { if (rc != ENOTSUP) goto fail1; /* Fallback for older firmware without Vadapter support */ if ((rc = hunt_mac_reconfigure(enp)) != 0) goto fail2; } return (0); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int hunt_mac_reconfigure( __in efx_nic_t *enp) { efx_port_t *epp = &(enp->en_port); efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_SET_MAC_IN_LEN, MC_CMD_SET_MAC_OUT_LEN)]; int rc; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_SET_MAC; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_SET_MAC_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN; MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu); MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0); EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR), epp->ep_mac_addr); /* * Note: The Huntington MAC does not support REJECT_BRDCST. * The REJECT_UNCST flag will also prevent multicast traffic * from reaching the filters. As Huntington filters drop any * traffic that does not match a filter it is ok to leave the * MAC running in promiscuous mode. See bug41141. */ MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT, SET_MAC_IN_REJECT_UNCST, 0, SET_MAC_IN_REJECT_BRDCST, 0); /* * Flow control, whether it is auto-negotiated or not, * is set via the PHY advertised capabilities. When set to * automatic the MAC will use the PHY settings to determine * the flow control settings. */ MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, MC_CMD_FCNTL_AUTO); /* Do not include the Ethernet frame checksum in RX packets */ MCDI_IN_POPULATE_DWORD_1(req, SET_MAC_IN_FLAGS, SET_MAC_IN_FLAG_INCLUDE_FCS, 0); efx_mcdi_execute_quiet(enp, &req); if (req.emr_rc != 0) { /* * Unprivileged functions cannot control link state, * but still need to configure filters. */ if (req.emr_rc != EACCES) { rc = req.emr_rc; goto fail1; } } /* * Apply the filters for the MAC configuration. * If the NIC isn't ready to accept filters this may * return success without setting anything. */ rc = efx_filter_reconfigure(enp, epp->ep_mac_addr, epp->ep_all_unicst, epp->ep_mulcst, epp->ep_all_mulcst, epp->ep_brdcst, epp->ep_mulcst_addr_list, epp->ep_mulcst_addr_count); return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int hunt_mac_multicast_list_set( __in efx_nic_t *enp) { efx_port_t *epp = &(enp->en_port); efx_mac_ops_t *emop = epp->ep_emop; int rc; EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); /* FIXME: Insert filters for multicast list */ if ((rc = emop->emo_reconfigure(enp)) != 0) goto fail1; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int hunt_mac_filter_default_rxq_set( __in efx_nic_t *enp, __in efx_rxq_t *erp, __in boolean_t using_rss) { efx_port_t *epp = &(enp->en_port); efx_rxq_t *old_rxq; boolean_t old_using_rss; int rc; hunt_filter_get_default_rxq(enp, &old_rxq, &old_using_rss); hunt_filter_default_rxq_set(enp, erp, using_rss); rc = efx_filter_reconfigure(enp, epp->ep_mac_addr, epp->ep_all_unicst, epp->ep_mulcst, epp->ep_all_mulcst, epp->ep_brdcst, epp->ep_mulcst_addr_list, epp->ep_mulcst_addr_count); if (rc != 0) goto fail1; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); hunt_filter_default_rxq_set(enp, old_rxq, old_using_rss); return (rc); } void hunt_mac_filter_default_rxq_clear( __in efx_nic_t *enp) { efx_port_t *epp = &(enp->en_port); hunt_filter_default_rxq_clear(enp); efx_filter_reconfigure(enp, epp->ep_mac_addr, epp->ep_all_unicst, epp->ep_mulcst, epp->ep_all_mulcst, epp->ep_brdcst, epp->ep_mulcst_addr_list, epp->ep_mulcst_addr_count); } #if EFSYS_OPT_LOOPBACK __checkReturn int hunt_mac_loopback_set( __in efx_nic_t *enp, __in efx_link_mode_t link_mode, __in efx_loopback_type_t loopback_type) { /* * TBD: Consider a common Siena/Huntington function. The code is * essentially identical. */ efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; efx_loopback_type_t old_loopback_type; efx_link_mode_t old_loopback_link_mode; int rc; /* The PHY object handles this on Huntington */ old_loopback_type = epp->ep_loopback_type; old_loopback_link_mode = epp->ep_loopback_link_mode; epp->ep_loopback_type = loopback_type; epp->ep_loopback_link_mode = link_mode; if ((rc = epop->epo_reconfigure(enp)) != 0) goto fail1; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); epp->ep_loopback_type = old_loopback_type; epp->ep_loopback_link_mode = old_loopback_link_mode; return (rc); } #endif /* EFSYS_OPT_LOOPBACK */ #if EFSYS_OPT_MAC_STATS #define HUNT_MAC_STAT_READ(_esmp, _field, _eqp) \ EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp) __checkReturn int hunt_mac_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __out_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, + __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, __out_opt uint32_t *generationp) { efx_qword_t value; efx_qword_t generation_start; efx_qword_t generation_end; _NOTE(ARGUNUSED(enp)) /* Read END first so we don't race with the MC */ EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END, &generation_end); EFSYS_MEM_READ_BARRIER(); /* TX */ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value); EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value); EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value); /* RX */ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value); EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value); EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]), &(value.eq_dword[0])); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]), &(value.eq_dword[1])); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]), &(value.eq_dword[0])); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]), &(value.eq_dword[1])); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]), &(value.eq_dword[0])); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]), &(value.eq_dword[1])); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]), &(value.eq_dword[0])); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]), &(value.eq_dword[1])); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value); /* Packet memory (EF10 only) */ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_BB_OVERFLOW, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_BB_OVERFLOW]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_BB_OVERFLOW, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_BB_OVERFLOW]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_VFIFO_FULL, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_VFIFO_FULL]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_VFIFO_FULL, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_VFIFO_FULL]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_QBB, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_QBB]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_QBB, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_QBB]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_MAPPING, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_MAPPING]), &value); /* RX datapath */ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_Q_DISABLED_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_Q_DISABLED_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_DI_DROPPED_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_DI_DROPPED_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_STREAMING_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_STREAMING_PKTS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_FETCH_CONDITIONS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_FETCH]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_WAIT_CONDITIONS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_WAIT]), &value); /* VADAPTER RX */ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_PACKETS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_PACKETS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_BYTES, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_BYTES]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_PACKETS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_BYTES, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_BYTES]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_PACKETS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_BYTES, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_BYTES]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_PACKETS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_PACKETS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_BYTES, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_BYTES]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_OVERFLOW, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_OVERFLOW]), &value); /* VADAPTER TX */ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_PACKETS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_BYTES, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_BYTES]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_PACKETS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_BYTES, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_PACKETS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_BYTES, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_PACKETS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_PACKETS]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_BYTES, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_BYTES]), &value); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_OVERFLOW, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_OVERFLOW]), &value); EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE); EFSYS_MEM_READ_BARRIER(); HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START, &generation_start); /* Check that we didn't read the stats in the middle of a DMA */ /* Not a good enough check ? */ if (memcmp(&generation_start, &generation_end, sizeof (generation_start))) return (EAGAIN); if (generationp) *generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0); return (0); } #endif /* EFSYS_OPT_MAC_STATS */ #endif /* EFSYS_OPT_HUNTINGTON */ Index: head/sys/dev/sfxge/common/hunt_phy.c =================================================================== --- head/sys/dev/sfxge/common/hunt_phy.c (revision 291394) +++ head/sys/dev/sfxge/common/hunt_phy.c (revision 291395) @@ -1,701 +1,701 @@ /*- * Copyright (c) 2012-2015 Solarflare Communications Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the FreeBSD Project. */ #include __FBSDID("$FreeBSD$"); #include "efsys.h" #include "efx.h" #include "efx_impl.h" #if EFSYS_OPT_HUNTINGTON static void hunt_phy_decode_cap( __in uint32_t mcdi_cap, __out uint32_t *maskp) { /* * TBD: consider common Siena/Hunt function: Hunt is a superset of * Siena here (adds 40G) */ uint32_t mask; mask = 0; if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN)) mask |= (1 << EFX_PHY_CAP_10HDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN)) mask |= (1 << EFX_PHY_CAP_10FDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN)) mask |= (1 << EFX_PHY_CAP_100HDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN)) mask |= (1 << EFX_PHY_CAP_100FDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN)) mask |= (1 << EFX_PHY_CAP_1000HDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) mask |= (1 << EFX_PHY_CAP_1000FDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) mask |= (1 << EFX_PHY_CAP_10000FDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) mask |= (1 << EFX_PHY_CAP_40000FDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN)) mask |= (1 << EFX_PHY_CAP_PAUSE); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN)) mask |= (1 << EFX_PHY_CAP_ASYM); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_AN_LBN)) mask |= (1 << EFX_PHY_CAP_AN); *maskp = mask; } static void hunt_phy_decode_link_mode( __in efx_nic_t *enp, __in uint32_t link_flags, __in unsigned int speed, __in unsigned int fcntl, __out efx_link_mode_t *link_modep, __out unsigned int *fcntlp) { /* * TBD: consider common Siena/Hunt function: Hunt is a superset of * Siena here (adds 40G and generate-only flow control) */ boolean_t fd = !!(link_flags & (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN)); boolean_t up = !!(link_flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN)); _NOTE(ARGUNUSED(enp)) if (!up) *link_modep = EFX_LINK_DOWN; else if (speed == 40000 && fd) *link_modep = EFX_LINK_40000FDX; else if (speed == 10000 && fd) *link_modep = EFX_LINK_10000FDX; else if (speed == 1000) *link_modep = fd ? EFX_LINK_1000FDX : EFX_LINK_1000HDX; else if (speed == 100) *link_modep = fd ? EFX_LINK_100FDX : EFX_LINK_100HDX; else if (speed == 10) *link_modep = fd ? EFX_LINK_10FDX : EFX_LINK_10HDX; else *link_modep = EFX_LINK_UNKNOWN; if (fcntl == MC_CMD_FCNTL_OFF) *fcntlp = 0; else if (fcntl == MC_CMD_FCNTL_RESPOND) *fcntlp = EFX_FCNTL_RESPOND; else if (fcntl == MC_CMD_FCNTL_GENERATE) *fcntlp = EFX_FCNTL_GENERATE; else if (fcntl == MC_CMD_FCNTL_BIDIR) *fcntlp = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE; else { EFSYS_PROBE1(mc_pcol_error, int, fcntl); *fcntlp = 0; } } void hunt_phy_link_ev( __in efx_nic_t *enp, __in efx_qword_t *eqp, __out efx_link_mode_t *link_modep) { /* * TBD: consider common Siena/Hunt function: Hunt is a superset of * Siena here (adds 40G) */ efx_port_t *epp = &(enp->en_port); unsigned int link_flags; unsigned int speed; unsigned int fcntl; efx_link_mode_t link_mode; uint32_t lp_cap_mask; /* * Convert the LINKCHANGE speed enumeration into mbit/s, in the * same way as GET_LINK encodes the speed */ switch (MCDI_EV_FIELD(eqp, LINKCHANGE_SPEED)) { case MCDI_EVENT_LINKCHANGE_SPEED_100M: speed = 100; break; case MCDI_EVENT_LINKCHANGE_SPEED_1G: speed = 1000; break; case MCDI_EVENT_LINKCHANGE_SPEED_10G: speed = 10000; break; case MCDI_EVENT_LINKCHANGE_SPEED_40G: speed = 40000; break; default: speed = 0; break; } link_flags = MCDI_EV_FIELD(eqp, LINKCHANGE_LINK_FLAGS); hunt_phy_decode_link_mode(enp, link_flags, speed, MCDI_EV_FIELD(eqp, LINKCHANGE_FCNTL), &link_mode, &fcntl); hunt_phy_decode_cap(MCDI_EV_FIELD(eqp, LINKCHANGE_LP_CAP), &lp_cap_mask); /* * It's safe to update ep_lp_cap_mask without the driver's port lock * because presumably any concurrently running efx_port_poll() is * only going to arrive at the same value. * * ep_fcntl has two meanings. It's either the link common fcntl * (if the PHY supports AN), or it's the forced link state. If * the former, it's safe to update the value for the same reason as * for ep_lp_cap_mask. If the latter, then just ignore the value, * because we can race with efx_mac_fcntl_set(). */ epp->ep_lp_cap_mask = lp_cap_mask; epp->ep_fcntl = fcntl; *link_modep = link_mode; } __checkReturn int hunt_phy_power( __in efx_nic_t *enp, __in boolean_t power) { /* TBD: consider common Siena/Hunt function: essentially identical */ int rc; if (!power) return (0); /* Check if the PHY is a zombie */ if ((rc = hunt_phy_verify(enp)) != 0) goto fail1; enp->en_reset_flags |= EFX_RESET_PHY; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int hunt_phy_get_link( __in efx_nic_t *enp, __out hunt_link_state_t *hlsp) { /* * TBD: consider common Siena/Hunt function: Hunt is very similar * (at least for now; not clear that the loopbacks should necessarily * be quite the same...) */ efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_GET_LINK_IN_LEN, MC_CMD_GET_LINK_OUT_LEN)]; int rc; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_GET_LINK; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_GET_LINK_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_GET_LINK_OUT_LEN; efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } if (req.emr_out_length_used < MC_CMD_GET_LINK_OUT_LEN) { rc = EMSGSIZE; goto fail2; } hunt_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_CAP), &hlsp->hls_adv_cap_mask); hunt_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_LP_CAP), &hlsp->hls_lp_cap_mask); hunt_phy_decode_link_mode(enp, MCDI_OUT_DWORD(req, GET_LINK_OUT_FLAGS), MCDI_OUT_DWORD(req, GET_LINK_OUT_LINK_SPEED), MCDI_OUT_DWORD(req, GET_LINK_OUT_FCNTL), &hlsp->hls_link_mode, &hlsp->hls_fcntl); #if EFSYS_OPT_LOOPBACK /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD); hlsp->hls_loopback = MCDI_OUT_DWORD(req, GET_LINK_OUT_LOOPBACK_MODE); #endif /* EFSYS_OPT_LOOPBACK */ hlsp->hls_mac_up = MCDI_OUT_DWORD(req, GET_LINK_OUT_MAC_FAULT) == 0; return (0); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int hunt_phy_reconfigure( __in efx_nic_t *enp) { /* * TBD: this is a little different for now (no LED support for Hunt * yet), but ultimately should consider common Siena/Hunt function: * Hunt should be a superset of Siena here (adds 40G) */ efx_nic_cfg_t *encp = &(enp->en_nic_cfg); efx_port_t *epp = &(enp->en_port); efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_SET_LINK_IN_LEN, MC_CMD_SET_LINK_OUT_LEN)]; uint32_t cap_mask; unsigned int led_mode; unsigned int speed; int rc; if (~encp->enc_func_flags & EFX_NIC_FUNC_LINKCTRL) goto out; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_SET_LINK; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_SET_LINK_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_SET_LINK_OUT_LEN; cap_mask = epp->ep_adv_cap_mask; MCDI_IN_POPULATE_DWORD_10(req, SET_LINK_IN_CAP, PHY_CAP_10HDX, (cap_mask >> EFX_PHY_CAP_10HDX) & 0x1, PHY_CAP_10FDX, (cap_mask >> EFX_PHY_CAP_10FDX) & 0x1, PHY_CAP_100HDX, (cap_mask >> EFX_PHY_CAP_100HDX) & 0x1, PHY_CAP_100FDX, (cap_mask >> EFX_PHY_CAP_100FDX) & 0x1, PHY_CAP_1000HDX, (cap_mask >> EFX_PHY_CAP_1000HDX) & 0x1, PHY_CAP_1000FDX, (cap_mask >> EFX_PHY_CAP_1000FDX) & 0x1, PHY_CAP_10000FDX, (cap_mask >> EFX_PHY_CAP_10000FDX) & 0x1, PHY_CAP_PAUSE, (cap_mask >> EFX_PHY_CAP_PAUSE) & 0x1, PHY_CAP_ASYM, (cap_mask >> EFX_PHY_CAP_ASYM) & 0x1, PHY_CAP_AN, (cap_mask >> EFX_PHY_CAP_AN) & 0x1); /* Too many fields for for POPULATE macros, so insert this afterwards */ MCDI_IN_SET_DWORD_FIELD(req, SET_LINK_IN_CAP, PHY_CAP_40000FDX, (cap_mask >> EFX_PHY_CAP_40000FDX) & 0x1); #if EFSYS_OPT_LOOPBACK MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE, epp->ep_loopback_type); switch (epp->ep_loopback_link_mode) { case EFX_LINK_100FDX: speed = 100; break; case EFX_LINK_1000FDX: speed = 1000; break; case EFX_LINK_10000FDX: speed = 10000; break; case EFX_LINK_40000FDX: speed = 40000; break; default: speed = 0; } #else MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE, MC_CMD_LOOPBACK_NONE); speed = 0; #endif /* EFSYS_OPT_LOOPBACK */ MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_SPEED, speed); #if EFSYS_OPT_PHY_FLAGS MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, epp->ep_phy_flags); #else MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, 0); #endif /* EFSYS_OPT_PHY_FLAGS */ efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } /* And set the blink mode */ (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_SET_ID_LED; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_SET_ID_LED_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_SET_ID_LED_OUT_LEN; #if EFSYS_OPT_PHY_LED_CONTROL switch (epp->ep_phy_led_mode) { case EFX_PHY_LED_DEFAULT: led_mode = MC_CMD_LED_DEFAULT; break; case EFX_PHY_LED_OFF: led_mode = MC_CMD_LED_OFF; break; case EFX_PHY_LED_ON: led_mode = MC_CMD_LED_ON; break; default: EFSYS_ASSERT(0); led_mode = MC_CMD_LED_DEFAULT; } MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, led_mode); #else MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, MC_CMD_LED_DEFAULT); #endif /* EFSYS_OPT_PHY_LED_CONTROL */ efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail2; } out: return (0); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int hunt_phy_verify( __in efx_nic_t *enp) { /* TBD: consider common Siena/Hunt function: essentially identical */ efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_GET_PHY_STATE_IN_LEN, MC_CMD_GET_PHY_STATE_OUT_LEN)]; uint32_t state; int rc; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_GET_PHY_STATE; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_GET_PHY_STATE_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_GET_PHY_STATE_OUT_LEN; efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } if (req.emr_out_length_used < MC_CMD_GET_PHY_STATE_OUT_LEN) { rc = EMSGSIZE; goto fail2; } state = MCDI_OUT_DWORD(req, GET_PHY_STATE_OUT_STATE); if (state != MC_CMD_PHY_STATE_OK) { if (state != MC_CMD_PHY_STATE_ZOMBIE) EFSYS_PROBE1(mc_pcol_error, int, state); rc = ENOTACTIVE; goto fail3; } return (0); fail3: EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int hunt_phy_oui_get( __in efx_nic_t *enp, __out uint32_t *ouip) { _NOTE(ARGUNUSED(enp, ouip)) return (ENOTSUP); } #if EFSYS_OPT_PHY_STATS __checkReturn int hunt_phy_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __out_ecount(EFX_PHY_NSTATS) uint32_t *stat) + __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat) { /* TBD: no stats support in firmware yet */ _NOTE(ARGUNUSED(enp, esmp)) memset(stat, 0, EFX_PHY_NSTATS * sizeof (*stat)); return (0); } #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES extern const char * hunt_phy_prop_name( __in efx_nic_t *enp, __in unsigned int id) { _NOTE(ARGUNUSED(enp, id)) return (NULL); } #endif /* EFSYS_OPT_NAMES */ extern __checkReturn int hunt_phy_prop_get( __in efx_nic_t *enp, __in unsigned int id, __in uint32_t flags, __out uint32_t *valp) { _NOTE(ARGUNUSED(enp, id, flags, valp)) return (ENOTSUP); } extern __checkReturn int hunt_phy_prop_set( __in efx_nic_t *enp, __in unsigned int id, __in uint32_t val) { _NOTE(ARGUNUSED(enp, id, val)) return (ENOTSUP); } #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_BIST __checkReturn int hunt_bist_enable_offline( __in efx_nic_t *enp) { int rc; if ((rc = efx_mcdi_bist_enable_offline(enp)) != 0) goto fail1; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int hunt_bist_start( __in efx_nic_t *enp, __in efx_bist_type_t type) { int rc; if ((rc = efx_mcdi_bist_start(enp, type)) != 0) goto fail1; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int hunt_bist_poll( __in efx_nic_t *enp, __in efx_bist_type_t type, __out efx_bist_result_t *resultp, __out_opt __drv_when(count > 0, __notnull) uint32_t *value_maskp, __out_ecount_opt(count) __drv_when(count > 0, __notnull) unsigned long *valuesp, __in size_t count) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN, MCDI_CTL_SDU_LEN_MAX)]; uint32_t value_mask = 0; uint32_t result; int rc; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_POLL_BIST; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MCDI_CTL_SDU_LEN_MAX; efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } if (req.emr_out_length_used < MC_CMD_POLL_BIST_OUT_RESULT_OFST + 4) { rc = EMSGSIZE; goto fail2; } if (count > 0) (void) memset(valuesp, '\0', count * sizeof (unsigned long)); result = MCDI_OUT_DWORD(req, POLL_BIST_OUT_RESULT); if (result == MC_CMD_POLL_BIST_FAILED && req.emr_out_length >= MC_CMD_POLL_BIST_OUT_MEM_LEN && count > EFX_BIST_MEM_ECC_FATAL) { if (valuesp != NULL) { valuesp[EFX_BIST_MEM_TEST] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_TEST); valuesp[EFX_BIST_MEM_ADDR] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ADDR); valuesp[EFX_BIST_MEM_BUS] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_BUS); valuesp[EFX_BIST_MEM_EXPECT] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_EXPECT); valuesp[EFX_BIST_MEM_ACTUAL] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ACTUAL); valuesp[EFX_BIST_MEM_ECC] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ECC); valuesp[EFX_BIST_MEM_ECC_PARITY] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ECC_PARITY); valuesp[EFX_BIST_MEM_ECC_FATAL] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ECC_FATAL); } value_mask |= (1 << EFX_BIST_MEM_TEST) | (1 << EFX_BIST_MEM_ADDR) | (1 << EFX_BIST_MEM_BUS) | (1 << EFX_BIST_MEM_EXPECT) | (1 << EFX_BIST_MEM_ACTUAL) | (1 << EFX_BIST_MEM_ECC) | (1 << EFX_BIST_MEM_ECC_PARITY) | (1 << EFX_BIST_MEM_ECC_FATAL); } else if (result == MC_CMD_POLL_BIST_FAILED && encp->enc_phy_type == EFX_PHY_XFI_FARMI && req.emr_out_length >= MC_CMD_POLL_BIST_OUT_MRSFP_LEN && count > EFX_BIST_FAULT_CODE) { if (valuesp != NULL) valuesp[EFX_BIST_FAULT_CODE] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_MRSFP_TEST); value_mask |= 1 << EFX_BIST_FAULT_CODE; } if (value_maskp != NULL) *value_maskp = value_mask; EFSYS_ASSERT(resultp != NULL); if (result == MC_CMD_POLL_BIST_RUNNING) *resultp = EFX_BIST_RESULT_RUNNING; else if (result == MC_CMD_POLL_BIST_PASSED) *resultp = EFX_BIST_RESULT_PASSED; else *resultp = EFX_BIST_RESULT_FAILED; return (0); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } void hunt_bist_stop( __in efx_nic_t *enp, __in efx_bist_type_t type) { /* There is no way to stop BIST on Huntinton. */ _NOTE(ARGUNUSED(enp, type)) } #endif /* EFSYS_OPT_BIST */ #endif /* EFSYS_OPT_HUNTINGTON */ Index: head/sys/dev/sfxge/common/mcdi_mon.c =================================================================== --- head/sys/dev/sfxge/common/mcdi_mon.c (revision 291394) +++ head/sys/dev/sfxge/common/mcdi_mon.c (revision 291395) @@ -1,552 +1,552 @@ /*- * Copyright (c) 2009-2015 Solarflare Communications Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the FreeBSD Project. */ #include __FBSDID("$FreeBSD$"); #include "efsys.h" #include "efx.h" #include "efx_impl.h" #if EFSYS_OPT_MON_MCDI #if EFSYS_OPT_MON_STATS #define MCDI_MON_NEXT_PAGE (uint16_t)0xfffe #define MCDI_MON_INVALID_SENSOR (uint16_t)0xfffd #define MCDI_MON_PAGE_SIZE 0x20 /* Bitmasks of valid port(s) for each sensor */ #define MCDI_MON_PORT_NONE (0x00) #define MCDI_MON_PORT_P1 (0x01) #define MCDI_MON_PORT_P2 (0x02) #define MCDI_MON_PORT_P3 (0x04) #define MCDI_MON_PORT_P4 (0x08) #define MCDI_MON_PORT_Px (0xFFFF) /* Entry for MCDI sensor in sensor map */ #define STAT(portmask, stat) \ { (MCDI_MON_PORT_##portmask), (EFX_MON_STAT_##stat) } /* Entry for sensor next page flag in sensor map */ #define STAT_NEXT_PAGE() \ { MCDI_MON_PORT_NONE, MCDI_MON_NEXT_PAGE } /* Placeholder for gaps in the array */ #define STAT_NO_SENSOR() \ { MCDI_MON_PORT_NONE, MCDI_MON_INVALID_SENSOR } /* Map from MC sensors to monitor statistics */ static const struct mcdi_sensor_map_s { uint16_t msm_port_mask; uint16_t msm_stat; } mcdi_sensor_map[] = { /* Sensor page 0 MC_CMD_SENSOR_xxx */ STAT(Px, INT_TEMP), /* 0x00 CONTROLLER_TEMP */ STAT(Px, EXT_TEMP), /* 0x01 PHY_COMMON_TEMP */ STAT(Px, INT_COOLING), /* 0x02 CONTROLLER_COOLING */ STAT(P1, EXT_TEMP), /* 0x03 PHY0_TEMP */ STAT(P1, EXT_COOLING), /* 0x04 PHY0_COOLING */ STAT(P2, EXT_TEMP), /* 0x05 PHY1_TEMP */ STAT(P2, EXT_COOLING), /* 0x06 PHY1_COOLING */ STAT(Px, 1V), /* 0x07 IN_1V0 */ STAT(Px, 1_2V), /* 0x08 IN_1V2 */ STAT(Px, 1_8V), /* 0x09 IN_1V8 */ STAT(Px, 2_5V), /* 0x0a IN_2V5 */ STAT(Px, 3_3V), /* 0x0b IN_3V3 */ STAT(Px, 12V), /* 0x0c IN_12V0 */ STAT(Px, 1_2VA), /* 0x0d IN_1V2A */ STAT(Px, VREF), /* 0x0e IN_VREF */ STAT(Px, VAOE), /* 0x0f OUT_VAOE */ STAT(Px, AOE_TEMP), /* 0x10 AOE_TEMP */ STAT(Px, PSU_AOE_TEMP), /* 0x11 PSU_AOE_TEMP */ STAT(Px, PSU_TEMP), /* 0x12 PSU_TEMP */ STAT(Px, FAN0), /* 0x13 FAN_0 */ STAT(Px, FAN1), /* 0x14 FAN_1 */ STAT(Px, FAN2), /* 0x15 FAN_2 */ STAT(Px, FAN3), /* 0x16 FAN_3 */ STAT(Px, FAN4), /* 0x17 FAN_4 */ STAT(Px, VAOE_IN), /* 0x18 IN_VAOE */ STAT(Px, IAOE), /* 0x19 OUT_IAOE */ STAT(Px, IAOE_IN), /* 0x1a IN_IAOE */ STAT(Px, NIC_POWER), /* 0x1b NIC_POWER */ STAT(Px, 0_9V), /* 0x1c IN_0V9 */ STAT(Px, I0_9V), /* 0x1d IN_I0V9 */ STAT(Px, I1_2V), /* 0x1e IN_I1V2 */ STAT_NEXT_PAGE(), /* 0x1f Next page flag (not a sensor) */ /* Sensor page 1 MC_CMD_SENSOR_xxx */ STAT(Px, 0_9V_ADC), /* 0x20 IN_0V9_ADC */ STAT(Px, INT_TEMP2), /* 0x21 CONTROLLER_2_TEMP */ STAT(Px, VREG_TEMP), /* 0x22 VREG_INTERNAL_TEMP */ STAT(Px, VREG_0_9V_TEMP), /* 0x23 VREG_0V9_TEMP */ STAT(Px, VREG_1_2V_TEMP), /* 0x24 VREG_1V2_TEMP */ STAT(Px, INT_VPTAT), /* 0x25 CTRLR. VPTAT */ STAT(Px, INT_ADC_TEMP), /* 0x26 CTRLR. INTERNAL_TEMP */ STAT(Px, EXT_VPTAT), /* 0x27 CTRLR. VPTAT_EXTADC */ STAT(Px, EXT_ADC_TEMP), /* 0x28 CTRLR. INTERNAL_TEMP_EXTADC */ STAT(Px, AMBIENT_TEMP), /* 0x29 AMBIENT_TEMP */ STAT(Px, AIRFLOW), /* 0x2a AIRFLOW */ STAT(Px, VDD08D_VSS08D_CSR), /* 0x2b VDD08D_VSS08D_CSR */ STAT(Px, VDD08D_VSS08D_CSR_EXTADC), /* 0x2c VDD08D_VSS08D_CSR_EXTADC */ STAT(Px, HOTPOINT_TEMP), /* 0x2d HOTPOINT_TEMP */ STAT(P1, PHY_POWER_SWITCH_PORT0), /* 0x2e PHY_POWER_SWITCH_PORT0 */ STAT(P2, PHY_POWER_SWITCH_PORT1), /* 0x2f PHY_POWER_SWITCH_PORT1 */ STAT(Px, MUM_VCC), /* 0x30 MUM_VCC */ STAT(Px, 0V9_A), /* 0x31 0V9_A */ STAT(Px, I0V9_A), /* 0x32 I0V9_A */ STAT(Px, 0V9_A_TEMP), /* 0x33 0V9_A_TEMP */ STAT(Px, 0V9_B), /* 0x34 0V9_B */ STAT(Px, I0V9_B), /* 0x35 I0V9_B */ STAT(Px, 0V9_B_TEMP), /* 0x36 0V9_B_TEMP */ STAT(Px, CCOM_AVREG_1V2_SUPPLY), /* 0x37 CCOM_AVREG_1V2_SUPPLY */ STAT(Px, CCOM_AVREG_1V2_SUPPLY_EXT_ADC), /* 0x38 CCOM_AVREG_1V2_SUPPLY_EXT_ADC */ STAT(Px, CCOM_AVREG_1V8_SUPPLY), /* 0x39 CCOM_AVREG_1V8_SUPPLY */ STAT(Px, CCOM_AVREG_1V8_SUPPLY_EXT_ADC), /* 0x3a CCOM_AVREG_1V8_SUPPLY_EXT_ADC */ STAT_NO_SENSOR(), /* 0x3b (no sensor) */ STAT_NO_SENSOR(), /* 0x3c (no sensor) */ STAT_NO_SENSOR(), /* 0x3d (no sensor) */ STAT_NO_SENSOR(), /* 0x3e (no sensor) */ STAT_NEXT_PAGE(), /* 0x3f Next page flag (not a sensor) */ /* Sensor page 2 MC_CMD_SENSOR_xxx */ STAT(Px, CONTROLLER_MASTER_VPTAT), /* 0x40 MASTER_VPTAT */ STAT(Px, CONTROLLER_MASTER_INTERNAL_TEMP), /* 0x41 MASTER_INT_TEMP */ STAT(Px, CONTROLLER_MASTER_VPTAT_EXT_ADC), /* 0x42 MAST_VPTAT_EXT_ADC */ STAT(Px, CONTROLLER_MASTER_INTERNAL_TEMP_EXT_ADC), /* 0x43 MASTER_INTERNAL_TEMP_EXT_ADC */ STAT(Px, CONTROLLER_SLAVE_VPTAT), /* 0x44 SLAVE_VPTAT */ STAT(Px, CONTROLLER_SLAVE_INTERNAL_TEMP), /* 0x45 SLAVE_INTERNAL_TEMP */ STAT(Px, CONTROLLER_SLAVE_VPTAT_EXT_ADC), /* 0x46 SLAVE_VPTAT_EXT_ADC */ STAT(Px, CONTROLLER_SLAVE_INTERNAL_TEMP_EXT_ADC), /* 0x47 SLAVE_INTERNAL_TEMP_EXT_ADC */ }; #define MCDI_STATIC_SENSOR_ASSERT(_field) \ EFX_STATIC_ASSERT(MC_CMD_SENSOR_STATE_ ## _field \ == EFX_MON_STAT_STATE_ ## _field) static void mcdi_mon_decode_stats( __in efx_nic_t *enp, __in_ecount(sensor_mask_size) uint32_t *sensor_mask, __in size_t sensor_mask_size, __in_opt efsys_mem_t *esmp, __out_ecount_opt(sensor_mask_size) uint32_t *stat_maskp, - __out_ecount_opt(EFX_MON_NSTATS) efx_mon_stat_value_t *stat) + __inout_ecount_opt(EFX_MON_NSTATS) efx_mon_stat_value_t *stat) { efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); uint16_t port_mask; uint16_t sensor; size_t sensor_max; uint32_t stat_mask[(EFX_ARRAY_SIZE(mcdi_sensor_map) + 31) / 32]; uint32_t idx = 0; uint32_t page = 0; /* Assert the MC_CMD_SENSOR and EFX_MON_STATE namespaces agree */ MCDI_STATIC_SENSOR_ASSERT(OK); MCDI_STATIC_SENSOR_ASSERT(WARNING); MCDI_STATIC_SENSOR_ASSERT(FATAL); MCDI_STATIC_SENSOR_ASSERT(BROKEN); MCDI_STATIC_SENSOR_ASSERT(NO_READING); EFX_STATIC_ASSERT(sizeof (stat_mask[0]) * 8 == EFX_MON_MASK_ELEMENT_SIZE); sensor_max = MIN((8 * sensor_mask_size), EFX_ARRAY_SIZE(mcdi_sensor_map)); port_mask = 1U << emip->emi_port; memset(stat_mask, 0, sizeof (stat_mask)); /* * The MCDI sensor readings in the DMA buffer are a packed array of * MC_CMD_SENSOR_VALUE_ENTRY structures, which only includes entries for * supported sensors (bit set in sensor_mask). The sensor_mask and * sensor readings do not include entries for the per-page NEXT_PAGE * flag. * * sensor_mask may legitimately contain MCDI sensors that the driver * does not understand. */ for (sensor = 0; sensor < sensor_max; ++sensor) { efx_mon_stat_t id = mcdi_sensor_map[sensor].msm_stat; if ((sensor % MCDI_MON_PAGE_SIZE) == MC_CMD_SENSOR_PAGE0_NEXT) { EFSYS_ASSERT3U(id, ==, MCDI_MON_NEXT_PAGE); page++; continue; } if (~(sensor_mask[page]) & (1U << sensor)) continue; idx++; if ((port_mask & mcdi_sensor_map[sensor].msm_port_mask) == 0) continue; EFSYS_ASSERT(id < EFX_MON_NSTATS); /* * stat_mask is a bitmask indexed by EFX_MON_* monitor statistic * identifiers from efx_mon_stat_t (without NEXT_PAGE bits). * * If there is an entry in the MCDI sensor to monitor statistic * map then the sensor reading is used for the value of the * monitor statistic. */ stat_mask[id / EFX_MON_MASK_ELEMENT_SIZE] |= (1U << (id % EFX_MON_MASK_ELEMENT_SIZE)); if (stat != NULL && esmp != NULL && !EFSYS_MEM_IS_NULL(esmp)) { efx_dword_t dword; /* Get MCDI sensor reading from DMA buffer */ EFSYS_MEM_READD(esmp, 4 * (idx - 1), &dword); /* Update EFX monitor stat from MCDI sensor reading */ stat[id].emsv_value = (uint16_t)EFX_DWORD_FIELD(dword, MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE); stat[id].emsv_state = (uint16_t)EFX_DWORD_FIELD(dword, MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE); } } if (stat_maskp != NULL) { memcpy(stat_maskp, stat_mask, sizeof (stat_mask)); } } __checkReturn int mcdi_mon_ev( __in efx_nic_t *enp, __in efx_qword_t *eqp, __out efx_mon_stat_t *idp, __out efx_mon_stat_value_t *valuep) { efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); efx_nic_cfg_t *encp = &(enp->en_nic_cfg); uint16_t port_mask; uint16_t sensor; uint16_t state; uint16_t value; efx_mon_stat_t id; int rc; port_mask = (emip->emi_port == 1) ? MCDI_MON_PORT_P1 : MCDI_MON_PORT_P2; sensor = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_MONITOR); state = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_STATE); value = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_VALUE); /* Hardware must support this MCDI sensor */ EFSYS_ASSERT3U(sensor, <, (8 * encp->enc_mcdi_sensor_mask_size)); EFSYS_ASSERT((sensor % MCDI_MON_PAGE_SIZE) != MC_CMD_SENSOR_PAGE0_NEXT); EFSYS_ASSERT(encp->enc_mcdi_sensor_maskp != NULL); EFSYS_ASSERT((encp->enc_mcdi_sensor_maskp[sensor / MCDI_MON_PAGE_SIZE] & (1U << (sensor % MCDI_MON_PAGE_SIZE))) != 0); /* But we don't have to understand it */ if (sensor >= EFX_ARRAY_SIZE(mcdi_sensor_map)) { rc = ENOTSUP; goto fail1; } id = mcdi_sensor_map[sensor].msm_stat; if ((port_mask & mcdi_sensor_map[sensor].msm_port_mask) == 0) return (ENODEV); EFSYS_ASSERT(id < EFX_MON_NSTATS); *idp = id; valuep->emsv_value = value; valuep->emsv_state = state; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } static __checkReturn int efx_mcdi_read_sensors( __in efx_nic_t *enp, __in efsys_mem_t *esmp, __in uint32_t size) { efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_READ_SENSORS_EXT_IN_LEN, MC_CMD_READ_SENSORS_EXT_OUT_LEN)]; uint32_t addr_lo, addr_hi; req.emr_cmd = MC_CMD_READ_SENSORS; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_READ_SENSORS_EXT_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_READ_SENSORS_EXT_OUT_LEN; addr_lo = (uint32_t)(EFSYS_MEM_ADDR(esmp) & 0xffffffff); addr_hi = (uint32_t)(EFSYS_MEM_ADDR(esmp) >> 32); MCDI_IN_SET_DWORD(req, READ_SENSORS_EXT_IN_DMA_ADDR_LO, addr_lo); MCDI_IN_SET_DWORD(req, READ_SENSORS_EXT_IN_DMA_ADDR_HI, addr_hi); MCDI_IN_SET_DWORD(req, READ_SENSORS_EXT_IN_LENGTH, size); efx_mcdi_execute(enp, &req); return (req.emr_rc); } static __checkReturn int efx_mcdi_sensor_info_npages( __in efx_nic_t *enp, __out uint32_t *npagesp) { efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN, MC_CMD_SENSOR_INFO_OUT_LENMAX)]; int page; int rc; EFSYS_ASSERT(npagesp != NULL); page = 0; do { (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_SENSOR_INFO; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_SENSOR_INFO_EXT_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_SENSOR_INFO_OUT_LENMAX; MCDI_IN_SET_DWORD(req, SENSOR_INFO_EXT_IN_PAGE, page++); efx_mcdi_execute_quiet(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } } while (MCDI_OUT_DWORD(req, SENSOR_INFO_OUT_MASK) & (1 << MC_CMD_SENSOR_PAGE0_NEXT)); *npagesp = page; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } static __checkReturn int efx_mcdi_sensor_info( __in efx_nic_t *enp, __out_ecount(npages) uint32_t *sensor_maskp, __in size_t npages) { efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN, MC_CMD_SENSOR_INFO_OUT_LENMAX)]; uint32_t page; int rc; EFSYS_ASSERT(sensor_maskp != NULL); for (page = 0; page < npages; page++) { uint32_t mask; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_SENSOR_INFO; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_SENSOR_INFO_EXT_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_SENSOR_INFO_OUT_LENMAX; MCDI_IN_SET_DWORD(req, SENSOR_INFO_EXT_IN_PAGE, page); efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } mask = MCDI_OUT_DWORD(req, SENSOR_INFO_OUT_MASK); if ((page != (npages - 1)) && ((mask & (1U << MC_CMD_SENSOR_PAGE0_NEXT)) == 0)) { rc = EINVAL; goto fail2; } sensor_maskp[page] = mask; } if (sensor_maskp[npages - 1] & (1U << MC_CMD_SENSOR_PAGE0_NEXT)) { rc = EINVAL; goto fail3; } return (0); fail3: EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int mcdi_mon_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values) + __inout_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); uint32_t size = encp->enc_mon_stat_dma_buf_size; int rc; if ((rc = efx_mcdi_read_sensors(enp, esmp, size)) != 0) goto fail1; EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, size); mcdi_mon_decode_stats(enp, encp->enc_mcdi_sensor_maskp, encp->enc_mcdi_sensor_mask_size, esmp, NULL, values); return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int mcdi_mon_cfg_build( __in efx_nic_t *enp) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); uint32_t npages; int rc; switch (enp->en_family) { #if EFSYS_OPT_SIENA case EFX_FAMILY_SIENA: encp->enc_mon_type = EFX_MON_SFC90X0; break; #endif #if EFSYS_OPT_HUNTINGTON case EFX_FAMILY_HUNTINGTON: encp->enc_mon_type = EFX_MON_SFC91X0; break; #endif default: rc = EINVAL; goto fail1; } /* Get mc sensor mask size */ npages = 0; if ((rc = efx_mcdi_sensor_info_npages(enp, &npages)) != 0) goto fail2; encp->enc_mon_stat_dma_buf_size = npages * EFX_MON_STATS_PAGE_SIZE; encp->enc_mcdi_sensor_mask_size = npages * sizeof (uint32_t); /* Allocate mc sensor mask */ EFSYS_KMEM_ALLOC(enp->en_esip, encp->enc_mcdi_sensor_mask_size, encp->enc_mcdi_sensor_maskp); if (encp->enc_mcdi_sensor_maskp == NULL) { rc = ENOMEM; goto fail3; } /* Read mc sensor mask */ if ((rc = efx_mcdi_sensor_info(enp, encp->enc_mcdi_sensor_maskp, npages)) != 0) goto fail4; /* Build monitor statistics mask */ mcdi_mon_decode_stats(enp, encp->enc_mcdi_sensor_maskp, encp->enc_mcdi_sensor_mask_size, NULL, encp->enc_mon_stat_mask, NULL); return (0); fail4: EFSYS_PROBE(fail4); EFSYS_KMEM_FREE(enp->en_esip, encp->enc_mcdi_sensor_mask_size, encp->enc_mcdi_sensor_maskp); fail3: EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } void mcdi_mon_cfg_free( __in efx_nic_t *enp) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); if (encp->enc_mcdi_sensor_maskp != NULL) { EFSYS_KMEM_FREE(enp->en_esip, encp->enc_mcdi_sensor_mask_size, encp->enc_mcdi_sensor_maskp); } } #endif /* EFSYS_OPT_MON_STATS */ #endif /* EFSYS_OPT_MON_MCDI */ Index: head/sys/dev/sfxge/common/mcdi_mon.h =================================================================== --- head/sys/dev/sfxge/common/mcdi_mon.h (revision 291394) +++ head/sys/dev/sfxge/common/mcdi_mon.h (revision 291395) @@ -1,76 +1,76 @@ /*- * Copyright (c) 2009-2015 Solarflare Communications Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the FreeBSD Project. * * $FreeBSD$ */ #ifndef _SYS_MCDI_MON_H #define _SYS_MCDI_MON_H #include "efx.h" #ifdef __cplusplus extern "C" { #endif #if EFSYS_OPT_MON_MCDI #if EFSYS_OPT_MON_STATS __checkReturn int mcdi_mon_cfg_build( __in efx_nic_t *enp); void mcdi_mon_cfg_free( __in efx_nic_t *enp); extern __checkReturn int mcdi_mon_ev( __in efx_nic_t *enp, __in efx_qword_t *eqp, __out efx_mon_stat_t *idp, __out efx_mon_stat_value_t *valuep); extern __checkReturn int mcdi_mon_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values); + __inout_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values); #endif /* EFSYS_OPT_MON_STATS */ #endif /* EFSYS_OPT_MON_MCDI */ #ifdef __cplusplus } #endif #endif /* _SYS_MCDI_MON_H */ Index: head/sys/dev/sfxge/common/siena_impl.h =================================================================== --- head/sys/dev/sfxge/common/siena_impl.h (revision 291394) +++ head/sys/dev/sfxge/common/siena_impl.h (revision 291395) @@ -1,484 +1,484 @@ /*- * Copyright (c) 2009-2015 Solarflare Communications Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the FreeBSD Project. * * $FreeBSD$ */ #ifndef _SYS_SIENA_IMPL_H #define _SYS_SIENA_IMPL_H #include "efx.h" #include "efx_regs.h" #include "efx_mcdi.h" #include "siena_flash.h" #ifdef __cplusplus extern "C" { #endif #if EFSYS_OPT_PHY_PROPS /* START MKCONFIG GENERATED SienaPhyHeaderPropsBlock a8db1f8eb5106efd */ typedef enum siena_phy_prop_e { SIENA_PHY_NPROPS } siena_phy_prop_t; /* END MKCONFIG GENERATED SienaPhyHeaderPropsBlock */ #endif /* EFSYS_OPT_PHY_PROPS */ #define SIENA_NVRAM_CHUNK 0x80 extern __checkReturn int siena_nic_probe( __in efx_nic_t *enp); #if EFSYS_OPT_PCIE_TUNE extern __checkReturn int siena_nic_pcie_extended_sync( __in efx_nic_t *enp); #endif extern __checkReturn int siena_nic_reset( __in efx_nic_t *enp); extern __checkReturn int siena_nic_init( __in efx_nic_t *enp); #if EFSYS_OPT_DIAG extern __checkReturn int siena_nic_register_test( __in efx_nic_t *enp); #endif /* EFSYS_OPT_DIAG */ extern void siena_nic_fini( __in efx_nic_t *enp); extern void siena_nic_unprobe( __in efx_nic_t *enp); #define SIENA_SRAM_ROWS 0x12000 extern void siena_sram_init( __in efx_nic_t *enp); #if EFSYS_OPT_DIAG extern __checkReturn int siena_sram_test( __in efx_nic_t *enp, __in efx_sram_pattern_fn_t func); #endif /* EFSYS_OPT_DIAG */ #if EFSYS_OPT_MCDI extern __checkReturn int siena_mcdi_init( __in efx_nic_t *enp, __in const efx_mcdi_transport_t *mtp); extern void siena_mcdi_request_copyin( __in efx_nic_t *enp, __in efx_mcdi_req_t *emrp, __in unsigned int seq, __in boolean_t ev_cpl, __in boolean_t new_epoch); extern __checkReturn boolean_t siena_mcdi_request_poll( __in efx_nic_t *enp); extern void siena_mcdi_request_copyout( __in efx_nic_t *enp, __in efx_mcdi_req_t *emrp); extern int siena_mcdi_poll_reboot( __in efx_nic_t *enp); extern void siena_mcdi_fini( __in efx_nic_t *enp); extern __checkReturn int siena_mcdi_fw_update_supported( __in efx_nic_t *enp, __out boolean_t *supportedp); extern __checkReturn int siena_mcdi_macaddr_change_supported( __in efx_nic_t *enp, __out boolean_t *supportedp); #endif /* EFSYS_OPT_MCDI */ #if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD extern __checkReturn int siena_nvram_partn_size( __in efx_nic_t *enp, __in unsigned int partn, __out size_t *sizep); extern __checkReturn int siena_nvram_partn_lock( __in efx_nic_t *enp, __in unsigned int partn); extern __checkReturn int siena_nvram_partn_read( __in efx_nic_t *enp, __in unsigned int partn, __in unsigned int offset, __out_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int siena_nvram_partn_erase( __in efx_nic_t *enp, __in unsigned int partn, __in unsigned int offset, __in size_t size); extern __checkReturn int siena_nvram_partn_write( __in efx_nic_t *enp, __in unsigned int partn, __in unsigned int offset, __out_bcount(size) caddr_t data, __in size_t size); extern void siena_nvram_partn_unlock( __in efx_nic_t *enp, __in unsigned int partn); extern __checkReturn int siena_nvram_get_dynamic_cfg( __in efx_nic_t *enp, __in unsigned int index, __in boolean_t vpd, __out siena_mc_dynamic_config_hdr_t **dcfgp, __out size_t *sizep); #endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */ #if EFSYS_OPT_NVRAM #if EFSYS_OPT_DIAG extern __checkReturn int siena_nvram_test( __in efx_nic_t *enp); #endif /* EFSYS_OPT_DIAG */ extern __checkReturn int siena_nvram_size( __in efx_nic_t *enp, __in efx_nvram_type_t type, __out size_t *sizep); extern __checkReturn int siena_nvram_get_subtype( __in efx_nic_t *enp, __in unsigned int partn, __out uint32_t *subtypep); extern __checkReturn int siena_nvram_get_version( __in efx_nic_t *enp, __in efx_nvram_type_t type, __out uint32_t *subtypep, __out_ecount(4) uint16_t version[4]); extern __checkReturn int siena_nvram_rw_start( __in efx_nic_t *enp, __in efx_nvram_type_t type, __out size_t *pref_chunkp); extern __checkReturn int siena_nvram_read_chunk( __in efx_nic_t *enp, __in efx_nvram_type_t type, __in unsigned int offset, __out_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int siena_nvram_erase( __in efx_nic_t *enp, __in efx_nvram_type_t type); extern __checkReturn int siena_nvram_write_chunk( __in efx_nic_t *enp, __in efx_nvram_type_t type, __in unsigned int offset, __in_bcount(size) caddr_t data, __in size_t size); extern void siena_nvram_rw_finish( __in efx_nic_t *enp, __in efx_nvram_type_t type); extern __checkReturn int siena_nvram_set_version( __in efx_nic_t *enp, __in efx_nvram_type_t type, __in_ecount(4) uint16_t version[4]); #endif /* EFSYS_OPT_NVRAM */ #if EFSYS_OPT_VPD extern __checkReturn int siena_vpd_init( __in efx_nic_t *enp); extern __checkReturn int siena_vpd_size( __in efx_nic_t *enp, __out size_t *sizep); extern __checkReturn int siena_vpd_read( __in efx_nic_t *enp, __out_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int siena_vpd_verify( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int siena_vpd_reinit( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size); extern __checkReturn int siena_vpd_get( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size, __inout efx_vpd_value_t *evvp); extern __checkReturn int siena_vpd_set( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size, __in efx_vpd_value_t *evvp); extern __checkReturn int siena_vpd_next( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size, __out efx_vpd_value_t *evvp, __inout unsigned int *contp); extern __checkReturn int siena_vpd_write( __in efx_nic_t *enp, __in_bcount(size) caddr_t data, __in size_t size); extern void siena_vpd_fini( __in efx_nic_t *enp); #endif /* EFSYS_OPT_VPD */ typedef struct siena_link_state_s { uint32_t sls_adv_cap_mask; uint32_t sls_lp_cap_mask; unsigned int sls_fcntl; efx_link_mode_t sls_link_mode; #if EFSYS_OPT_LOOPBACK efx_loopback_type_t sls_loopback; #endif boolean_t sls_mac_up; } siena_link_state_t; extern void siena_phy_link_ev( __in efx_nic_t *enp, __in efx_qword_t *eqp, __out efx_link_mode_t *link_modep); extern __checkReturn int siena_phy_get_link( __in efx_nic_t *enp, __out siena_link_state_t *slsp); extern __checkReturn int siena_phy_power( __in efx_nic_t *enp, __in boolean_t on); extern __checkReturn int siena_phy_reconfigure( __in efx_nic_t *enp); extern __checkReturn int siena_phy_verify( __in efx_nic_t *enp); extern __checkReturn int siena_phy_oui_get( __in efx_nic_t *enp, __out uint32_t *ouip); #if EFSYS_OPT_PHY_STATS extern void siena_phy_decode_stats( __in efx_nic_t *enp, __in uint32_t vmask, __in_opt efsys_mem_t *esmp, __out_opt uint64_t *smaskp, __out_ecount_opt(EFX_PHY_NSTATS) uint32_t *stat); extern __checkReturn int siena_phy_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, __out_ecount(EFX_PHY_NSTATS) uint32_t *stat); #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES extern const char * siena_phy_prop_name( __in efx_nic_t *enp, __in unsigned int id); #endif /* EFSYS_OPT_NAMES */ extern __checkReturn int siena_phy_prop_get( __in efx_nic_t *enp, __in unsigned int id, __in uint32_t flags, __out uint32_t *valp); extern __checkReturn int siena_phy_prop_set( __in efx_nic_t *enp, __in unsigned int id, __in uint32_t val); #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_BIST extern __checkReturn int siena_phy_bist_start( __in efx_nic_t *enp, __in efx_bist_type_t type); extern __checkReturn int siena_phy_bist_poll( __in efx_nic_t *enp, __in efx_bist_type_t type, __out efx_bist_result_t *resultp, __out_opt __drv_when(count > 0, __notnull) uint32_t *value_maskp, __out_ecount_opt(count) __drv_when(count > 0, __notnull) unsigned long *valuesp, __in size_t count); extern void siena_phy_bist_stop( __in efx_nic_t *enp, __in efx_bist_type_t type); #endif /* EFSYS_OPT_BIST */ extern __checkReturn int siena_mac_poll( __in efx_nic_t *enp, __out efx_link_mode_t *link_modep); extern __checkReturn int siena_mac_up( __in efx_nic_t *enp, __out boolean_t *mac_upp); extern __checkReturn int siena_mac_reconfigure( __in efx_nic_t *enp); #if EFSYS_OPT_LOOPBACK extern __checkReturn int siena_mac_loopback_set( __in efx_nic_t *enp, __in efx_link_mode_t link_mode, __in efx_loopback_type_t loopback_type); #endif /* EFSYS_OPT_LOOPBACK */ #if EFSYS_OPT_MAC_STATS extern __checkReturn int siena_mac_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __out_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, + __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, __out_opt uint32_t *generationp); #endif /* EFSYS_OPT_MAC_STATS */ #ifdef __cplusplus } #endif #endif /* _SYS_SIENA_IMPL_H */ Index: head/sys/dev/sfxge/common/siena_mac.c =================================================================== --- head/sys/dev/sfxge/common/siena_mac.c (revision 291394) +++ head/sys/dev/sfxge/common/siena_mac.c (revision 291395) @@ -1,436 +1,436 @@ /*- * Copyright (c) 2009-2015 Solarflare Communications Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the FreeBSD Project. */ #include __FBSDID("$FreeBSD$"); #include "efsys.h" #include "efx.h" #include "efx_impl.h" #if EFSYS_OPT_SIENA __checkReturn int siena_mac_poll( __in efx_nic_t *enp, __out efx_link_mode_t *link_modep) { efx_port_t *epp = &(enp->en_port); siena_link_state_t sls; int rc; if ((rc = siena_phy_get_link(enp, &sls)) != 0) goto fail1; epp->ep_adv_cap_mask = sls.sls_adv_cap_mask; epp->ep_fcntl = sls.sls_fcntl; *link_modep = sls.sls_link_mode; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); *link_modep = EFX_LINK_UNKNOWN; return (rc); } __checkReturn int siena_mac_up( __in efx_nic_t *enp, __out boolean_t *mac_upp) { siena_link_state_t sls; int rc; /* * Because Siena doesn't *require* polling, we can't rely on * siena_mac_poll() being executed to populate epp->ep_mac_up. */ if ((rc = siena_phy_get_link(enp, &sls)) != 0) goto fail1; *mac_upp = sls.sls_mac_up; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int siena_mac_reconfigure( __in efx_nic_t *enp) { efx_port_t *epp = &(enp->en_port); efx_oword_t multicast_hash[2]; efx_mcdi_req_t req; uint8_t payload[MAX(MAX(MC_CMD_SET_MAC_IN_LEN, MC_CMD_SET_MAC_OUT_LEN), MAX(MC_CMD_SET_MCAST_HASH_IN_LEN, MC_CMD_SET_MCAST_HASH_OUT_LEN))]; unsigned int fcntl; int rc; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_SET_MAC; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_SET_MAC_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN; MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu); MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0); EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR), epp->ep_mac_addr); MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT, SET_MAC_IN_REJECT_UNCST, !epp->ep_all_unicst, SET_MAC_IN_REJECT_BRDCST, !epp->ep_brdcst); if (epp->ep_fcntl_autoneg) /* efx_fcntl_set() has already set the phy capabilities */ fcntl = MC_CMD_FCNTL_AUTO; else if (epp->ep_fcntl & EFX_FCNTL_RESPOND) fcntl = (epp->ep_fcntl & EFX_FCNTL_GENERATE) ? MC_CMD_FCNTL_BIDIR : MC_CMD_FCNTL_RESPOND; else fcntl = MC_CMD_FCNTL_OFF; MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, fcntl); efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } /* Push multicast hash */ if (epp->ep_all_mulcst) { /* A hash matching all multicast is all 1s */ EFX_SET_OWORD(multicast_hash[0]); EFX_SET_OWORD(multicast_hash[1]); } else if (epp->ep_mulcst) { /* Use the hash set by the multicast list */ multicast_hash[0] = epp->ep_multicst_hash[0]; multicast_hash[1] = epp->ep_multicst_hash[1]; } else { /* A hash matching no traffic is simply 0 */ EFX_ZERO_OWORD(multicast_hash[0]); EFX_ZERO_OWORD(multicast_hash[1]); } /* * Broadcast packets go through the multicast hash filter. * The IEEE 802.3 CRC32 of the broadcast address is 0xbe2612ff * so we always add bit 0xff to the mask (bit 0x7f in the * second octword). */ if (epp->ep_brdcst) EFX_SET_OWORD_BIT(multicast_hash[1], 0x7f); (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_SET_MCAST_HASH; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_SET_MCAST_HASH_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_SET_MCAST_HASH_OUT_LEN; memcpy(MCDI_IN2(req, uint8_t, SET_MCAST_HASH_IN_HASH0), multicast_hash, sizeof (multicast_hash)); efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail2; } return (0); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } #if EFSYS_OPT_LOOPBACK __checkReturn int siena_mac_loopback_set( __in efx_nic_t *enp, __in efx_link_mode_t link_mode, __in efx_loopback_type_t loopback_type) { efx_port_t *epp = &(enp->en_port); efx_phy_ops_t *epop = epp->ep_epop; efx_loopback_type_t old_loopback_type; efx_link_mode_t old_loopback_link_mode; int rc; /* The PHY object handles this on Siena */ old_loopback_type = epp->ep_loopback_type; old_loopback_link_mode = epp->ep_loopback_link_mode; epp->ep_loopback_type = loopback_type; epp->ep_loopback_link_mode = link_mode; if ((rc = epop->epo_reconfigure(enp)) != 0) goto fail1; return (0); fail1: EFSYS_PROBE(fail2); epp->ep_loopback_type = old_loopback_type; epp->ep_loopback_link_mode = old_loopback_link_mode; return (rc); } #endif /* EFSYS_OPT_LOOPBACK */ #if EFSYS_OPT_MAC_STATS #define SIENA_MAC_STAT_READ(_esmp, _field, _eqp) \ EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp) __checkReturn int siena_mac_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __out_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, + __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, __out_opt uint32_t *generationp) { efx_qword_t value; efx_qword_t generation_start; efx_qword_t generation_end; _NOTE(ARGUNUSED(enp)) /* Read END first so we don't race with the MC */ EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END, &generation_end); EFSYS_MEM_READ_BARRIER(); /* TX */ SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value); EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value); EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value); EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value); /* RX */ SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value); EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value); EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]), &(value.eq_dword[0])); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]), &(value.eq_dword[1])); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]), &(value.eq_dword[0])); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]), &(value.eq_dword[1])); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]), &(value.eq_dword[0])); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]), &(value.eq_dword[1])); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]), &(value.eq_dword[0])); EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]), &(value.eq_dword[1])); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value); EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value); EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE); EFSYS_MEM_READ_BARRIER(); SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START, &generation_start); /* Check that we didn't read the stats in the middle of a DMA */ /* Not a good enough check ? */ if (memcmp(&generation_start, &generation_end, sizeof (generation_start))) return (EAGAIN); if (generationp) *generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0); return (0); } #endif /* EFSYS_OPT_MAC_STATS */ #endif /* EFSYS_OPT_SIENA */ Index: head/sys/dev/sfxge/common/siena_phy.c =================================================================== --- head/sys/dev/sfxge/common/siena_phy.c (revision 291394) +++ head/sys/dev/sfxge/common/siena_phy.c (revision 291395) @@ -1,842 +1,842 @@ /*- * Copyright (c) 2009-2015 Solarflare Communications Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the FreeBSD Project. */ #include __FBSDID("$FreeBSD$"); #include "efsys.h" #include "efx.h" #include "efx_impl.h" #if EFSYS_OPT_SIENA static void siena_phy_decode_cap( __in uint32_t mcdi_cap, __out uint32_t *maskp) { uint32_t mask; mask = 0; if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN)) mask |= (1 << EFX_PHY_CAP_10HDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN)) mask |= (1 << EFX_PHY_CAP_10FDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN)) mask |= (1 << EFX_PHY_CAP_100HDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN)) mask |= (1 << EFX_PHY_CAP_100FDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN)) mask |= (1 << EFX_PHY_CAP_1000HDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN)) mask |= (1 << EFX_PHY_CAP_1000FDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN)) mask |= (1 << EFX_PHY_CAP_10000FDX); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN)) mask |= (1 << EFX_PHY_CAP_PAUSE); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN)) mask |= (1 << EFX_PHY_CAP_ASYM); if (mcdi_cap & (1 << MC_CMD_PHY_CAP_AN_LBN)) mask |= (1 << EFX_PHY_CAP_AN); *maskp = mask; } static void siena_phy_decode_link_mode( __in efx_nic_t *enp, __in uint32_t link_flags, __in unsigned int speed, __in unsigned int fcntl, __out efx_link_mode_t *link_modep, __out unsigned int *fcntlp) { boolean_t fd = !!(link_flags & (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN)); boolean_t up = !!(link_flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN)); _NOTE(ARGUNUSED(enp)) if (!up) *link_modep = EFX_LINK_DOWN; else if (speed == 10000 && fd) *link_modep = EFX_LINK_10000FDX; else if (speed == 1000) *link_modep = fd ? EFX_LINK_1000FDX : EFX_LINK_1000HDX; else if (speed == 100) *link_modep = fd ? EFX_LINK_100FDX : EFX_LINK_100HDX; else if (speed == 10) *link_modep = fd ? EFX_LINK_10FDX : EFX_LINK_10HDX; else *link_modep = EFX_LINK_UNKNOWN; if (fcntl == MC_CMD_FCNTL_OFF) *fcntlp = 0; else if (fcntl == MC_CMD_FCNTL_RESPOND) *fcntlp = EFX_FCNTL_RESPOND; else if (fcntl == MC_CMD_FCNTL_BIDIR) *fcntlp = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE; else { EFSYS_PROBE1(mc_pcol_error, int, fcntl); *fcntlp = 0; } } void siena_phy_link_ev( __in efx_nic_t *enp, __in efx_qword_t *eqp, __out efx_link_mode_t *link_modep) { efx_port_t *epp = &(enp->en_port); unsigned int link_flags; unsigned int speed; unsigned int fcntl; efx_link_mode_t link_mode; uint32_t lp_cap_mask; /* * Convert the LINKCHANGE speed enumeration into mbit/s, in the * same way as GET_LINK encodes the speed */ switch (MCDI_EV_FIELD(eqp, LINKCHANGE_SPEED)) { case MCDI_EVENT_LINKCHANGE_SPEED_100M: speed = 100; break; case MCDI_EVENT_LINKCHANGE_SPEED_1G: speed = 1000; break; case MCDI_EVENT_LINKCHANGE_SPEED_10G: speed = 10000; break; default: speed = 0; break; } link_flags = MCDI_EV_FIELD(eqp, LINKCHANGE_LINK_FLAGS); siena_phy_decode_link_mode(enp, link_flags, speed, MCDI_EV_FIELD(eqp, LINKCHANGE_FCNTL), &link_mode, &fcntl); siena_phy_decode_cap(MCDI_EV_FIELD(eqp, LINKCHANGE_LP_CAP), &lp_cap_mask); /* * It's safe to update ep_lp_cap_mask without the driver's port lock * because presumably any concurrently running efx_port_poll() is * only going to arrive at the same value. * * ep_fcntl has two meanings. It's either the link common fcntl * (if the PHY supports AN), or it's the forced link state. If * the former, it's safe to update the value for the same reason as * for ep_lp_cap_mask. If the latter, then just ignore the value, * because we can race with efx_mac_fcntl_set(). */ epp->ep_lp_cap_mask = lp_cap_mask; if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) epp->ep_fcntl = fcntl; *link_modep = link_mode; } __checkReturn int siena_phy_power( __in efx_nic_t *enp, __in boolean_t power) { int rc; if (!power) return (0); /* Check if the PHY is a zombie */ if ((rc = siena_phy_verify(enp)) != 0) goto fail1; enp->en_reset_flags |= EFX_RESET_PHY; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int siena_phy_get_link( __in efx_nic_t *enp, __out siena_link_state_t *slsp) { efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_GET_LINK_IN_LEN, MC_CMD_GET_LINK_OUT_LEN)]; int rc; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_GET_LINK; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_GET_LINK_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_GET_LINK_OUT_LEN; efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } if (req.emr_out_length_used < MC_CMD_GET_LINK_OUT_LEN) { rc = EMSGSIZE; goto fail2; } siena_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_CAP), &slsp->sls_adv_cap_mask); siena_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_LP_CAP), &slsp->sls_lp_cap_mask); siena_phy_decode_link_mode(enp, MCDI_OUT_DWORD(req, GET_LINK_OUT_FLAGS), MCDI_OUT_DWORD(req, GET_LINK_OUT_LINK_SPEED), MCDI_OUT_DWORD(req, GET_LINK_OUT_FCNTL), &slsp->sls_link_mode, &slsp->sls_fcntl); #if EFSYS_OPT_LOOPBACK /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS); EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD); slsp->sls_loopback = MCDI_OUT_DWORD(req, GET_LINK_OUT_LOOPBACK_MODE); #endif /* EFSYS_OPT_LOOPBACK */ slsp->sls_mac_up = MCDI_OUT_DWORD(req, GET_LINK_OUT_MAC_FAULT) == 0; return (0); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int siena_phy_reconfigure( __in efx_nic_t *enp) { efx_port_t *epp = &(enp->en_port); efx_mcdi_req_t req; uint8_t payload[MAX(MAX(MC_CMD_SET_ID_LED_IN_LEN, MC_CMD_SET_ID_LED_OUT_LEN), MAX(MC_CMD_SET_LINK_IN_LEN, MC_CMD_SET_LINK_OUT_LEN))]; uint32_t cap_mask; unsigned int led_mode; unsigned int speed; int rc; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_SET_LINK; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_SET_LINK_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_SET_LINK_OUT_LEN; cap_mask = epp->ep_adv_cap_mask; MCDI_IN_POPULATE_DWORD_10(req, SET_LINK_IN_CAP, PHY_CAP_10HDX, (cap_mask >> EFX_PHY_CAP_10HDX) & 0x1, PHY_CAP_10FDX, (cap_mask >> EFX_PHY_CAP_10FDX) & 0x1, PHY_CAP_100HDX, (cap_mask >> EFX_PHY_CAP_100HDX) & 0x1, PHY_CAP_100FDX, (cap_mask >> EFX_PHY_CAP_100FDX) & 0x1, PHY_CAP_1000HDX, (cap_mask >> EFX_PHY_CAP_1000HDX) & 0x1, PHY_CAP_1000FDX, (cap_mask >> EFX_PHY_CAP_1000FDX) & 0x1, PHY_CAP_10000FDX, (cap_mask >> EFX_PHY_CAP_10000FDX) & 0x1, PHY_CAP_PAUSE, (cap_mask >> EFX_PHY_CAP_PAUSE) & 0x1, PHY_CAP_ASYM, (cap_mask >> EFX_PHY_CAP_ASYM) & 0x1, PHY_CAP_AN, (cap_mask >> EFX_PHY_CAP_AN) & 0x1); #if EFSYS_OPT_LOOPBACK MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE, epp->ep_loopback_type); switch (epp->ep_loopback_link_mode) { case EFX_LINK_100FDX: speed = 100; break; case EFX_LINK_1000FDX: speed = 1000; break; case EFX_LINK_10000FDX: speed = 10000; break; default: speed = 0; } #else MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE, MC_CMD_LOOPBACK_NONE); speed = 0; #endif /* EFSYS_OPT_LOOPBACK */ MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_SPEED, speed); #if EFSYS_OPT_PHY_FLAGS MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, epp->ep_phy_flags); #else MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, 0); #endif /* EFSYS_OPT_PHY_FLAGS */ efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } /* And set the blink mode */ (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_SET_ID_LED; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_SET_ID_LED_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_SET_ID_LED_OUT_LEN; #if EFSYS_OPT_PHY_LED_CONTROL switch (epp->ep_phy_led_mode) { case EFX_PHY_LED_DEFAULT: led_mode = MC_CMD_LED_DEFAULT; break; case EFX_PHY_LED_OFF: led_mode = MC_CMD_LED_OFF; break; case EFX_PHY_LED_ON: led_mode = MC_CMD_LED_ON; break; default: EFSYS_ASSERT(0); led_mode = MC_CMD_LED_DEFAULT; } MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, led_mode); #else MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, MC_CMD_LED_DEFAULT); #endif /* EFSYS_OPT_PHY_LED_CONTROL */ efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail2; } return (0); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int siena_phy_verify( __in efx_nic_t *enp) { efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_GET_PHY_STATE_IN_LEN, MC_CMD_GET_PHY_STATE_OUT_LEN)]; uint32_t state; int rc; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_GET_PHY_STATE; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_GET_PHY_STATE_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_GET_PHY_STATE_OUT_LEN; efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } if (req.emr_out_length_used < MC_CMD_GET_PHY_STATE_OUT_LEN) { rc = EMSGSIZE; goto fail2; } state = MCDI_OUT_DWORD(req, GET_PHY_STATE_OUT_STATE); if (state != MC_CMD_PHY_STATE_OK) { if (state != MC_CMD_PHY_STATE_ZOMBIE) EFSYS_PROBE1(mc_pcol_error, int, state); rc = ENOTACTIVE; goto fail3; } return (0); fail3: EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } __checkReturn int siena_phy_oui_get( __in efx_nic_t *enp, __out uint32_t *ouip) { _NOTE(ARGUNUSED(enp, ouip)) return (ENOTSUP); } #if EFSYS_OPT_PHY_STATS #define SIENA_SIMPLE_STAT_SET(_vmask, _esmp, _smask, _stat, \ _mc_record, _efx_record) \ if ((_vmask) & (1ULL << (_mc_record))) { \ (_smask) |= (1ULL << (_efx_record)); \ if ((_stat) != NULL && !EFSYS_MEM_IS_NULL(_esmp)) { \ efx_dword_t dword; \ EFSYS_MEM_READD(_esmp, (_mc_record) * 4, &dword);\ (_stat)[_efx_record] = \ EFX_DWORD_FIELD(dword, EFX_DWORD_0); \ } \ } #define SIENA_SIMPLE_STAT_SET2(_vmask, _esmp, _smask, _stat, _record) \ SIENA_SIMPLE_STAT_SET(_vmask, _esmp, _smask, _stat, \ MC_CMD_ ## _record, \ EFX_PHY_STAT_ ## _record) void siena_phy_decode_stats( __in efx_nic_t *enp, __in uint32_t vmask, __in_opt efsys_mem_t *esmp, __out_opt uint64_t *smaskp, - __out_ecount_opt(EFX_PHY_NSTATS) uint32_t *stat) + __inout_ecount_opt(EFX_PHY_NSTATS) uint32_t *stat) { uint64_t smask = 0; _NOTE(ARGUNUSED(enp)) SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, OUI); SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PMA_PMD_LINK_UP); SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PMA_PMD_RX_FAULT); SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PMA_PMD_TX_FAULT); if (vmask & (1 << MC_CMD_PMA_PMD_SIGNAL)) { smask |= ((1ULL << EFX_PHY_STAT_PMA_PMD_SIGNAL_A) | (1ULL << EFX_PHY_STAT_PMA_PMD_SIGNAL_B) | (1ULL << EFX_PHY_STAT_PMA_PMD_SIGNAL_C) | (1ULL << EFX_PHY_STAT_PMA_PMD_SIGNAL_D)); if (stat != NULL && esmp != NULL && !EFSYS_MEM_IS_NULL(esmp)) { efx_dword_t dword; uint32_t sig; EFSYS_MEM_READD(esmp, 4 * MC_CMD_PMA_PMD_SIGNAL, &dword); sig = EFX_DWORD_FIELD(dword, EFX_DWORD_0); stat[EFX_PHY_STAT_PMA_PMD_SIGNAL_A] = (sig >> 1) & 1; stat[EFX_PHY_STAT_PMA_PMD_SIGNAL_B] = (sig >> 2) & 1; stat[EFX_PHY_STAT_PMA_PMD_SIGNAL_C] = (sig >> 3) & 1; stat[EFX_PHY_STAT_PMA_PMD_SIGNAL_D] = (sig >> 4) & 1; } } SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PMA_PMD_SNR_A, EFX_PHY_STAT_SNR_A); SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PMA_PMD_SNR_B, EFX_PHY_STAT_SNR_B); SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PMA_PMD_SNR_C, EFX_PHY_STAT_SNR_C); SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PMA_PMD_SNR_D, EFX_PHY_STAT_SNR_D); SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PCS_LINK_UP); SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PCS_RX_FAULT); SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PCS_TX_FAULT); SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PCS_BER); SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, PCS_BLOCK_ERRORS); SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PHYXS_LINK_UP, EFX_PHY_STAT_PHY_XS_LINK_UP); SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PHYXS_RX_FAULT, EFX_PHY_STAT_PHY_XS_RX_FAULT); SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PHYXS_TX_FAULT, EFX_PHY_STAT_PHY_XS_TX_FAULT); SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_PHYXS_ALIGN, EFX_PHY_STAT_PHY_XS_ALIGN); if (vmask & (1 << MC_CMD_PHYXS_SYNC)) { smask |= ((1 << EFX_PHY_STAT_PHY_XS_SYNC_A) | (1 << EFX_PHY_STAT_PHY_XS_SYNC_B) | (1 << EFX_PHY_STAT_PHY_XS_SYNC_C) | (1 << EFX_PHY_STAT_PHY_XS_SYNC_D)); if (stat != NULL && !EFSYS_MEM_IS_NULL(esmp)) { efx_dword_t dword; uint32_t sync; EFSYS_MEM_READD(esmp, 4 * MC_CMD_PHYXS_SYNC, &dword); sync = EFX_DWORD_FIELD(dword, EFX_DWORD_0); stat[EFX_PHY_STAT_PHY_XS_SYNC_A] = (sync >> 0) & 1; stat[EFX_PHY_STAT_PHY_XS_SYNC_B] = (sync >> 1) & 1; stat[EFX_PHY_STAT_PHY_XS_SYNC_C] = (sync >> 2) & 1; stat[EFX_PHY_STAT_PHY_XS_SYNC_D] = (sync >> 3) & 1; } } SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, AN_LINK_UP); SIENA_SIMPLE_STAT_SET2(vmask, esmp, smask, stat, AN_COMPLETE); SIENA_SIMPLE_STAT_SET(vmask, esmp, smask, stat, MC_CMD_CL22_LINK_UP, EFX_PHY_STAT_CL22EXT_LINK_UP); if (smaskp != NULL) *smaskp = smask; } __checkReturn int siena_phy_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, - __out_ecount(EFX_PHY_NSTATS) uint32_t *stat) + __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); uint32_t vmask = encp->enc_mcdi_phy_stat_mask; uint64_t smask; efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_PHY_STATS_IN_LEN, MC_CMD_PHY_STATS_OUT_DMA_LEN)]; int rc; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_PHY_STATS; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_PHY_STATS_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_PHY_STATS_OUT_DMA_LEN; MCDI_IN_SET_DWORD(req, PHY_STATS_IN_DMA_ADDR_LO, EFSYS_MEM_ADDR(esmp) & 0xffffffff); MCDI_IN_SET_DWORD(req, PHY_STATS_IN_DMA_ADDR_HI, EFSYS_MEM_ADDR(esmp) >> 32); efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } EFSYS_ASSERT3U(req.emr_out_length, ==, MC_CMD_PHY_STATS_OUT_DMA_LEN); siena_phy_decode_stats(enp, vmask, esmp, &smask, stat); EFSYS_ASSERT(smask == encp->enc_phy_stat_mask); return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (0); } #endif /* EFSYS_OPT_PHY_STATS */ #if EFSYS_OPT_PHY_PROPS #if EFSYS_OPT_NAMES extern const char * siena_phy_prop_name( __in efx_nic_t *enp, __in unsigned int id) { _NOTE(ARGUNUSED(enp, id)) return (NULL); } #endif /* EFSYS_OPT_NAMES */ extern __checkReturn int siena_phy_prop_get( __in efx_nic_t *enp, __in unsigned int id, __in uint32_t flags, __out uint32_t *valp) { _NOTE(ARGUNUSED(enp, id, flags, valp)) return (ENOTSUP); } extern __checkReturn int siena_phy_prop_set( __in efx_nic_t *enp, __in unsigned int id, __in uint32_t val) { _NOTE(ARGUNUSED(enp, id, val)) return (ENOTSUP); } #endif /* EFSYS_OPT_PHY_PROPS */ #if EFSYS_OPT_BIST __checkReturn int siena_phy_bist_start( __in efx_nic_t *enp, __in efx_bist_type_t type) { int rc; if ((rc = efx_mcdi_bist_start(enp, type)) != 0) goto fail1; return (0); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } static __checkReturn unsigned long siena_phy_sft9001_bist_status( __in uint16_t code) { switch (code) { case MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY: return (EFX_PHY_CABLE_STATUS_BUSY); case MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT: return (EFX_PHY_CABLE_STATUS_INTERPAIRSHORT); case MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT: return (EFX_PHY_CABLE_STATUS_INTRAPAIRSHORT); case MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN: return (EFX_PHY_CABLE_STATUS_OPEN); case MC_CMD_POLL_BIST_SFT9001_PAIR_OK: return (EFX_PHY_CABLE_STATUS_OK); default: return (EFX_PHY_CABLE_STATUS_INVALID); } } __checkReturn int siena_phy_bist_poll( __in efx_nic_t *enp, __in efx_bist_type_t type, __out efx_bist_result_t *resultp, __out_opt __drv_when(count > 0, __notnull) uint32_t *value_maskp, __out_ecount_opt(count) __drv_when(count > 0, __notnull) unsigned long *valuesp, __in size_t count) { efx_nic_cfg_t *encp = &(enp->en_nic_cfg); uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN, MCDI_CTL_SDU_LEN_MAX)]; uint32_t value_mask = 0; efx_mcdi_req_t req; uint32_t result; int rc; (void) memset(payload, 0, sizeof (payload)); req.emr_cmd = MC_CMD_POLL_BIST; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MCDI_CTL_SDU_LEN_MAX; efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } if (req.emr_out_length_used < MC_CMD_POLL_BIST_OUT_RESULT_OFST + 4) { rc = EMSGSIZE; goto fail2; } if (count > 0) (void) memset(valuesp, '\0', count * sizeof (unsigned long)); result = MCDI_OUT_DWORD(req, POLL_BIST_OUT_RESULT); /* Extract PHY specific results */ if (result == MC_CMD_POLL_BIST_PASSED && encp->enc_phy_type == EFX_PHY_SFT9001B && req.emr_out_length_used >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN && (type == EFX_BIST_TYPE_PHY_CABLE_SHORT || type == EFX_BIST_TYPE_PHY_CABLE_LONG)) { uint16_t word; if (count > EFX_BIST_PHY_CABLE_LENGTH_A) { if (valuesp != NULL) valuesp[EFX_BIST_PHY_CABLE_LENGTH_A] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A); value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_A); } if (count > EFX_BIST_PHY_CABLE_LENGTH_B) { if (valuesp != NULL) valuesp[EFX_BIST_PHY_CABLE_LENGTH_B] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B); value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_B); } if (count > EFX_BIST_PHY_CABLE_LENGTH_C) { if (valuesp != NULL) valuesp[EFX_BIST_PHY_CABLE_LENGTH_C] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C); value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_C); } if (count > EFX_BIST_PHY_CABLE_LENGTH_D) { if (valuesp != NULL) valuesp[EFX_BIST_PHY_CABLE_LENGTH_D] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D); value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_D); } if (count > EFX_BIST_PHY_CABLE_STATUS_A) { if (valuesp != NULL) { word = MCDI_OUT_WORD(req, POLL_BIST_OUT_SFT9001_CABLE_STATUS_A); valuesp[EFX_BIST_PHY_CABLE_STATUS_A] = siena_phy_sft9001_bist_status(word); } value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_A); } if (count > EFX_BIST_PHY_CABLE_STATUS_B) { if (valuesp != NULL) { word = MCDI_OUT_WORD(req, POLL_BIST_OUT_SFT9001_CABLE_STATUS_B); valuesp[EFX_BIST_PHY_CABLE_STATUS_B] = siena_phy_sft9001_bist_status(word); } value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_B); } if (count > EFX_BIST_PHY_CABLE_STATUS_C) { if (valuesp != NULL) { word = MCDI_OUT_WORD(req, POLL_BIST_OUT_SFT9001_CABLE_STATUS_C); valuesp[EFX_BIST_PHY_CABLE_STATUS_C] = siena_phy_sft9001_bist_status(word); } value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_C); } if (count > EFX_BIST_PHY_CABLE_STATUS_D) { if (valuesp != NULL) { word = MCDI_OUT_WORD(req, POLL_BIST_OUT_SFT9001_CABLE_STATUS_D); valuesp[EFX_BIST_PHY_CABLE_STATUS_D] = siena_phy_sft9001_bist_status(word); } value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_D); } } else if (result == MC_CMD_POLL_BIST_FAILED && encp->enc_phy_type == EFX_PHY_QLX111V && req.emr_out_length >= MC_CMD_POLL_BIST_OUT_MRSFP_LEN && count > EFX_BIST_FAULT_CODE) { if (valuesp != NULL) valuesp[EFX_BIST_FAULT_CODE] = MCDI_OUT_DWORD(req, POLL_BIST_OUT_MRSFP_TEST); value_mask |= 1 << EFX_BIST_FAULT_CODE; } if (value_maskp != NULL) *value_maskp = value_mask; EFSYS_ASSERT(resultp != NULL); if (result == MC_CMD_POLL_BIST_RUNNING) *resultp = EFX_BIST_RESULT_RUNNING; else if (result == MC_CMD_POLL_BIST_PASSED) *resultp = EFX_BIST_RESULT_PASSED; else *resultp = EFX_BIST_RESULT_FAILED; return (0); fail2: EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, int, rc); return (rc); } void siena_phy_bist_stop( __in efx_nic_t *enp, __in efx_bist_type_t type) { /* There is no way to stop BIST on Siena */ _NOTE(ARGUNUSED(enp, type)) } #endif /* EFSYS_OPT_BIST */ #endif /* EFSYS_OPT_SIENA */