summaryrefslogtreecommitdiffstats
path: root/sys/dev/sfxge
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2016-01-25 08:56:15 -0200
committerRenato Botelho <renato@netgate.com>2016-01-25 08:56:15 -0200
commiteb84e0723f3b4bc5e40024f66fe21c14b09e9ec4 (patch)
treefec6b99d018e13f1fccbe31478aaf29a28a55642 /sys/dev/sfxge
parentc50df8e1b90c4f9b8bbffa592477c129854776ce (diff)
parent94b1bbbd44bd88b6db1c00d795cdf7675b3ae254 (diff)
downloadFreeBSD-src-eb84e0723f3b4bc5e40024f66fe21c14b09e9ec4.zip
FreeBSD-src-eb84e0723f3b4bc5e40024f66fe21c14b09e9ec4.tar.gz
Merge remote-tracking branch 'origin/stable/10' into devel
Diffstat (limited to 'sys/dev/sfxge')
-rw-r--r--sys/dev/sfxge/common/ef10_impl.h46
-rw-r--r--sys/dev/sfxge/common/ef10_tlv_layout.h10
-rw-r--r--sys/dev/sfxge/common/efsys.h4
-rw-r--r--sys/dev/sfxge/common/efx.h73
-rw-r--r--sys/dev/sfxge/common/efx_check.h11
-rw-r--r--sys/dev/sfxge/common/efx_impl.h54
-rw-r--r--sys/dev/sfxge/common/efx_lic.c792
-rw-r--r--sys/dev/sfxge/common/efx_mac.c51
-rw-r--r--sys/dev/sfxge/common/efx_mcdi.c166
-rw-r--r--sys/dev/sfxge/common/efx_mcdi.h5
-rw-r--r--sys/dev/sfxge/common/efx_nic.c52
-rw-r--r--sys/dev/sfxge/common/efx_nvram.c131
-rw-r--r--sys/dev/sfxge/common/efx_phy.c30
-rw-r--r--sys/dev/sfxge/common/efx_regs_ef10.h65
-rw-r--r--sys/dev/sfxge/common/efx_rx.c4
-rw-r--r--sys/dev/sfxge/common/efx_tx.c22
-rw-r--r--sys/dev/sfxge/common/efx_vpd.c19
-rw-r--r--sys/dev/sfxge/common/hunt_ev.c184
-rw-r--r--sys/dev/sfxge/common/hunt_impl.h193
-rw-r--r--sys/dev/sfxge/common/hunt_mac.c307
-rw-r--r--sys/dev/sfxge/common/hunt_mcdi.c145
-rw-r--r--sys/dev/sfxge/common/hunt_nic.c210
-rw-r--r--sys/dev/sfxge/common/hunt_nvram.c215
-rw-r--r--sys/dev/sfxge/common/hunt_phy.c85
-rwxr-xr-xsys/dev/sfxge/common/hunt_tx.c35
-rw-r--r--sys/dev/sfxge/common/hunt_vpd.c41
-rw-r--r--sys/dev/sfxge/common/medford_impl.h22
-rw-r--r--sys/dev/sfxge/common/medford_nic.c266
-rw-r--r--sys/dev/sfxge/common/siena_flash.h4
-rw-r--r--sys/dev/sfxge/common/siena_impl.h102
-rw-r--r--sys/dev/sfxge/common/siena_mcdi.c75
-rw-r--r--sys/dev/sfxge/common/siena_nic.c1
-rw-r--r--sys/dev/sfxge/common/siena_nvram.c181
-rw-r--r--sys/dev/sfxge/common/siena_vpd.c7
-rw-r--r--sys/dev/sfxge/sfxge.h5
-rw-r--r--sys/dev/sfxge/sfxge_tx.c238
-rw-r--r--sys/dev/sfxge/sfxge_tx.h1
-rw-r--r--sys/dev/sfxge/sfxge_version.h2
38 files changed, 2522 insertions, 1332 deletions
diff --git a/sys/dev/sfxge/common/ef10_impl.h b/sys/dev/sfxge/common/ef10_impl.h
index 9b9f0aa..0c687ae 100644
--- a/sys/dev/sfxge/common/ef10_impl.h
+++ b/sys/dev/sfxge/common/ef10_impl.h
@@ -45,6 +45,52 @@ extern "C" {
#define EF10_MAX_PIOBUF_NBUFS MEDFORD_PIOBUF_NBUFS
#endif
+extern __checkReturn efx_rc_t
+efx_mcdi_get_port_assignment(
+ __in efx_nic_t *enp,
+ __out uint32_t *portp);
+
+extern __checkReturn efx_rc_t
+efx_mcdi_get_port_modes(
+ __in efx_nic_t *enp,
+ __out uint32_t *modesp);
+
+extern __checkReturn efx_rc_t
+efx_mcdi_get_mac_address_pf(
+ __in efx_nic_t *enp,
+ __out_ecount_opt(6) uint8_t mac_addrp[6]);
+
+extern __checkReturn efx_rc_t
+efx_mcdi_get_mac_address_vf(
+ __in efx_nic_t *enp,
+ __out_ecount_opt(6) uint8_t mac_addrp[6]);
+
+extern __checkReturn efx_rc_t
+efx_mcdi_get_clock(
+ __in efx_nic_t *enp,
+ __out uint32_t *sys_freqp);
+
+extern __checkReturn efx_rc_t
+efx_mcdi_get_vector_cfg(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *vec_basep,
+ __out_opt uint32_t *pf_nvecp,
+ __out_opt uint32_t *vf_nvecp);
+
+extern __checkReturn efx_rc_t
+ef10_get_datapath_caps(
+ __in efx_nic_t *enp);
+
+extern __checkReturn efx_rc_t
+ef10_get_privilege_mask(
+ __in efx_nic_t *enp,
+ __out uint32_t *maskp);
+
+extern __checkReturn efx_rc_t
+ef10_external_port_mapping(
+ __in efx_nic_t *enp,
+ __in uint32_t port,
+ __out uint8_t *external_portp);
#ifdef __cplusplus
diff --git a/sys/dev/sfxge/common/ef10_tlv_layout.h b/sys/dev/sfxge/common/ef10_tlv_layout.h
index 4063165..80364ce 100644
--- a/sys/dev/sfxge/common/ef10_tlv_layout.h
+++ b/sys/dev/sfxge/common/ef10_tlv_layout.h
@@ -113,7 +113,11 @@ struct tlv_partition_header {
uint32_t tag;
uint32_t length;
uint16_t type_id;
- uint16_t reserved;
+/* 0 indicates the default segment (always located at offset 0), while other values
+ * are for RFID-selectable presets that should immediately follow the default segment.
+ * The default segment may also have preset > 0, which means that it is a preset
+ * selected through an RFID command and copied by FW to the location at offset 0. */
+ uint16_t preset;
uint32_t generation;
uint32_t total_length;
};
@@ -376,7 +380,7 @@ struct tlv_tmp_gubbins {
int8_t with_rmon; /* 0 -> off, 1 -> on, -1 -> leave alone */
/* Consumed by clocks_hunt.c */
int8_t clk_mode; /* 0 -> off, 1 -> on, -1 -> leave alone */
- /* Consumed by sram.c */
+ /* No longer used, superseded by TLV_TAG_DESCRIPTOR_CACHE_CONFIG. */
int8_t rx_dc_size; /* -1 -> leave alone */
int8_t tx_dc_size;
int16_t num_q_allocs;
@@ -690,7 +694,6 @@ struct tlv_mcast_filter_chaining {
#define TLV_MCAST_FILTER_CHAINING_ENABLED (1)
};
-
/* Pacer rate limit per PF */
#define TLV_TAG_RATE_LIMIT(pf) (0x101b0000 + (pf))
@@ -700,7 +703,6 @@ struct tlv_rate_limit {
uint32_t rate_mbps;
};
-
/* OCSD Enable/Disable
*
* This setting allows OCSD to be disabled. This is a requirement for HP
diff --git a/sys/dev/sfxge/common/efsys.h b/sys/dev/sfxge/common/efsys.h
index 7bc1fe0..14238ad 100644
--- a/sys/dev/sfxge/common/efsys.h
+++ b/sys/dev/sfxge/common/efsys.h
@@ -211,6 +211,8 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#define __out_ecount_opt(_n)
#define __out_bcount(_n)
#define __out_bcount_opt(_n)
+#define __out_bcount_part(_n, _l)
+#define __out_bcount_part_opt(_n, _l)
#define __deref_out
@@ -293,6 +295,8 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#define EFSYS_OPT_DECODE_INTR_FATAL 1
+#define EFSYS_OPT_LICENSING 0
+
/* ID */
typedef struct __efsys_identifier_s efsys_identifier_t;
diff --git a/sys/dev/sfxge/common/efx.h b/sys/dev/sfxge/common/efx.h
index 0483c9a..ce70546 100644
--- a/sys/dev/sfxge/common/efx.h
+++ b/sys/dev/sfxge/common/efx.h
@@ -1071,6 +1071,7 @@ efx_bist_stop(
#define EFX_FEATURE_TX_SRC_FILTERS 0x00000400
#define EFX_FEATURE_PIO_BUFFERS 0x00000800
#define EFX_FEATURE_FW_ASSISTED_TSO 0x00001000
+#define EFX_FEATURE_FW_ASSISTED_TSO_V2 0x00002000
typedef struct efx_nic_cfg_s {
uint32_t enc_board_type;
@@ -1152,14 +1153,18 @@ typedef struct efx_nic_cfg_s {
*/
uint32_t enc_tx_tso_tcp_header_offset_limit;
boolean_t enc_fw_assisted_tso_enabled;
+ boolean_t enc_fw_assisted_tso_v2_enabled;
boolean_t enc_hw_tx_insert_vlan_enabled;
/* Datapath firmware vadapter/vport/vswitch support */
boolean_t enc_datapath_cap_evb;
boolean_t enc_rx_disable_scatter_supported;
boolean_t enc_allow_set_mac_with_installed_filters;
+ boolean_t enc_enhanced_set_mac_supported;
/* External port identifier */
uint8_t enc_external_port;
uint32_t enc_mcdi_max_payload_length;
+ /* VPD may be per-PF or global */
+ boolean_t enc_vpd_is_global;
} efx_nic_cfg_t;
#define EFX_PCI_FUNCTION_IS_PF(_encp) ((_encp)->enc_vf == 0xffff)
@@ -1315,6 +1320,7 @@ typedef enum efx_nvram_type_e {
EFX_NVRAM_CPLD,
EFX_NVRAM_FPGA_BACKUP,
EFX_NVRAM_DYNAMIC_CFG,
+ EFX_NVRAM_LICENSE,
EFX_NVRAM_NTYPES,
} efx_nvram_type_t;
@@ -2002,6 +2008,7 @@ efx_tx_fini(
#define EFX_TXQ_CKSUM_IPV4 0x0001
#define EFX_TXQ_CKSUM_TCPUDP 0x0002
+#define EFX_TXQ_FATSOV2 0x0004
extern __checkReturn efx_rc_t
efx_tx_qcreate(
@@ -2089,6 +2096,21 @@ efx_tx_qdesc_tso_create(
__in uint8_t tcp_flags,
__out efx_desc_t *edp);
+/* Number of FATSOv2 option descriptors */
+#define EFX_TX_FATSOV2_OPT_NDESCS 2
+
+/* Maximum number of DMA segments per TSO packet (not superframe) */
+#define EFX_TX_FATSOV2_DMA_SEGS_PER_PKT_MAX 24
+
+extern void
+efx_tx_qdesc_tso2_create(
+ __in efx_txq_t *etp,
+ __in uint16_t ipv4_id,
+ __in uint32_t tcp_seq,
+ __in uint16_t tcp_mss,
+ __out_ecount(count) efx_desc_t *edp,
+ __in int count);
+
extern void
efx_tx_qdesc_vlantci_create(
__in efx_txq_t *etp,
@@ -2291,6 +2313,57 @@ efx_hash_bytes(
__in size_t length,
__in uint32_t init);
+#if EFSYS_OPT_LICENSING
+
+/* LICENSING */
+
+typedef struct efx_key_stats_s {
+ uint32_t eks_valid;
+ uint32_t eks_invalid;
+ uint32_t eks_blacklisted;
+ uint32_t eks_unverifiable;
+ uint32_t eks_wrong_node;
+ uint32_t eks_licensed_apps_lo;
+ uint32_t eks_licensed_apps_hi;
+ uint32_t eks_licensed_features_lo;
+ uint32_t eks_licensed_features_hi;
+} efx_key_stats_t;
+
+extern __checkReturn efx_rc_t
+efx_lic_init(
+ __in efx_nic_t *enp);
+
+extern void
+efx_lic_fini(
+ __in efx_nic_t *enp);
+
+extern __checkReturn efx_rc_t
+efx_lic_update_licenses(
+ __in efx_nic_t *enp);
+
+extern __checkReturn efx_rc_t
+efx_lic_get_key_stats(
+ __in efx_nic_t *enp,
+ __out efx_key_stats_t *ksp);
+
+extern __checkReturn efx_rc_t
+efx_lic_app_state(
+ __in efx_nic_t *enp,
+ __in uint64_t app_id,
+ __out boolean_t *licensedp);
+
+extern __checkReturn efx_rc_t
+efx_lic_get_id(
+ __in efx_nic_t *enp,
+ __in size_t buffer_size,
+ __out uint32_t *typep,
+ __out size_t *lengthp,
+ __out_opt uint8_t *bufferp);
+
+
+#endif /* EFSYS_OPT_LICENSING */
+
+
#ifdef __cplusplus
}
diff --git a/sys/dev/sfxge/common/efx_check.h b/sys/dev/sfxge/common/efx_check.h
index 199fab0..d6b7cf4 100644
--- a/sys/dev/sfxge/common/efx_check.h
+++ b/sys/dev/sfxge/common/efx_check.h
@@ -401,4 +401,15 @@
# endif
#endif /* EFSYS_OPT_BIST */
+/* Support MCDI licensing API */
+#if EFSYS_OPT_LICENSING
+# if !EFSYS_OPT_MCDI
+# error "LICENSING requires MCDI"
+# endif
+# if !EFSYS_HAS_UINT64
+# error "LICENSING requires UINT64"
+# endif
+#endif /* EFSYS_OPT_LICENSING */
+
+
#endif /* _SYS_EFX_CHECK_H */
diff --git a/sys/dev/sfxge/common/efx_impl.h b/sys/dev/sfxge/common/efx_impl.h
index 5397ffe..5495b15 100644
--- a/sys/dev/sfxge/common/efx_impl.h
+++ b/sys/dev/sfxge/common/efx_impl.h
@@ -84,6 +84,7 @@ extern "C" {
#define EFX_MOD_WOL 0x00000800
#define EFX_MOD_FILTER 0x00001000
#define EFX_MOD_PKTFILTER 0x00002000
+#define EFX_MOD_LIC 0x00004000
#define EFX_RESET_MAC 0x00000001
#define EFX_RESET_PHY 0x00000002
@@ -96,6 +97,7 @@ typedef enum efx_mac_type_e {
EFX_MAC_FALCON_XMAC,
EFX_MAC_SIENA,
EFX_MAC_HUNTINGTON,
+ EFX_MAC_MEDFORD,
EFX_MAC_NTYPES
} efx_mac_type_t;
@@ -146,6 +148,9 @@ typedef struct efx_tx_ops_s {
void (*etxo_qdesc_tso_create)(efx_txq_t *, uint16_t,
uint32_t, uint8_t,
efx_desc_t *);
+ void (*etxo_qdesc_tso2_create)(efx_txq_t *, uint16_t,
+ uint32_t, uint16_t,
+ efx_desc_t *, int);
void (*etxo_qdesc_vlantci_create)(efx_txq_t *, uint16_t,
efx_desc_t *);
#if EFSYS_OPT_QSTATS
@@ -189,6 +194,7 @@ typedef struct efx_mac_ops_s {
efx_rc_t (*emo_poll)(efx_nic_t *, efx_link_mode_t *);
efx_rc_t (*emo_up)(efx_nic_t *, boolean_t *);
efx_rc_t (*emo_addr_set)(efx_nic_t *);
+ efx_rc_t (*emo_pdu_set)(efx_nic_t *);
efx_rc_t (*emo_reconfigure)(efx_nic_t *);
efx_rc_t (*emo_multicast_list_set)(efx_nic_t *);
efx_rc_t (*emo_filter_default_rxq_set)(efx_nic_t *,
@@ -358,6 +364,7 @@ typedef struct efx_intr_s {
typedef struct efx_nic_ops_s {
efx_rc_t (*eno_probe)(efx_nic_t *);
+ efx_rc_t (*eno_board_cfg)(efx_nic_t *);
efx_rc_t (*eno_set_drv_limits)(efx_nic_t *, efx_drv_limits_t*);
efx_rc_t (*eno_reset)(efx_nic_t *);
efx_rc_t (*eno_init)(efx_nic_t *);
@@ -456,9 +463,8 @@ falconsiena_filter_tbl_clear(
typedef struct efx_mcdi_ops_s {
efx_rc_t (*emco_init)(efx_nic_t *, const efx_mcdi_transport_t *);
- void (*emco_request_copyin)(efx_nic_t *, efx_mcdi_req_t *,
- unsigned int, boolean_t, boolean_t);
- void (*emco_request_copyout)(efx_nic_t *, efx_mcdi_req_t *);
+ void (*emco_send_request)(efx_nic_t *, void *, size_t,
+ void *, size_t);
efx_rc_t (*emco_poll_reboot)(efx_nic_t *);
boolean_t (*emco_poll_response)(efx_nic_t *);
void (*emco_read_response)(efx_nic_t *, void *, size_t, size_t);
@@ -479,21 +485,21 @@ typedef struct efx_nvram_ops_s {
#if EFSYS_OPT_DIAG
efx_rc_t (*envo_test)(efx_nic_t *);
#endif /* EFSYS_OPT_DIAG */
- efx_rc_t (*envo_size)(efx_nic_t *, efx_nvram_type_t, size_t *);
- efx_rc_t (*envo_get_version)(efx_nic_t *, efx_nvram_type_t,
- uint32_t *, uint16_t *);
- efx_rc_t (*envo_rw_start)(efx_nic_t *, efx_nvram_type_t, size_t *);
- efx_rc_t (*envo_read_chunk)(efx_nic_t *, efx_nvram_type_t,
+ efx_rc_t (*envo_type_to_partn)(efx_nic_t *, efx_nvram_type_t,
+ uint32_t *);
+ efx_rc_t (*envo_partn_size)(efx_nic_t *, uint32_t, size_t *);
+ efx_rc_t (*envo_partn_rw_start)(efx_nic_t *, uint32_t, size_t *);
+ efx_rc_t (*envo_partn_read)(efx_nic_t *, uint32_t,
unsigned int, caddr_t, size_t);
- efx_rc_t (*envo_erase)(efx_nic_t *, efx_nvram_type_t);
- efx_rc_t (*envo_write_chunk)(efx_nic_t *, efx_nvram_type_t,
+ efx_rc_t (*envo_partn_erase)(efx_nic_t *, uint32_t,
+ unsigned int, size_t);
+ efx_rc_t (*envo_partn_write)(efx_nic_t *, uint32_t,
unsigned int, caddr_t, size_t);
- void (*envo_rw_finish)(efx_nic_t *, efx_nvram_type_t);
- efx_rc_t (*envo_set_version)(efx_nic_t *, efx_nvram_type_t,
+ void (*envo_partn_rw_finish)(efx_nic_t *, uint32_t);
+ efx_rc_t (*envo_partn_get_version)(efx_nic_t *, uint32_t,
+ uint32_t *, uint16_t *);
+ efx_rc_t (*envo_partn_set_version)(efx_nic_t *, uint32_t,
uint16_t *);
-
- efx_rc_t (*envo_type_to_partn)(efx_nic_t *, efx_nvram_type_t,
- uint32_t *);
} efx_nvram_ops_t;
#endif /* EFSYS_OPT_NVRAM */
@@ -553,7 +559,8 @@ efx_mcdi_nvram_read(
__in uint32_t partn,
__in uint32_t offset,
__out_bcount(size) caddr_t data,
- __in size_t size);
+ __in size_t size,
+ __in uint32_t mode);
__checkReturn efx_rc_t
efx_mcdi_nvram_erase(
@@ -587,6 +594,18 @@ efx_mcdi_nvram_test(
#endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
+#if EFSYS_OPT_LICENSING
+
+typedef struct efx_lic_ops_s {
+ efx_rc_t (*elo_update_licenses)(efx_nic_t *);
+ efx_rc_t (*elo_get_key_stats)(efx_nic_t *, efx_key_stats_t *);
+ efx_rc_t (*elo_app_state)(efx_nic_t *, uint64_t, boolean_t *);
+ efx_rc_t (*elo_get_id)(efx_nic_t *, size_t, uint32_t *,
+ size_t *, uint8_t *);
+} efx_lic_ops_t;
+
+#endif
+
typedef struct efx_drv_cfg_s {
uint32_t edc_min_vi_count;
uint32_t edc_max_vi_count;
@@ -636,6 +655,9 @@ struct efx_nic_s {
uint32_t en_rss_context;
#endif /* EFSYS_OPT_RX_SCALE */
uint32_t en_vport_id;
+#if EFSYS_OPT_LICENSING
+ efx_lic_ops_t *en_elop;
+#endif
union {
#if EFSYS_OPT_FALCON
struct {
diff --git a/sys/dev/sfxge/common/efx_lic.c b/sys/dev/sfxge/common/efx_lic.c
new file mode 100644
index 0000000..33c8aba
--- /dev/null
+++ b/sys/dev/sfxge/common/efx_lic.c
@@ -0,0 +1,792 @@
+/*-
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efx.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_LICENSING
+
+#if EFSYS_OPT_SIENA
+
+static __checkReturn efx_rc_t
+efx_mcdi_fc_license_update_license(
+ __in efx_nic_t *enp);
+
+static __checkReturn efx_rc_t
+efx_mcdi_fc_license_get_key_stats(
+ __in efx_nic_t *enp,
+ __out efx_key_stats_t *eksp);
+
+static efx_lic_ops_t __efx_lic_v1_ops = {
+ efx_mcdi_fc_license_update_license, /* elo_update_licenses */
+ efx_mcdi_fc_license_get_key_stats, /* elo_get_key_stats */
+ NULL, /* elo_app_state */
+ NULL, /* elo_get_id */
+};
+
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensing_update_licenses(
+ __in efx_nic_t *enp);
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensing_get_key_stats(
+ __in efx_nic_t *enp,
+ __out efx_key_stats_t *eksp);
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensed_app_state(
+ __in efx_nic_t *enp,
+ __in uint64_t app_id,
+ __out boolean_t *licensedp);
+
+static efx_lic_ops_t __efx_lic_v2_ops = {
+ efx_mcdi_licensing_update_licenses, /* elo_update_licenses */
+ efx_mcdi_licensing_get_key_stats, /* elo_get_key_stats */
+ efx_mcdi_licensed_app_state, /* elo_app_state */
+ NULL, /* elo_get_id */
+};
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+#if EFSYS_OPT_MEDFORD
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensing_v3_update_licenses(
+ __in efx_nic_t *enp);
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensing_v3_report_license(
+ __in efx_nic_t *enp,
+ __out efx_key_stats_t *eksp);
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensing_v3_app_state(
+ __in efx_nic_t *enp,
+ __in uint64_t app_id,
+ __out boolean_t *licensedp);
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensing_v3_get_id(
+ __in efx_nic_t *enp,
+ __in size_t buffer_size,
+ __out uint32_t *typep,
+ __out size_t *lengthp,
+ __out_bcount_part_opt(buffer_size, *lengthp)
+ uint8_t *bufferp);
+
+static efx_lic_ops_t __efx_lic_v3_ops = {
+ efx_mcdi_licensing_v3_update_licenses, /* elo_update_licenses */
+ efx_mcdi_licensing_v3_report_license, /* elo_get_key_stats */
+ efx_mcdi_licensing_v3_app_state, /* elo_app_state */
+ efx_mcdi_licensing_v3_get_id, /* elo_get_id */
+};
+
+#endif /* EFSYS_OPT_MEDFORD */
+
+
+/* V1 Licensing - used in Siena Modena only */
+
+#if EFSYS_OPT_SIENA
+
+static __checkReturn efx_rc_t
+efx_mcdi_fc_license_update_license(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MC_CMD_FC_IN_LICENSE_LEN];
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FC_OP_LICENSE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = 0;
+
+ MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
+ MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used != 0) {
+ rc = EIO;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+static __checkReturn efx_rc_t
+efx_mcdi_fc_license_get_key_stats(
+ __in efx_nic_t *enp,
+ __out efx_key_stats_t *eksp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FC_IN_LICENSE_LEN,
+ MC_CMD_FC_OUT_LICENSE_LEN)];
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FC_OP_LICENSE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN;
+
+ MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
+ MC_CMD_FC_IN_LICENSE_GET_KEY_STATS);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ eksp->eks_valid =
+ MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS);
+ eksp->eks_invalid =
+ MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS);
+ eksp->eks_blacklisted =
+ MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS);
+ eksp->eks_unverifiable = 0;
+ eksp->eks_wrong_node = 0;
+ eksp->eks_licensed_apps_lo = 0;
+ eksp->eks_licensed_apps_hi = 0;
+ eksp->eks_licensed_features_lo = 0;
+ eksp->eks_licensed_features_hi = 0;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_SIENA */
+
+/* V2 Licensing - used by Huntington family only. See SF-113611-TC */
+
+#if EFSYS_OPT_HUNTINGTON
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensed_app_state(
+ __in efx_nic_t *enp,
+ __in uint64_t app_id,
+ __out boolean_t *licensedp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
+ MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN)];
+ uint32_t app_state;
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ /* V2 licensing supports 32bit app id only */
+ if ((app_id >> 32) != 0) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID,
+ app_id & 0xffffffff);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+
+ app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE));
+ if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) {
+ *licensedp = B_TRUE;
+ } else {
+ *licensedp = B_FALSE;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensing_update_licenses(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MC_CMD_LICENSING_IN_LEN];
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_LICENSING;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = 0;
+
+ MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
+ MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used != 0) {
+ rc = EIO;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensing_get_key_stats(
+ __in efx_nic_t *enp,
+ __out efx_key_stats_t *eksp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_LICENSING_IN_LEN,
+ MC_CMD_LICENSING_OUT_LEN)];
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_LICENSING;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_LICENSING_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
+ MC_CMD_LICENSING_IN_OP_GET_KEY_STATS);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ eksp->eks_valid =
+ MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS);
+ eksp->eks_invalid =
+ MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS);
+ eksp->eks_blacklisted =
+ MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS);
+ eksp->eks_unverifiable =
+ MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS);
+ eksp->eks_wrong_node =
+ MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS);
+ eksp->eks_licensed_apps_lo = 0;
+ eksp->eks_licensed_apps_hi = 0;
+ eksp->eks_licensed_features_lo = 0;
+ eksp->eks_licensed_features_hi = 0;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+/* V3 Licensing - used starting from Medford family. See SF-114884-SW */
+
+#if EFSYS_OPT_MEDFORD
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensing_v3_update_licenses(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MC_CMD_LICENSING_V3_IN_LEN];
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_LICENSING_V3;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
+ req.emr_out_buf = NULL;
+ req.emr_out_length = 0;
+
+ MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
+ MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensing_v3_report_license(
+ __in efx_nic_t *enp,
+ __out efx_key_stats_t *eksp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_LICENSING_V3_IN_LEN,
+ MC_CMD_LICENSING_V3_OUT_LEN)];
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_LICENSING_V3;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
+ MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ eksp->eks_valid =
+ MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS);
+ eksp->eks_invalid =
+ MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS);
+ eksp->eks_blacklisted = 0;
+ eksp->eks_unverifiable =
+ MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS);
+ eksp->eks_wrong_node =
+ MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS);
+ eksp->eks_licensed_apps_lo =
+ MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO);
+ eksp->eks_licensed_apps_hi =
+ MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI);
+ eksp->eks_licensed_features_lo =
+ MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO);
+ eksp->eks_licensed_features_hi =
+ MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensing_v3_app_state(
+ __in efx_nic_t *enp,
+ __in uint64_t app_id,
+ __out boolean_t *licensedp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN,
+ MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN)];
+ uint32_t app_state;
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO,
+ app_id & 0xffffffff);
+ MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI,
+ app_id >> 32);
+
+ 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_LICENSED_V3_APP_STATE_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE));
+ if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) {
+ *licensedp = B_TRUE;
+ } else {
+ *licensedp = B_FALSE;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+static __checkReturn efx_rc_t
+efx_mcdi_licensing_v3_get_id(
+ __in efx_nic_t *enp,
+ __in size_t buffer_size,
+ __out uint32_t *typep,
+ __out size_t *lengthp,
+ __out_bcount_part_opt(buffer_size, *lengthp)
+ uint8_t *bufferp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
+ MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN)];
+ efx_rc_t rc;
+
+ req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3;
+
+ if (bufferp == NULL) {
+ /* Request id type and length only */
+ req.emr_in_buf = bufferp;
+ req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
+ req.emr_out_buf = bufferp;
+ req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
+ (void) memset(payload, 0, sizeof (payload));
+ } else {
+ /* Request full buffer */
+ req.emr_in_buf = bufferp;
+ req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
+ req.emr_out_buf = bufferp;
+ req.emr_out_length = MIN(buffer_size, MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN);
+ (void) memset(bufferp, 0, req.emr_out_length);
+ }
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE);
+ *lengthp = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH);
+
+ if (bufferp == NULL) {
+ /* modify length requirements to indicate to caller the extra buffering
+ ** needed to read the complete output.
+ */
+ *lengthp += MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
+ } else {
+ /* Shift ID down to start of buffer */
+ memmove(bufferp,
+ bufferp+MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
+ *lengthp);
+ memset(bufferp+(*lengthp), 0, MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST);
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+
+#endif /* EFSYS_OPT_MEDFORD */
+
+ __checkReturn efx_rc_t
+efx_lic_init(
+ __in efx_nic_t *enp)
+{
+ efx_lic_ops_t *elop;
+ efx_rc_t rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+ EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC));
+
+ switch (enp->en_family) {
+
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ elop = (efx_lic_ops_t *)&__efx_lic_v1_ops;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ elop = (efx_lic_ops_t *)&__efx_lic_v2_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+#if EFSYS_OPT_MEDFORD
+ case EFX_FAMILY_MEDFORD:
+ elop = (efx_lic_ops_t *)&__efx_lic_v3_ops;
+ break;
+#endif /* EFSYS_OPT_MEDFORD */
+
+ default:
+ EFSYS_ASSERT(0);
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ enp->en_elop = elop;
+ enp->en_mod_flags |= EFX_MOD_LIC;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ void
+efx_lic_fini(
+ __in efx_nic_t *enp)
+{
+ efx_lic_ops_t *elop = enp->en_elop;
+
+ 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_LIC);
+
+ enp->en_elop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_LIC;
+}
+
+
+ __checkReturn efx_rc_t
+efx_lic_update_licenses(
+ __in efx_nic_t *enp)
+{
+ efx_lic_ops_t *elop = enp->en_elop;
+ efx_rc_t rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
+
+ if ((rc = elop->elo_update_licenses(enp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+efx_lic_get_key_stats(
+ __in efx_nic_t *enp,
+ __out efx_key_stats_t *eksp)
+{
+ efx_lic_ops_t *elop = enp->en_elop;
+ efx_rc_t rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
+
+ if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+efx_lic_app_state(
+ __in efx_nic_t *enp,
+ __in uint64_t app_id,
+ __out boolean_t *licensedp)
+{
+ efx_lic_ops_t *elop = enp->en_elop;
+ efx_rc_t rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
+
+ if (elop->elo_app_state == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+efx_lic_get_id(
+ __in efx_nic_t *enp,
+ __in size_t buffer_size,
+ __out uint32_t *typep,
+ __out size_t *lengthp,
+ __out_opt uint8_t *bufferp
+ )
+{
+ efx_lic_ops_t *elop = enp->en_elop;
+ efx_rc_t rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
+
+ if (elop->elo_get_id == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = elop->elo_get_id(enp, buffer_size, typep,
+ lengthp, bufferp)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_LICENSING */
diff --git a/sys/dev/sfxge/common/efx_mac.c b/sys/dev/sfxge/common/efx_mac.c
index c8794a6..4868c4b 100644
--- a/sys/dev/sfxge/common/efx_mac.c
+++ b/sys/dev/sfxge/common/efx_mac.c
@@ -56,6 +56,7 @@ static efx_mac_ops_t __efx_falcon_gmac_ops = {
falcon_mac_poll, /* emo_poll */
falcon_mac_up, /* emo_up */
falcon_gmac_reconfigure, /* emo_addr_set */
+ falcon_gmac_reconfigure, /* emo_pdu_set */
falcon_gmac_reconfigure, /* emo_reconfigure */
falconsiena_mac_multicast_list_set, /* emo_multicast_list_set */
NULL, /* emo_filter_set_default_rxq */
@@ -77,6 +78,7 @@ static efx_mac_ops_t __efx_falcon_xmac_ops = {
falcon_mac_poll, /* emo_poll */
falcon_mac_up, /* emo_up */
falcon_xmac_reconfigure, /* emo_addr_set */
+ falcon_xmac_reconfigure, /* emo_pdu_set */
falcon_xmac_reconfigure, /* emo_reconfigure */
falconsiena_mac_multicast_list_set, /* emo_multicast_list_set */
NULL, /* emo_filter_set_default_rxq */
@@ -98,6 +100,7 @@ static efx_mac_ops_t __efx_siena_mac_ops = {
siena_mac_poll, /* emo_poll */
siena_mac_up, /* emo_up */
siena_mac_reconfigure, /* emo_addr_set */
+ siena_mac_reconfigure, /* emo_pdu_set */
siena_mac_reconfigure, /* emo_reconfigure */
falconsiena_mac_multicast_list_set, /* emo_multicast_list_set */
NULL, /* emo_filter_set_default_rxq */
@@ -113,27 +116,28 @@ static efx_mac_ops_t __efx_siena_mac_ops = {
};
#endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_HUNTINGTON
-static efx_mac_ops_t __efx_hunt_mac_ops = {
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
+static efx_mac_ops_t __efx_ef10_mac_ops = {
NULL, /* emo_reset */
- hunt_mac_poll, /* emo_poll */
- hunt_mac_up, /* emo_up */
- hunt_mac_addr_set, /* emo_addr_set */
- hunt_mac_reconfigure, /* emo_reconfigure */
- hunt_mac_multicast_list_set, /* emo_multicast_list_set */
- hunt_mac_filter_default_rxq_set, /* emo_filter_default_rxq_set */
- hunt_mac_filter_default_rxq_clear,
+ ef10_mac_poll, /* emo_poll */
+ ef10_mac_up, /* emo_up */
+ ef10_mac_addr_set, /* emo_addr_set */
+ ef10_mac_pdu_set, /* emo_pdu_set */
+ ef10_mac_reconfigure, /* emo_reconfigure */
+ ef10_mac_multicast_list_set, /* emo_multicast_list_set */
+ ef10_mac_filter_default_rxq_set, /* emo_filter_default_rxq_set */
+ ef10_mac_filter_default_rxq_clear,
/* emo_filter_default_rxq_clear */
#if EFSYS_OPT_LOOPBACK
- hunt_mac_loopback_set, /* emo_loopback_set */
+ ef10_mac_loopback_set, /* emo_loopback_set */
#endif /* EFSYS_OPT_LOOPBACK */
#if EFSYS_OPT_MAC_STATS
efx_mcdi_mac_stats_upload, /* emo_stats_upload */
efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
- hunt_mac_stats_update /* emo_stats_update */
+ ef10_mac_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MAC_STATS */
};
-#endif /* EFSYS_OPT_HUNTINGTON */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
static efx_mac_ops_t *__efx_mac_ops[] = {
/* [EFX_MAC_INVALID] */
@@ -158,7 +162,13 @@ static efx_mac_ops_t *__efx_mac_ops[] = {
#endif
/* [EFX_MAC_HUNTINGTON] */
#if EFSYS_OPT_HUNTINGTON
- &__efx_hunt_mac_ops,
+ &__efx_ef10_mac_ops,
+#else
+ NULL,
+#endif
+ /* [EFX_MAC_MEDFORD] */
+#if EFSYS_OPT_MEDFORD
+ &__efx_ef10_mac_ops,
#else
NULL,
#endif
@@ -190,7 +200,7 @@ efx_mac_pdu_set(
old_pdu = epp->ep_mac_pdu;
epp->ep_mac_pdu = (uint32_t)pdu;
- if ((rc = emop->emo_reconfigure(enp)) != 0)
+ if ((rc = emop->emo_pdu_set(enp)) != 0)
goto fail3;
return (0);
@@ -781,6 +791,13 @@ efx_mac_select(
efx_mac_ops_t *emop;
int rc = EINVAL;
+#if EFSYS_OPT_SIENA
+ if (enp->en_family == EFX_FAMILY_SIENA) {
+ type = EFX_MAC_SIENA;
+ goto chosen;
+ }
+#endif
+
#if EFSYS_OPT_HUNTINGTON
if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
type = EFX_MAC_HUNTINGTON;
@@ -788,9 +805,9 @@ efx_mac_select(
}
#endif
-#if EFSYS_OPT_SIENA
- if (enp->en_family == EFX_FAMILY_SIENA) {
- type = EFX_MAC_SIENA;
+#if EFSYS_OPT_MEDFORD
+ if (enp->en_family == EFX_FAMILY_MEDFORD) {
+ type = EFX_MAC_MEDFORD;
goto chosen;
}
#endif
diff --git a/sys/dev/sfxge/common/efx_mcdi.c b/sys/dev/sfxge/common/efx_mcdi.c
index 07224c7..9f7a9ff 100644
--- a/sys/dev/sfxge/common/efx_mcdi.c
+++ b/sys/dev/sfxge/common/efx_mcdi.c
@@ -36,13 +36,32 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_MCDI
+/*
+ * There are three versions of the MCDI interface:
+ * - MCDIv0: Siena BootROM. Transport uses MCDIv1 headers.
+ * - MCDIv1: Siena firmware and Huntington BootROM.
+ * - MCDIv2: EF10 firmware (Huntington/Medford) and Medford BootROM.
+ * Transport uses MCDIv2 headers.
+ *
+ * MCDIv2 Header NOT_EPOCH flag
+ * ----------------------------
+ * A new epoch begins at initial startup or after an MC reboot, and defines when
+ * the MC should reject stale MCDI requests.
+ *
+ * The first MCDI request sent by the host should contain NOT_EPOCH=0, and all
+ * subsequent requests (until the next MC reboot) should contain NOT_EPOCH=1.
+ *
+ * After rebooting the MC will fail all requests with NOT_EPOCH=1 by writing a
+ * response with ERROR=1 and DATALEN=0 until a request is seen with NOT_EPOCH=0.
+ */
+
+
#if EFSYS_OPT_SIENA
static efx_mcdi_ops_t __efx_mcdi_siena_ops = {
siena_mcdi_init, /* emco_init */
- siena_mcdi_request_copyin, /* emco_request_copyin */
- siena_mcdi_request_copyout, /* emco_request_copyout */
+ siena_mcdi_send_request, /* emco_send_request */
siena_mcdi_poll_reboot, /* emco_poll_reboot */
siena_mcdi_poll_response, /* emco_poll_response */
siena_mcdi_read_response, /* emco_read_response */
@@ -56,8 +75,7 @@ static efx_mcdi_ops_t __efx_mcdi_siena_ops = {
static efx_mcdi_ops_t __efx_mcdi_ef10_ops = {
ef10_mcdi_init, /* emco_init */
- ef10_mcdi_request_copyin, /* emco_request_copyin */
- ef10_mcdi_request_copyout, /* emco_request_copyout */
+ ef10_mcdi_send_request, /* emco_send_request */
ef10_mcdi_poll_reboot, /* emco_poll_reboot */
ef10_mcdi_poll_response, /* emco_poll_response */
ef10_mcdi_read_response, /* emco_read_response */
@@ -179,26 +197,16 @@ efx_mcdi_new_epoch(
}
static void
-efx_mcdi_request_copyin(
+efx_mcdi_send_request(
__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)
-{
- efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
-
- emcop->emco_request_copyin(enp, emrp, seq, ev_cpl, new_epoch);
-}
-
-static void
-efx_mcdi_request_copyout(
- __in efx_nic_t *enp,
- __in efx_mcdi_req_t *emrp)
+ __in void *hdrp,
+ __in size_t hdr_len,
+ __in void *sdup,
+ __in size_t sdu_len)
{
efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
- emcop->emco_request_copyout(enp, emrp);
+ emcop->emco_send_request(enp, hdrp, hdr_len, sdup, sdu_len);
}
static efx_rc_t
@@ -241,8 +249,15 @@ efx_mcdi_request_start(
__in efx_mcdi_req_t *emrp,
__in boolean_t ev_cpl)
{
+#if EFSYS_OPT_MCDI_LOGGING
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+#endif
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_dword_t hdr[2];
+ size_t hdr_len;
+ unsigned int max_version;
unsigned int seq;
+ unsigned int xflags;
boolean_t new_epoch;
int state;
@@ -269,13 +284,64 @@ efx_mcdi_request_start(
emip->emi_poll_cnt = 0;
seq = emip->emi_seq++ & EFX_MASK32(MCDI_HEADER_SEQ);
new_epoch = emip->emi_new_epoch;
+ max_version = emip->emi_max_version;
EFSYS_UNLOCK(enp->en_eslp, state);
- efx_mcdi_request_copyin(enp, emrp, seq, ev_cpl, new_epoch);
+ xflags = 0;
+ if (ev_cpl)
+ xflags |= MCDI_HEADER_XFLAGS_EVREQ;
+
+ /*
+ * Huntington firmware supports MCDIv2, but the Huntington BootROM only
+ * supports MCDIv1. Use MCDIv1 headers for MCDIv1 commands where
+ * possible to support this.
+ */
+ if ((max_version >= 2) &&
+ ((emrp->emr_cmd > MC_CMD_CMD_SPACE_ESCAPE_7) ||
+ (emrp->emr_in_length > MCDI_CTL_SDU_LEN_MAX_V1))) {
+ /* Construct MCDI v2 header */
+ hdr_len = sizeof (hdr);
+ EFX_POPULATE_DWORD_8(hdr[0],
+ MCDI_HEADER_CODE, MC_CMD_V2_EXTN,
+ MCDI_HEADER_RESYNC, 1,
+ MCDI_HEADER_DATALEN, 0,
+ MCDI_HEADER_SEQ, seq,
+ MCDI_HEADER_NOT_EPOCH, new_epoch ? 0 : 1,
+ MCDI_HEADER_ERROR, 0,
+ MCDI_HEADER_RESPONSE, 0,
+ MCDI_HEADER_XFLAGS, xflags);
+
+ EFX_POPULATE_DWORD_2(hdr[1],
+ MC_CMD_V2_EXTN_IN_EXTENDED_CMD, emrp->emr_cmd,
+ MC_CMD_V2_EXTN_IN_ACTUAL_LEN, emrp->emr_in_length);
+ } else {
+ /* Construct MCDI v1 header */
+ hdr_len = sizeof (hdr[0]);
+ EFX_POPULATE_DWORD_8(hdr[0],
+ MCDI_HEADER_CODE, emrp->emr_cmd,
+ MCDI_HEADER_RESYNC, 1,
+ MCDI_HEADER_DATALEN, emrp->emr_in_length,
+ MCDI_HEADER_SEQ, seq,
+ MCDI_HEADER_NOT_EPOCH, new_epoch ? 0 : 1,
+ MCDI_HEADER_ERROR, 0,
+ MCDI_HEADER_RESPONSE, 0,
+ MCDI_HEADER_XFLAGS, xflags);
+ }
+
+#if EFSYS_OPT_MCDI_LOGGING
+ if (emtp->emt_logger != NULL) {
+ emtp->emt_logger(emtp->emt_context, EFX_LOG_MCDI_REQUEST,
+ &hdr, hdr_len,
+ emrp->emr_in_buf, emrp->emr_in_length);
+ }
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+
+ efx_mcdi_send_request(enp, &hdr[0], hdr_len,
+ emrp->emr_in_buf, emrp->emr_in_length);
}
- void
+static void
efx_mcdi_read_response_header(
__in efx_nic_t *enp,
__inout efx_mcdi_req_t *emrp)
@@ -384,19 +450,56 @@ efx_mcdi_read_response_header(
return;
fail3:
- if (!emrp->emr_quiet)
- EFSYS_PROBE(fail3);
fail2:
- if (!emrp->emr_quiet)
- EFSYS_PROBE(fail2);
fail1:
- if (!emrp->emr_quiet)
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
emrp->emr_rc = rc;
emrp->emr_out_length_used = 0;
}
+static void
+efx_mcdi_finish_response(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp)
+{
+#if EFSYS_OPT_MCDI_LOGGING
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+ efx_dword_t hdr[2];
+ unsigned int hdr_len;
+ size_t bytes;
+
+ if (emrp->emr_out_buf == NULL)
+ return;
+
+ /* Read the command header to detect MCDI response format */
+ hdr_len = sizeof (hdr[0]);
+ efx_mcdi_read_response(enp, &hdr[0], 0, hdr_len);
+ if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) {
+ /*
+ * Read the actual payload length. The length given in the event
+ * is only correct for responses with the V1 format.
+ */
+ efx_mcdi_read_response(enp, &hdr[1], hdr_len, sizeof (hdr[1]));
+ hdr_len += sizeof (hdr[1]);
+
+ emrp->emr_out_length_used = EFX_DWORD_FIELD(hdr[1],
+ MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
+ }
+
+ /* Copy payload out into caller supplied buffer */
+ bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length);
+ efx_mcdi_read_response(enp, emrp->emr_out_buf, hdr_len, bytes);
+
+#if EFSYS_OPT_MCDI_LOGGING
+ if (emtp->emt_logger != NULL) {
+ emtp->emt_logger(emtp->emt_context,
+ EFX_LOG_MCDI_RESPONSE,
+ &hdr, hdr_len,
+ emrp->emr_out_buf, bytes);
+ }
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+}
+
__checkReturn boolean_t
efx_mcdi_request_poll(
@@ -444,7 +547,7 @@ efx_mcdi_request_poll(
if ((rc = emrp->emr_rc) != 0)
goto fail2;
- efx_mcdi_request_copyout(enp, emrp);
+ efx_mcdi_finish_response(enp, emrp);
return (B_TRUE);
fail2:
@@ -638,7 +741,6 @@ efx_mcdi_ev_cpl(
{
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
- efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
efx_mcdi_req_t *emrp;
int state;
@@ -680,7 +782,7 @@ efx_mcdi_ev_cpl(
}
}
if (errcode == 0) {
- emcop->emco_request_copyout(enp, emrp);
+ efx_mcdi_finish_response(enp, emrp);
}
emtp->emt_ev_cpl(emtp->emt_context);
diff --git a/sys/dev/sfxge/common/efx_mcdi.h b/sys/dev/sfxge/common/efx_mcdi.h
index 36b3d8d..dd1d76e 100644
--- a/sys/dev/sfxge/common/efx_mcdi.h
+++ b/sys/dev/sfxge/common/efx_mcdi.h
@@ -88,11 +88,6 @@ efx_mcdi_execute_quiet(
__in efx_nic_t *enp,
__inout efx_mcdi_req_t *emrp);
- extern void
-efx_mcdi_read_response_header(
- __in efx_nic_t *enp,
- __inout efx_mcdi_req_t *emrp);
-
extern void
efx_mcdi_ev_cpl(
__in efx_nic_t *enp,
diff --git a/sys/dev/sfxge/common/efx_nic.c b/sys/dev/sfxge/common/efx_nic.c
index 07acc56..dd28ece 100644
--- a/sys/dev/sfxge/common/efx_nic.c
+++ b/sys/dev/sfxge/common/efx_nic.c
@@ -244,6 +244,7 @@ fail1:
static efx_nic_ops_t __efx_nic_falcon_ops = {
falcon_nic_probe, /* eno_probe */
+ NULL, /* eno_board_cfg */
NULL, /* eno_set_drv_limits */
falcon_nic_reset, /* eno_reset */
falcon_nic_init, /* eno_init */
@@ -263,6 +264,7 @@ static efx_nic_ops_t __efx_nic_falcon_ops = {
static efx_nic_ops_t __efx_nic_siena_ops = {
siena_nic_probe, /* eno_probe */
+ NULL, /* eno_board_cfg */
NULL, /* eno_set_drv_limits */
siena_nic_reset, /* eno_reset */
siena_nic_init, /* eno_init */
@@ -282,6 +284,7 @@ static efx_nic_ops_t __efx_nic_siena_ops = {
static efx_nic_ops_t __efx_nic_hunt_ops = {
ef10_nic_probe, /* eno_probe */
+ hunt_board_cfg, /* eno_board_cfg */
ef10_nic_set_drv_limits, /* eno_set_drv_limits */
ef10_nic_reset, /* eno_reset */
ef10_nic_init, /* eno_init */
@@ -297,6 +300,27 @@ static efx_nic_ops_t __efx_nic_hunt_ops = {
#endif /* EFSYS_OPT_HUNTINGTON */
+#if EFSYS_OPT_MEDFORD
+
+static efx_nic_ops_t __efx_nic_medford_ops = {
+ ef10_nic_probe, /* eno_probe */
+ medford_board_cfg, /* eno_board_cfg */
+ ef10_nic_set_drv_limits, /* eno_set_drv_limits */
+ ef10_nic_reset, /* eno_reset */
+ ef10_nic_init, /* eno_init */
+ ef10_nic_get_vi_pool, /* eno_get_vi_pool */
+ ef10_nic_get_bar_region, /* eno_get_bar_region */
+#if EFSYS_OPT_DIAG
+ ef10_sram_test, /* eno_sram_test */
+ ef10_nic_register_test, /* eno_register_test */
+#endif /* EFSYS_OPT_DIAG */
+ ef10_nic_fini, /* eno_fini */
+ ef10_nic_unprobe, /* eno_unprobe */
+};
+
+#endif /* EFSYS_OPT_MEDFORD */
+
+
__checkReturn efx_rc_t
efx_nic_create(
__in efx_family_t family,
@@ -357,10 +381,29 @@ efx_nic_create(
EFX_FEATURE_MAC_HEADER_FILTERS |
EFX_FEATURE_MCDI_DMA |
EFX_FEATURE_PIO_BUFFERS |
- EFX_FEATURE_FW_ASSISTED_TSO;
+ EFX_FEATURE_FW_ASSISTED_TSO |
+ EFX_FEATURE_FW_ASSISTED_TSO_V2;
break;
#endif /* EFSYS_OPT_HUNTINGTON */
+#if EFSYS_OPT_MEDFORD
+ case EFX_FAMILY_MEDFORD:
+ enp->en_enop = (efx_nic_ops_t *)&__efx_nic_medford_ops;
+ /*
+ * FW_ASSISTED_TSO ommitted as Medford only supports firmware
+ * assisted TSO version 2, not the v1 scheme used on Huntington.
+ */
+ enp->en_features =
+ EFX_FEATURE_IPV6 |
+ EFX_FEATURE_LINK_EVENTS |
+ EFX_FEATURE_PERIODIC_MAC_STATS |
+ EFX_FEATURE_MCDI |
+ EFX_FEATURE_MAC_HEADER_FILTERS |
+ EFX_FEATURE_MCDI_DMA |
+ EFX_FEATURE_PIO_BUFFERS;
+ break;
+#endif /* EFSYS_OPT_MEDFORD */
+
default:
rc = ENOTSUP;
goto fail2;
@@ -665,8 +708,9 @@ efx_nic_reset(
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
/*
- * All modules except the MCDI, PROBE, NVRAM, VPD, MON (which we
- * do not reset here) must have been shut down or never initialized.
+ * All modules except the MCDI, PROBE, NVRAM, VPD, MON, LIC
+ * (which we do not reset here) must have been shut down or never
+ * initialized.
*
* A rule of thumb here is: If the controller or MC reboots, is *any*
* state lost. If it's lost and needs reapplying, then the module
@@ -674,7 +718,7 @@ efx_nic_reset(
*/
mod_flags = enp->en_mod_flags;
mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
- EFX_MOD_VPD | EFX_MOD_MON);
+ EFX_MOD_VPD | EFX_MOD_MON | EFX_MOD_LIC);
EFSYS_ASSERT3U(mod_flags, ==, 0);
if (mod_flags != 0) {
rc = EINVAL;
diff --git a/sys/dev/sfxge/common/efx_nvram.c b/sys/dev/sfxge/common/efx_nvram.c
index 7597636..272e6c7 100644
--- a/sys/dev/sfxge/common/efx_nvram.c
+++ b/sys/dev/sfxge/common/efx_nvram.c
@@ -42,15 +42,15 @@ static efx_nvram_ops_t __efx_nvram_falcon_ops = {
#if EFSYS_OPT_DIAG
falcon_nvram_test, /* envo_test */
#endif /* EFSYS_OPT_DIAG */
- falcon_nvram_size, /* envo_size */
- falcon_nvram_get_version, /* envo_get_version */
- falcon_nvram_rw_start, /* envo_rw_start */
- falcon_nvram_read_chunk, /* envo_read_chunk */
- falcon_nvram_erase, /* envo_erase */
- falcon_nvram_write_chunk, /* envo_write_chunk */
- falcon_nvram_rw_finish, /* envo_rw_finish */
- falcon_nvram_set_version, /* envo_set_version */
falcon_nvram_type_to_partn, /* envo_type_to_partn */
+ falcon_nvram_partn_size, /* envo_partn_size */
+ falcon_nvram_partn_rw_start, /* envo_partn_rw_start */
+ falcon_nvram_partn_read, /* envo_partn_read */
+ falcon_nvram_partn_erase, /* envo_partn_erase */
+ falcon_nvram_partn_write, /* envo_partn_write */
+ falcon_nvram_partn_rw_finish, /* envo_partn_rw_finish */
+ falcon_nvram_partn_get_version, /* envo_partn_get_version */
+ falcon_nvram_partn_set_version, /* envo_partn_set_version */
};
#endif /* EFSYS_OPT_FALCON */
@@ -61,15 +61,15 @@ static efx_nvram_ops_t __efx_nvram_siena_ops = {
#if EFSYS_OPT_DIAG
siena_nvram_test, /* envo_test */
#endif /* EFSYS_OPT_DIAG */
- siena_nvram_size, /* envo_size */
- siena_nvram_get_version, /* envo_get_version */
- siena_nvram_rw_start, /* envo_rw_start */
- siena_nvram_read_chunk, /* envo_read_chunk */
- siena_nvram_erase, /* envo_erase */
- siena_nvram_write_chunk, /* envo_write_chunk */
- siena_nvram_rw_finish, /* envo_rw_finish */
- siena_nvram_set_version, /* envo_set_version */
siena_nvram_type_to_partn, /* envo_type_to_partn */
+ siena_nvram_partn_size, /* envo_partn_size */
+ siena_nvram_partn_rw_start, /* envo_partn_rw_start */
+ siena_nvram_partn_read, /* envo_partn_read */
+ siena_nvram_partn_erase, /* envo_partn_erase */
+ siena_nvram_partn_write, /* envo_partn_write */
+ siena_nvram_partn_rw_finish, /* envo_partn_rw_finish */
+ siena_nvram_partn_get_version, /* envo_partn_get_version */
+ siena_nvram_partn_set_version, /* envo_partn_set_version */
};
#endif /* EFSYS_OPT_SIENA */
@@ -80,15 +80,15 @@ static efx_nvram_ops_t __efx_nvram_ef10_ops = {
#if EFSYS_OPT_DIAG
ef10_nvram_test, /* envo_test */
#endif /* EFSYS_OPT_DIAG */
- ef10_nvram_size, /* envo_size */
- ef10_nvram_get_version, /* envo_get_version */
- ef10_nvram_rw_start, /* envo_rw_start */
- ef10_nvram_read_chunk, /* envo_read_chunk */
- ef10_nvram_erase, /* envo_erase */
- ef10_nvram_write_chunk, /* envo_write_chunk */
- ef10_nvram_rw_finish, /* envo_rw_finish */
- ef10_nvram_set_version, /* envo_set_version */
ef10_nvram_type_to_partn, /* envo_type_to_partn */
+ ef10_nvram_partn_size, /* envo_partn_size */
+ ef10_nvram_partn_rw_start, /* envo_partn_rw_start */
+ ef10_nvram_partn_read, /* envo_partn_read */
+ ef10_nvram_partn_erase, /* envo_partn_erase */
+ ef10_nvram_partn_write, /* envo_partn_write */
+ ef10_nvram_partn_rw_finish, /* envo_partn_rw_finish */
+ ef10_nvram_partn_get_version, /* envo_partn_get_version */
+ ef10_nvram_partn_set_version, /* envo_partn_set_version */
};
#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
@@ -178,6 +178,7 @@ efx_nvram_size(
__out size_t *sizep)
{
efx_nvram_ops_t *envop = enp->en_envop;
+ uint32_t partn;
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -185,13 +186,19 @@ efx_nvram_size(
EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
- if ((rc = envop->envo_size(enp, type, sizep)) != 0)
+ if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
goto fail1;
+ if ((rc = envop->envo_partn_size(enp, partn, sizep)) != 0)
+ goto fail2;
+
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
+ *sizep = 0;
return (rc);
}
@@ -204,6 +211,7 @@ efx_nvram_get_version(
__out_ecount(4) uint16_t version[4])
{
efx_nvram_ops_t *envop = enp->en_envop;
+ uint32_t partn;
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -212,11 +220,17 @@ efx_nvram_get_version(
EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
- if ((rc = envop->envo_get_version(enp, type, subtypep, version)) != 0)
+ if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
goto fail1;
+ if ((rc = envop->envo_partn_get_version(enp, partn,
+ subtypep, version)) != 0)
+ goto fail2;
+
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
@@ -230,6 +244,7 @@ efx_nvram_rw_start(
__out_opt size_t *chunk_sizep)
{
efx_nvram_ops_t *envop = enp->en_envop;
+ uint32_t partn;
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -240,13 +255,18 @@ efx_nvram_rw_start(
EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
- if ((rc = envop->envo_rw_start(enp, type, chunk_sizep)) != 0)
+ if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
goto fail1;
+ if ((rc = envop->envo_partn_rw_start(enp, partn, chunk_sizep)) != 0)
+ goto fail2;
+
enp->en_nvram_locked = type;
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
@@ -262,6 +282,7 @@ efx_nvram_read_chunk(
__in size_t size)
{
efx_nvram_ops_t *envop = enp->en_envop;
+ uint32_t partn;
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -272,11 +293,16 @@ efx_nvram_read_chunk(
EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
- if ((rc = envop->envo_read_chunk(enp, type, offset, data, size)) != 0)
+ if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
goto fail1;
+ if ((rc = envop->envo_partn_read(enp, partn, offset, data, size)) != 0)
+ goto fail2;
+
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
@@ -289,6 +315,9 @@ efx_nvram_erase(
__in efx_nvram_type_t type)
{
efx_nvram_ops_t *envop = enp->en_envop;
+ unsigned int offset = 0;
+ size_t size = 0;
+ uint32_t partn;
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -299,11 +328,21 @@ efx_nvram_erase(
EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
- if ((rc = envop->envo_erase(enp, type)) != 0)
+ if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
goto fail1;
+ if ((rc = envop->envo_partn_size(enp, partn, &size)) != 0)
+ goto fail2;
+
+ if ((rc = envop->envo_partn_erase(enp, partn, offset, size)) != 0)
+ goto fail3;
+
return (0);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
@@ -319,6 +358,7 @@ efx_nvram_write_chunk(
__in size_t size)
{
efx_nvram_ops_t *envop = enp->en_envop;
+ uint32_t partn;
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -329,11 +369,16 @@ efx_nvram_write_chunk(
EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
- if ((rc = envop->envo_write_chunk(enp, type, offset, data, size)) != 0)
+ if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
goto fail1;
+ if ((rc = envop->envo_partn_write(enp, partn, offset, data, size)) != 0)
+ goto fail2;
+
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
@@ -346,6 +391,7 @@ efx_nvram_rw_finish(
__in efx_nvram_type_t type)
{
efx_nvram_ops_t *envop = enp->en_envop;
+ uint32_t partn;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
@@ -355,7 +401,8 @@ efx_nvram_rw_finish(
EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
- envop->envo_rw_finish(enp, type);
+ if (envop->envo_type_to_partn(enp, type, &partn) == 0)
+ envop->envo_partn_rw_finish(enp, partn);
enp->en_nvram_locked = EFX_NVRAM_INVALID;
}
@@ -367,6 +414,7 @@ efx_nvram_set_version(
__in_ecount(4) uint16_t version[4])
{
efx_nvram_ops_t *envop = enp->en_envop;
+ uint32_t partn;
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -382,11 +430,16 @@ efx_nvram_set_version(
*/
EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
- if ((rc = envop->envo_set_version(enp, type, version)) != 0)
+ if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
goto fail1;
+ if ((rc = envop->envo_partn_set_version(enp, partn, version)) != 0)
+ goto fail2;
+
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
@@ -668,10 +721,11 @@ efx_mcdi_nvram_read(
__in uint32_t partn,
__in uint32_t offset,
__out_bcount(size) caddr_t data,
- __in size_t size)
+ __in size_t size,
+ __in uint32_t mode)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_LEN,
+ uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_V2_LEN,
MC_CMD_NVRAM_READ_OUT_LENMAX)];
efx_rc_t rc;
@@ -683,13 +737,14 @@ efx_mcdi_nvram_read(
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_NVRAM_READ;
req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_READ_IN_LEN;
+ req.emr_in_length = MC_CMD_NVRAM_READ_IN_V2_LEN;
req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_NVRAM_READ_OUT_LENMAX;
- MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_TYPE, partn);
- MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_OFFSET, offset);
- MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_LENGTH, size);
+ MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_TYPE, partn);
+ MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_OFFSET, offset);
+ MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_LENGTH, size);
+ MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_MODE, mode);
efx_mcdi_execute(enp, &req);
diff --git a/sys/dev/sfxge/common/efx_phy.c b/sys/dev/sfxge/common/efx_phy.c
index dd966be..51e1ccb 100644
--- a/sys/dev/sfxge/common/efx_phy.c
+++ b/sys/dev/sfxge/common/efx_phy.c
@@ -265,33 +265,34 @@ static efx_phy_ops_t __efx_phy_siena_ops = {
};
#endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_HUNTINGTON
-static efx_phy_ops_t __efx_phy_hunt_ops = {
- hunt_phy_power, /* epo_power */
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
+static efx_phy_ops_t __efx_phy_ef10_ops = {
+ ef10_phy_power, /* epo_power */
NULL, /* epo_reset */
- hunt_phy_reconfigure, /* epo_reconfigure */
- hunt_phy_verify, /* epo_verify */
+ ef10_phy_reconfigure, /* epo_reconfigure */
+ ef10_phy_verify, /* epo_verify */
NULL, /* epo_uplink_check */
NULL, /* epo_downlink_check */
- hunt_phy_oui_get, /* epo_oui_get */
+ ef10_phy_oui_get, /* epo_oui_get */
#if EFSYS_OPT_PHY_STATS
- hunt_phy_stats_update, /* epo_stats_update */
+ ef10_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 */
+ ef10_phy_prop_name, /* epo_prop_name */
#endif
- hunt_phy_prop_get, /* epo_prop_get */
- hunt_phy_prop_set, /* epo_prop_set */
+ ef10_phy_prop_get, /* epo_prop_get */
+ ef10_phy_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
#if EFSYS_OPT_BIST
+ /* FIXME: Are these BIST methods appropriate for Medford? */
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 */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
__checkReturn efx_rc_t
efx_phy_probe(
@@ -356,9 +357,14 @@ efx_phy_probe(
#endif /* EFSYS_OPT_SIENA */
#if EFSYS_OPT_HUNTINGTON
case EFX_FAMILY_HUNTINGTON:
- epop = (efx_phy_ops_t *)&__efx_phy_hunt_ops;
+ epop = (efx_phy_ops_t *)&__efx_phy_ef10_ops;
break;
#endif /* EFSYS_OPT_HUNTINGTON */
+#if EFSYS_OPT_MEDFORD
+ case EFX_FAMILY_MEDFORD:
+ epop = (efx_phy_ops_t *)&__efx_phy_ef10_ops;
+ break;
+#endif /* EFSYS_OPT_MEDFORD */
default:
rc = ENOTSUP;
goto fail1;
diff --git a/sys/dev/sfxge/common/efx_regs_ef10.h b/sys/dev/sfxge/common/efx_regs_ef10.h
index bd7619a..43745e5 100644
--- a/sys/dev/sfxge/common/efx_regs_ef10.h
+++ b/sys/dev/sfxge/common/efx_regs_ef10.h
@@ -50,7 +50,7 @@ extern "C" {
*/
#define ER_DZ_BIU_HW_REV_ID_REG_OFST 0x00000000
-/* hunta0=pcie_pf_bar2 */
+/* hunta0,medforda0=pcie_pf_bar2 */
#define ER_DZ_BIU_HW_REV_ID_REG_RESET 0xeb14face
@@ -64,7 +64,7 @@ extern "C" {
*/
#define ER_DZ_BIU_MC_SFT_STATUS_REG_OFST 0x00000010
-/* hunta0=pcie_pf_bar2 */
+/* hunta0,medforda0=pcie_pf_bar2 */
#define ER_DZ_BIU_MC_SFT_STATUS_REG_STEP 4
#define ER_DZ_BIU_MC_SFT_STATUS_REG_ROWS 8
#define ER_DZ_BIU_MC_SFT_STATUS_REG_RESET 0x1111face
@@ -80,7 +80,7 @@ extern "C" {
*/
#define ER_DZ_BIU_INT_ISR_REG_OFST 0x00000090
-/* hunta0=pcie_pf_bar2 */
+/* hunta0,medforda0=pcie_pf_bar2 */
#define ER_DZ_BIU_INT_ISR_REG_RESET 0x0
@@ -94,7 +94,7 @@ extern "C" {
*/
#define ER_DZ_MC_DB_LWRD_REG_OFST 0x00000200
-/* hunta0=pcie_pf_bar2 */
+/* hunta0,medforda0=pcie_pf_bar2 */
#define ER_DZ_MC_DB_LWRD_REG_RESET 0x0
@@ -108,7 +108,7 @@ extern "C" {
*/
#define ER_DZ_MC_DB_HWRD_REG_OFST 0x00000204
-/* hunta0=pcie_pf_bar2 */
+/* hunta0,medforda0=pcie_pf_bar2 */
#define ER_DZ_MC_DB_HWRD_REG_RESET 0x0
@@ -122,7 +122,7 @@ extern "C" {
*/
#define ER_DZ_EVQ_RPTR_REG_OFST 0x00000400
-/* hunta0=pcie_pf_bar2 */
+/* hunta0,medforda0=pcie_pf_bar2 */
#define ER_DZ_EVQ_RPTR_REG_STEP 8192
#define ER_DZ_EVQ_RPTR_REG_ROWS 2048
#define ER_DZ_EVQ_RPTR_REG_RESET 0x0
@@ -140,7 +140,7 @@ extern "C" {
*/
#define ER_DZ_EVQ_TMR_REG_OFST 0x00000420
-/* hunta0=pcie_pf_bar2 */
+/* hunta0,medforda0=pcie_pf_bar2 */
#define ER_DZ_EVQ_TMR_REG_STEP 8192
#define ER_DZ_EVQ_TMR_REG_ROWS 2048
#define ER_DZ_EVQ_TMR_REG_RESET 0x0
@@ -158,7 +158,7 @@ extern "C" {
*/
#define ER_DZ_RX_DESC_UPD_REG_OFST 0x00000830
-/* hunta0=pcie_pf_bar2 */
+/* hunta0,medforda0=pcie_pf_bar2 */
#define ER_DZ_RX_DESC_UPD_REG_STEP 8192
#define ER_DZ_RX_DESC_UPD_REG_ROWS 2048
#define ER_DZ_RX_DESC_UPD_REG_RESET 0x0
@@ -174,7 +174,7 @@ extern "C" {
*/
#define ER_DZ_TX_DESC_UPD_REG_OFST 0x00000a10
-/* hunta0=pcie_pf_bar2 */
+/* hunta0,medforda0=pcie_pf_bar2 */
#define ER_DZ_TX_DESC_UPD_REG_STEP 8192
#define ER_DZ_TX_DESC_UPD_REG_ROWS 2048
#define ER_DZ_TX_DESC_UPD_REG_RESET 0x0
@@ -248,8 +248,14 @@ extern "C" {
#define ESF_DZ_RX_OVERRIDE_HOLDOFF_WIDTH 1
#define ESF_DZ_RX_DROP_EVENT_LBN 58
#define ESF_DZ_RX_DROP_EVENT_WIDTH 1
-#define ESF_DZ_RX_EV_RSVD2_LBN 54
-#define ESF_DZ_RX_EV_RSVD2_WIDTH 4
+#define ESF_DD_RX_EV_RSVD2_LBN 54
+#define ESF_DD_RX_EV_RSVD2_WIDTH 4
+#define ESF_EZ_RX_TCP_UDP_INNER_CHKSUM_ERR_LBN 57
+#define ESF_EZ_RX_TCP_UDP_INNER_CHKSUM_ERR_WIDTH 1
+#define ESF_EZ_RX_IP_INNER_CHKSUM_ERR_LBN 56
+#define ESF_EZ_RX_IP_INNER_CHKSUM_ERR_WIDTH 1
+#define ESF_EZ_RX_EV_RSVD2_LBN 54
+#define ESF_EZ_RX_EV_RSVD2_WIDTH 2
#define ESF_DZ_RX_EV_SOFT2_LBN 52
#define ESF_DZ_RX_EV_SOFT2_WIDTH 2
#define ESF_DZ_RX_DSC_PTR_LBITS_LBN 48
@@ -293,10 +299,21 @@ extern "C" {
#define ESF_DZ_RX_MAC_CLASS_WIDTH 1
#define ESE_DZ_MAC_CLASS_MCAST 1
#define ESE_DZ_MAC_CLASS_UCAST 0
-#define ESF_DZ_RX_EV_SOFT1_LBN 32
-#define ESF_DZ_RX_EV_SOFT1_WIDTH 3
-#define ESF_DZ_RX_EV_RSVD1_LBN 30
-#define ESF_DZ_RX_EV_RSVD1_WIDTH 2
+#define ESF_DD_RX_EV_SOFT1_LBN 32
+#define ESF_DD_RX_EV_SOFT1_WIDTH 3
+#define ESF_EZ_RX_EV_SOFT1_LBN 34
+#define ESF_EZ_RX_EV_SOFT1_WIDTH 1
+#define ESF_EZ_RX_ENCAP_HDR_LBN 32
+#define ESF_EZ_RX_ENCAP_HDR_WIDTH 2
+#define ESE_EZ_ENCAP_HDR_GRE 2
+#define ESE_EZ_ENCAP_HDR_VXLAN 1
+#define ESE_EZ_ENCAP_HDR_NONE 0
+#define ESF_DD_RX_EV_RSVD1_LBN 30
+#define ESF_DD_RX_EV_RSVD1_WIDTH 2
+#define ESF_EZ_RX_EV_RSVD1_LBN 31
+#define ESF_EZ_RX_EV_RSVD1_WIDTH 1
+#define ESF_EZ_RX_ABORT_LBN 30
+#define ESF_EZ_RX_ABORT_WIDTH 1
#define ESF_DZ_RX_ECC_ERR_LBN 29
#define ESF_DZ_RX_ECC_ERR_WIDTH 1
#define ESF_DZ_RX_CRC1_ERR_LBN 28
@@ -369,12 +386,22 @@ extern "C" {
#define ESF_DZ_TX_OVERRIDE_HOLDOFF_WIDTH 1
#define ESF_DZ_TX_DROP_EVENT_LBN 58
#define ESF_DZ_TX_DROP_EVENT_WIDTH 1
-#define ESF_DZ_TX_EV_RSVD_LBN 48
-#define ESF_DZ_TX_EV_RSVD_WIDTH 10
+#define ESF_DD_TX_EV_RSVD_LBN 48
+#define ESF_DD_TX_EV_RSVD_WIDTH 10
+#define ESF_EZ_TCP_UDP_INNER_CHKSUM_ERR_LBN 57
+#define ESF_EZ_TCP_UDP_INNER_CHKSUM_ERR_WIDTH 1
+#define ESF_EZ_IP_INNER_CHKSUM_ERR_LBN 56
+#define ESF_EZ_IP_INNER_CHKSUM_ERR_WIDTH 1
+#define ESF_EZ_TX_EV_RSVD_LBN 48
+#define ESF_EZ_TX_EV_RSVD_WIDTH 8
#define ESF_DZ_TX_SOFT2_LBN 32
#define ESF_DZ_TX_SOFT2_WIDTH 16
-#define ESF_DZ_TX_SOFT1_LBN 24
-#define ESF_DZ_TX_SOFT1_WIDTH 8
+#define ESF_DD_TX_SOFT1_LBN 24
+#define ESF_DD_TX_SOFT1_WIDTH 8
+#define ESF_EZ_TX_CAN_MERGE_LBN 31
+#define ESF_EZ_TX_CAN_MERGE_WIDTH 1
+#define ESF_EZ_TX_SOFT1_LBN 24
+#define ESF_EZ_TX_SOFT1_WIDTH 7
#define ESF_DZ_TX_QLABEL_LBN 16
#define ESF_DZ_TX_QLABEL_WIDTH 5
#define ESF_DZ_TX_DESCR_INDX_LBN 0
diff --git a/sys/dev/sfxge/common/efx_rx.c b/sys/dev/sfxge/common/efx_rx.c
index a0b143f..8ebe205 100644
--- a/sys/dev/sfxge/common/efx_rx.c
+++ b/sys/dev/sfxge/common/efx_rx.c
@@ -78,14 +78,14 @@ falconsiena_rx_prefix_hash(
__in efx_rx_hash_alg_t func,
__in uint8_t *buffer);
+#endif /* EFSYS_OPT_RX_SCALE */
+
static __checkReturn efx_rc_t
falconsiena_rx_prefix_pktlen(
__in efx_nic_t *enp,
__in uint8_t *buffer,
__out uint16_t *lengthp);
-#endif /* EFSYS_OPT_RX_SCALE */
-
static void
falconsiena_rx_qpost(
__in efx_rxq_t *erp,
diff --git a/sys/dev/sfxge/common/efx_tx.c b/sys/dev/sfxge/common/efx_tx.c
index cff7742..168fde4 100644
--- a/sys/dev/sfxge/common/efx_tx.c
+++ b/sys/dev/sfxge/common/efx_tx.c
@@ -142,6 +142,7 @@ static efx_tx_ops_t __efx_tx_falcon_ops = {
falconsiena_tx_qdesc_post, /* etxo_qdesc_post */
falconsiena_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
NULL, /* etxo_qdesc_tso_create */
+ NULL, /* etxo_qdesc_tso2_create */
NULL, /* etxo_qdesc_vlantci_create */
#if EFSYS_OPT_QSTATS
falconsiena_tx_qstats_update, /* etxo_qstats_update */
@@ -167,6 +168,7 @@ static efx_tx_ops_t __efx_tx_siena_ops = {
falconsiena_tx_qdesc_post, /* etxo_qdesc_post */
falconsiena_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
NULL, /* etxo_qdesc_tso_create */
+ NULL, /* etxo_qdesc_tso2_create */
NULL, /* etxo_qdesc_vlantci_create */
#if EFSYS_OPT_QSTATS
falconsiena_tx_qstats_update, /* etxo_qstats_update */
@@ -192,6 +194,7 @@ static efx_tx_ops_t __efx_tx_hunt_ops = {
ef10_tx_qdesc_post, /* etxo_qdesc_post */
ef10_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
hunt_tx_qdesc_tso_create, /* etxo_qdesc_tso_create */
+ ef10_tx_qdesc_tso2_create, /* etxo_qdesc_tso2_create */
ef10_tx_qdesc_vlantci_create, /* etxo_qdesc_vlantci_create */
#if EFSYS_OPT_QSTATS
ef10_tx_qstats_update, /* etxo_qstats_update */
@@ -217,6 +220,7 @@ static efx_tx_ops_t __efx_tx_medford_ops = {
ef10_tx_qdesc_post, /* etxo_qdesc_post */
ef10_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
NULL, /* etxo_qdesc_tso_create */
+ ef10_tx_qdesc_tso2_create, /* etxo_qdesc_tso2_create */
ef10_tx_qdesc_vlantci_create, /* etxo_qdesc_vlantci_create */
#if EFSYS_OPT_QSTATS
ef10_tx_qstats_update, /* etxo_qstats_update */
@@ -641,6 +645,24 @@ efx_tx_qdesc_tso_create(
}
void
+efx_tx_qdesc_tso2_create(
+ __in efx_txq_t *etp,
+ __in uint16_t ipv4_id,
+ __in uint32_t tcp_seq,
+ __in uint16_t mss,
+ __out_ecount(count) efx_desc_t *edp,
+ __in int count)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+ EFSYS_ASSERT(etxop->etxo_qdesc_tso2_create != NULL);
+
+ etxop->etxo_qdesc_tso2_create(etp, ipv4_id, tcp_seq, mss, edp, count);
+}
+
+ void
efx_tx_qdesc_vlantci_create(
__in efx_txq_t *etp,
__in uint16_t tci,
diff --git a/sys/dev/sfxge/common/efx_vpd.c b/sys/dev/sfxge/common/efx_vpd.c
index c1762e6..ebeddfe 100644
--- a/sys/dev/sfxge/common/efx_vpd.c
+++ b/sys/dev/sfxge/common/efx_vpd.c
@@ -669,7 +669,7 @@ efx_vpd_hunk_next(
__in size_t size,
__out efx_vpd_tag_t *tagp,
__out efx_vpd_keyword_t *keywordp,
- __out_bcount_opt(*paylenp) unsigned int *payloadp,
+ __out_opt unsigned int *payloadp,
__out_opt uint8_t *paylenp,
__inout unsigned int *contp)
{
@@ -689,12 +689,18 @@ efx_vpd_hunk_next(
if ((rc = efx_vpd_next_tag(data, size, &offset,
&tag, &taglen)) != 0)
goto fail1;
- if (tag == EFX_VPD_END)
+
+ if (tag == EFX_VPD_END) {
+ keyword = 0;
+ paylen = 0;
+ index = 0;
break;
+ }
if (tag == EFX_VPD_ID) {
- if (index == *contp) {
+ if (index++ == *contp) {
EFSYS_ASSERT3U(taglen, <, 0x100);
+ keyword = 0;
paylen = (uint8_t)MIN(taglen, 0xff);
goto done;
@@ -705,7 +711,7 @@ efx_vpd_hunk_next(
taglen, pos, &keyword, &keylen)) != 0)
goto fail2;
- if (index == *contp) {
+ if (index++ == *contp) {
offset += pos + 3;
paylen = keylen;
@@ -717,9 +723,6 @@ efx_vpd_hunk_next(
offset += taglen;
}
- *contp = 0;
- return (0);
-
done:
*tagp = tag;
*keywordp = keyword;
@@ -728,7 +731,7 @@ done:
if (paylenp != NULL)
*paylenp = paylen;
- ++(*contp);
+ *contp = index;
return (0);
fail2:
diff --git a/sys/dev/sfxge/common/hunt_ev.c b/sys/dev/sfxge/common/hunt_ev.c
index 2cea2e0..1a41b49 100644
--- a/sys/dev/sfxge/common/hunt_ev.c
+++ b/sys/dev/sfxge/common/hunt_ev.c
@@ -444,9 +444,9 @@ ef10_ev_qmoderate(
eep->ee_index, &dword, 0);
} else {
EFX_POPULATE_DWORD_2(dword,
- FRF_CZ_TC_TIMER_MODE, mode,
- FRF_CZ_TC_TIMER_VAL, timer_val);
- EFX_BAR_TBL_WRITED(enp, FR_BZ_TIMER_COMMAND_REGP0,
+ ERF_DZ_TC_TIMER_MODE, mode,
+ ERF_DZ_TC_TIMER_VAL, timer_val);
+ EFX_BAR_TBL_WRITED(enp, ER_DZ_EVQ_TMR_REG,
eep->ee_index, &dword, 0);
}
@@ -486,17 +486,14 @@ ef10_ev_rx(
{
efx_nic_t *enp = eep->ee_enp;
uint32_t size;
-#if 0
- boolean_t parse_err;
-#endif
uint32_t label;
- uint32_t mcast;
- uint32_t eth_base_class;
+ uint32_t mac_class;
uint32_t eth_tag_class;
uint32_t l3_class;
uint32_t l4_class;
uint32_t next_read_lbits;
uint16_t flags;
+ boolean_t cont;
boolean_t should_abort;
efx_evq_rxq_state_t *eersp;
unsigned int desc_count;
@@ -508,10 +505,15 @@ ef10_ev_rx(
if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
return (B_FALSE);
- /*
- * FIXME: likely to be incomplete, incorrect and inefficient.
- * Improvements in all three areas are required.
- */
+ /* Basic packet information */
+ size = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_BYTES);
+ next_read_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);
+ label = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);
+ eth_tag_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_TAG_CLASS);
+ mac_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_MAC_CLASS);
+ l3_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L3_CLASS);
+ l4_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L4_CLASS);
+ cont = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CONT);
if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DROP_EVENT) != 0) {
/* Drop this event */
@@ -519,9 +521,7 @@ ef10_ev_rx(
}
flags = 0;
- size = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_BYTES);
-
- if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CONT) != 0) {
+ if (cont != 0) {
/*
* This may be part of a scattered frame, or it may be a
* truncated frame if scatter is disabled on this RXQ.
@@ -534,41 +534,9 @@ ef10_ev_rx(
flags |= EFX_PKT_CONT;
}
-#if 0
- /* TODO What to do if the packet is flagged with parsing error */
- parse_err = (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_PARSE_INCOMPLETE) != 0);
-#endif
- label = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);
-
- if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECRC_ERR) != 0) {
- /* Ethernet frame CRC bad */
- flags |= EFX_DISCARD;
- }
- if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CRC0_ERR) != 0) {
- /* IP+TCP, bad CRC in iSCSI header */
- flags |= EFX_DISCARD;
- }
- if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CRC1_ERR) != 0) {
- /* IP+TCP, bad CRC in iSCSI payload or FCoE or FCoIP */
- flags |= EFX_DISCARD;
- }
- if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECC_ERR) != 0) {
- /* ECC memory error */
- flags |= EFX_DISCARD;
- }
-
- mcast = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_MAC_CLASS);
- if (mcast == ESE_DZ_MAC_CLASS_UCAST)
+ if (mac_class == ESE_DZ_MAC_CLASS_UCAST)
flags |= EFX_PKT_UNICAST;
- eth_base_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_BASE_CLASS);
- eth_tag_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_TAG_CLASS);
- l3_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L3_CLASS);
- l4_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L4_CLASS);
-
- /* bottom 4 bits of incremented index (not last desc consumed) */
- next_read_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);
-
/* Increment the count of descriptors read */
eersp = &eep->ee_rxq_state[label];
desc_count = (next_read_lbits - eersp->eers_rx_read_ptr) &
@@ -587,88 +555,84 @@ ef10_ev_rx(
/* Calculate the index of the the last descriptor consumed */
last_used_id = (eersp->eers_rx_read_ptr - 1) & eersp->eers_rx_mask;
- /* EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_OVERRIDE_HOLDOFF); */
-
- switch (eth_base_class) {
- case ESE_DZ_ETH_BASE_CLASS_LLC_SNAP:
- case ESE_DZ_ETH_BASE_CLASS_LLC:
- case ESE_DZ_ETH_BASE_CLASS_ETH2:
- default:
- break;
+ /* Check for errors that invalidate checksum and L3/L4 fields */
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECC_ERR) != 0) {
+ /* RX frame truncated (error flag is misnamed) */
+ EFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC);
+ flags |= EFX_DISCARD;
+ goto deliver;
+ }
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECRC_ERR) != 0) {
+ /* Bad Ethernet frame CRC */
+ EFX_EV_QSTAT_INCR(eep, EV_RX_ETH_CRC_ERR);
+ flags |= EFX_DISCARD;
+ goto deliver;
+ }
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_PARSE_INCOMPLETE)) {
+ /*
+ * Hardware parse failed, due to malformed headers
+ * or headers that are too long for the parser.
+ * Headers and checksums must be validated by the host.
+ */
+ // TODO: EFX_EV_QSTAT_INCR(eep, EV_RX_PARSE_INCOMPLETE);
+ goto deliver;
}
- switch (eth_tag_class) {
- case ESE_DZ_ETH_TAG_CLASS_RSVD7:
- case ESE_DZ_ETH_TAG_CLASS_RSVD6:
- case ESE_DZ_ETH_TAG_CLASS_RSVD5:
- case ESE_DZ_ETH_TAG_CLASS_RSVD4:
- break;
-
- case ESE_DZ_ETH_TAG_CLASS_RSVD3: /* Triple tagged */
- case ESE_DZ_ETH_TAG_CLASS_VLAN2: /* Double tagged */
- case ESE_DZ_ETH_TAG_CLASS_VLAN1: /* VLAN tagged */
+ if ((eth_tag_class == ESE_DZ_ETH_TAG_CLASS_VLAN1) ||
+ (eth_tag_class == ESE_DZ_ETH_TAG_CLASS_VLAN2)) {
flags |= EFX_PKT_VLAN_TAGGED;
- break;
-
- case ESE_DZ_ETH_TAG_CLASS_NONE:
- default:
- break;
}
switch (l3_class) {
- case ESE_DZ_L3_CLASS_RSVD7: /* Used by firmware for packet overrun */
-#if 0
- parse_err = B_TRUE;
-#endif
- flags |= EFX_DISCARD;
- break;
+ case ESE_DZ_L3_CLASS_IP4:
+ case ESE_DZ_L3_CLASS_IP4_FRAG:
+ flags |= EFX_PKT_IPV4;
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_IPCKSUM_ERR)) {
+ EFX_EV_QSTAT_INCR(eep, EV_RX_IPV4_HDR_CHKSUM_ERR);
+ } else {
+ flags |= EFX_CKSUM_IPV4;
+ }
- case ESE_DZ_L3_CLASS_ARP:
- case ESE_DZ_L3_CLASS_FCOE:
+ if (l4_class == ESE_DZ_L4_CLASS_TCP) {
+ EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV4);
+ flags |= EFX_PKT_TCP;
+ } else if (l4_class == ESE_DZ_L4_CLASS_UDP) {
+ EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV4);
+ flags |= EFX_PKT_UDP;
+ } else {
+ EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV4);
+ }
break;
- case ESE_DZ_L3_CLASS_IP6_FRAG:
case ESE_DZ_L3_CLASS_IP6:
+ case ESE_DZ_L3_CLASS_IP6_FRAG:
flags |= EFX_PKT_IPV6;
- break;
- case ESE_DZ_L3_CLASS_IP4_FRAG:
- case ESE_DZ_L3_CLASS_IP4:
- flags |= EFX_PKT_IPV4;
- if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_IPCKSUM_ERR) == 0)
- flags |= EFX_CKSUM_IPV4;
+ if (l4_class == ESE_DZ_L4_CLASS_TCP) {
+ EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV6);
+ flags |= EFX_PKT_TCP;
+ } else if (l4_class == ESE_DZ_L4_CLASS_UDP) {
+ EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV6);
+ flags |= EFX_PKT_UDP;
+ } else {
+ EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV6);
+ }
break;
- case ESE_DZ_L3_CLASS_UNKNOWN:
default:
+ EFX_EV_QSTAT_INCR(eep, EV_RX_NON_IP);
break;
}
- switch (l4_class) {
- case ESE_DZ_L4_CLASS_RSVD7:
- case ESE_DZ_L4_CLASS_RSVD6:
- case ESE_DZ_L4_CLASS_RSVD5:
- case ESE_DZ_L4_CLASS_RSVD4:
- case ESE_DZ_L4_CLASS_RSVD3:
- break;
-
- case ESE_DZ_L4_CLASS_UDP:
- flags |= EFX_PKT_UDP;
- if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR) == 0)
- flags |= EFX_CKSUM_TCPUDP;
- break;
-
- case ESE_DZ_L4_CLASS_TCP:
- flags |= EFX_PKT_TCP;
- if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR) == 0)
+ if (flags & (EFX_PKT_TCP | EFX_PKT_UDP)) {
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR)) {
+ EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_UDP_CHKSUM_ERR);
+ } else {
flags |= EFX_CKSUM_TCPUDP;
- break;
-
- case ESE_DZ_L4_CLASS_UNKNOWN:
- default:
- break;
+ }
}
+deliver:
/* If we're not discarding the packet then it is ok */
if (~flags & EFX_DISCARD)
EFX_EV_QSTAT_INCR(eep, EV_RX_OK);
@@ -835,7 +799,7 @@ ef10_ev_mcdi(
case MCDI_EVENT_CODE_LINKCHANGE: {
efx_link_mode_t link_mode;
- hunt_phy_link_ev(enp, eqp, &link_mode);
+ ef10_phy_link_ev(enp, eqp, &link_mode);
should_abort = eecp->eec_link_change(arg, link_mode);
break;
}
diff --git a/sys/dev/sfxge/common/hunt_impl.h b/sys/dev/sfxge/common/hunt_impl.h
index f8c3b5e..49ecbea 100644
--- a/sys/dev/sfxge/common/hunt_impl.h
+++ b/sys/dev/sfxge/common/hunt_impl.h
@@ -54,6 +54,13 @@ extern "C" {
*/
#define EF10_RX_WPTR_ALIGN 8
+/*
+ * Max byte offset into the packet the TCP header must start for the hardware
+ * to be able to parse the packet correctly.
+ * FIXME: Move to ef10_impl.h when it is included in all driver builds.
+ */
+#define EF10_TCP_HEADER_OFFSET_LIMIT 208
+
/* Invalid RSS context handle */
#define EF10_RSS_CONTEXT_INVALID (0xffffffff)
@@ -165,6 +172,10 @@ ef10_nic_probe(
__in efx_nic_t *enp);
extern __checkReturn efx_rc_t
+hunt_board_cfg(
+ __in efx_nic_t *enp);
+
+extern __checkReturn efx_rc_t
ef10_nic_set_drv_limits(
__inout efx_nic_t *enp,
__in efx_drv_limits_t *edlp);
@@ -209,41 +220,45 @@ ef10_nic_unprobe(
/* MAC */
extern __checkReturn efx_rc_t
-hunt_mac_poll(
+ef10_mac_poll(
__in efx_nic_t *enp,
__out efx_link_mode_t *link_modep);
extern __checkReturn efx_rc_t
-hunt_mac_up(
+ef10_mac_up(
__in efx_nic_t *enp,
__out boolean_t *mac_upp);
extern __checkReturn efx_rc_t
-hunt_mac_addr_set(
+ef10_mac_addr_set(
__in efx_nic_t *enp);
extern __checkReturn efx_rc_t
-hunt_mac_reconfigure(
+ef10_mac_pdu_set(
__in efx_nic_t *enp);
extern __checkReturn efx_rc_t
-hunt_mac_multicast_list_set(
+ef10_mac_reconfigure(
+ __in efx_nic_t *enp);
+
+extern __checkReturn efx_rc_t
+ef10_mac_multicast_list_set(
__in efx_nic_t *enp);
extern __checkReturn efx_rc_t
-hunt_mac_filter_default_rxq_set(
+ef10_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(
+ef10_mac_filter_default_rxq_clear(
__in efx_nic_t *enp);
#if EFSYS_OPT_LOOPBACK
extern __checkReturn efx_rc_t
-hunt_mac_loopback_set(
+ef10_mac_loopback_set(
__in efx_nic_t *enp,
__in efx_link_mode_t link_mode,
__in efx_loopback_type_t loopback_type);
@@ -253,7 +268,7 @@ hunt_mac_loopback_set(
#if EFSYS_OPT_MAC_STATS
extern __checkReturn efx_rc_t
-hunt_mac_stats_update(
+ef10_mac_stats_update(
__in efx_nic_t *enp,
__in efsys_mem_t *esmp,
__inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat,
@@ -276,12 +291,12 @@ ef10_mcdi_fini(
__in efx_nic_t *enp);
extern void
-ef10_mcdi_request_copyin(
+ef10_mcdi_send_request(
__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);
+ __in void *hdrp,
+ __in size_t hdr_len,
+ __in void *sdup,
+ __in size_t sdu_len);
extern __checkReturn boolean_t
ef10_mcdi_poll_response(
@@ -294,11 +309,6 @@ ef10_mcdi_read_response(
__in size_t offset,
__in size_t length);
-extern void
-ef10_mcdi_request_copyout(
- __in efx_nic_t *enp,
- __in efx_mcdi_req_t *emrp);
-
extern efx_rc_t
ef10_mcdi_poll_reboot(
__in efx_nic_t *enp);
@@ -359,39 +369,10 @@ ef10_nvram_partn_write_segment_tlv(
__in boolean_t all_segments);
extern __checkReturn efx_rc_t
-ef10_nvram_partn_size(
- __in efx_nic_t *enp,
- __in uint32_t partn,
- __out size_t *sizep);
-
-extern __checkReturn efx_rc_t
ef10_nvram_partn_lock(
__in efx_nic_t *enp,
__in uint32_t partn);
-extern __checkReturn efx_rc_t
-ef10_nvram_partn_read(
- __in efx_nic_t *enp,
- __in uint32_t partn,
- __in unsigned int offset,
- __out_bcount(size) caddr_t data,
- __in size_t size);
-
-extern __checkReturn efx_rc_t
-ef10_nvram_partn_erase(
- __in efx_nic_t *enp,
- __in uint32_t partn,
- __in unsigned int offset,
- __in size_t size);
-
-extern __checkReturn efx_rc_t
-ef10_nvram_partn_write(
- __in efx_nic_t *enp,
- __in uint32_t partn,
- __in unsigned int offset,
- __out_bcount(size) caddr_t data,
- __in size_t size);
-
extern void
ef10_nvram_partn_unlock(
__in efx_nic_t *enp,
@@ -410,117 +391,122 @@ ef10_nvram_test(
#endif /* EFSYS_OPT_DIAG */
extern __checkReturn efx_rc_t
-ef10_nvram_size(
+ef10_nvram_type_to_partn(
__in efx_nic_t *enp,
__in efx_nvram_type_t type,
+ __out uint32_t *partnp);
+
+extern __checkReturn efx_rc_t
+ef10_nvram_partn_size(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
__out size_t *sizep);
extern __checkReturn efx_rc_t
-ef10_nvram_get_version(
+ef10_nvram_partn_rw_start(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
- __out uint32_t *subtypep,
- __out_ecount(4) uint16_t version[4]);
+ __in uint32_t partn,
+ __out size_t *chunk_sizep);
extern __checkReturn efx_rc_t
-ef10_nvram_rw_start(
+ef10_nvram_partn_read_mode(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
- __out size_t *pref_chunkp);
+ __in uint32_t partn,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size,
+ __in uint32_t mode);
extern __checkReturn efx_rc_t
-ef10_nvram_read_chunk(
+ef10_nvram_partn_read(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
+ __in uint32_t partn,
__in unsigned int offset,
__out_bcount(size) caddr_t data,
__in size_t size);
-extern __checkReturn efx_rc_t
-ef10_nvram_erase(
+extern __checkReturn efx_rc_t
+ef10_nvram_partn_erase(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type);
+ __in uint32_t partn,
+ __in unsigned int offset,
+ __in size_t size);
extern __checkReturn efx_rc_t
-ef10_nvram_write_chunk(
+ef10_nvram_partn_write(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
+ __in uint32_t partn,
__in unsigned int offset,
- __in_bcount(size) caddr_t data,
+ __out_bcount(size) caddr_t data,
__in size_t size);
extern void
-ef10_nvram_rw_finish(
+ef10_nvram_partn_rw_finish(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type);
+ __in uint32_t partn);
extern __checkReturn efx_rc_t
-ef10_nvram_partn_set_version(
+ef10_nvram_partn_get_version(
__in efx_nic_t *enp,
__in uint32_t partn,
- __in_ecount(4) uint16_t version[4]);
+ __out uint32_t *subtypep,
+ __out_ecount(4) uint16_t version[4]);
extern __checkReturn efx_rc_t
-ef10_nvram_set_version(
+ef10_nvram_partn_set_version(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
+ __in uint32_t partn,
__in_ecount(4) uint16_t version[4]);
-extern __checkReturn efx_rc_t
-ef10_nvram_type_to_partn(
- __in efx_nic_t *enp,
- __in efx_nvram_type_t type,
- __out uint32_t *partnp);
-
#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;
+typedef struct ef10_link_state_s {
+ uint32_t els_adv_cap_mask;
+ uint32_t els_lp_cap_mask;
+ unsigned int els_fcntl;
+ efx_link_mode_t els_link_mode;
#if EFSYS_OPT_LOOPBACK
- efx_loopback_type_t hls_loopback;
+ efx_loopback_type_t els_loopback;
#endif
- boolean_t hls_mac_up;
-} hunt_link_state_t;
+ boolean_t els_mac_up;
+} ef10_link_state_t;
extern void
-hunt_phy_link_ev(
+ef10_phy_link_ev(
__in efx_nic_t *enp,
__in efx_qword_t *eqp,
__out efx_link_mode_t *link_modep);
extern __checkReturn efx_rc_t
-hunt_phy_get_link(
+ef10_phy_get_link(
__in efx_nic_t *enp,
- __out hunt_link_state_t *hlsp);
+ __out ef10_link_state_t *elsp);
extern __checkReturn efx_rc_t
-hunt_phy_power(
+ef10_phy_power(
__in efx_nic_t *enp,
__in boolean_t on);
extern __checkReturn efx_rc_t
-hunt_phy_reconfigure(
+ef10_phy_reconfigure(
__in efx_nic_t *enp);
extern __checkReturn efx_rc_t
-hunt_phy_verify(
+ef10_phy_verify(
__in efx_nic_t *enp);
extern __checkReturn efx_rc_t
-hunt_phy_oui_get(
+ef10_phy_oui_get(
__in efx_nic_t *enp,
__out uint32_t *ouip);
#if EFSYS_OPT_PHY_STATS
extern __checkReturn efx_rc_t
-hunt_phy_stats_update(
+ef10_phy_stats_update(
__in efx_nic_t *enp,
__in efsys_mem_t *esmp,
__inout_ecount(EFX_PHY_NSTATS) uint32_t *stat);
@@ -532,21 +518,21 @@ hunt_phy_stats_update(
#if EFSYS_OPT_NAMES
extern const char *
-hunt_phy_prop_name(
+ef10_phy_prop_name(
__in efx_nic_t *enp,
__in unsigned int id);
#endif /* EFSYS_OPT_NAMES */
extern __checkReturn efx_rc_t
-hunt_phy_prop_get(
+ef10_phy_prop_get(
__in efx_nic_t *enp,
__in unsigned int id,
__in uint32_t flags,
__out uint32_t *valp);
extern __checkReturn efx_rc_t
-hunt_phy_prop_set(
+ef10_phy_prop_set(
__in efx_nic_t *enp,
__in unsigned int id,
__in uint32_t val);
@@ -696,6 +682,15 @@ hunt_tx_qdesc_tso_create(
__out efx_desc_t *edp);
extern void
+ef10_tx_qdesc_tso2_create(
+ __in efx_txq_t *etp,
+ __in uint16_t ipv4_id,
+ __in uint32_t tcp_seq,
+ __in uint16_t tcp_mss,
+ __out_ecount(count) efx_desc_t *edp,
+ __in int count);
+
+extern void
ef10_tx_qdesc_vlantci_create(
__in efx_txq_t *etp,
__in uint16_t vlan_tci,
@@ -733,7 +728,7 @@ ef10_tx_qstats_update(
#define HUNT_MIN_PIO_ALLOC_SIZE (HUNT_PIOBUF_SIZE / 32)
-#define HUNT_LEGACY_PF_PRIVILEGE_MASK \
+#define EF10_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 | \
@@ -746,7 +741,7 @@ ef10_tx_qstats_update(
MC_CMD_PRIVILEGE_MASK_IN_GRP_ALL_MULTICAST | \
MC_CMD_PRIVILEGE_MASK_IN_GRP_PROMISCUOUS)
-#define HUNT_LEGACY_VF_PRIVILEGE_MASK 0
+#define EF10_LEGACY_VF_PRIVILEGE_MASK 0
typedef uint32_t efx_piobuf_handle_t;
@@ -886,14 +881,14 @@ ef10_rx_prefix_hash(
__in efx_rx_hash_alg_t func,
__in uint8_t *buffer);
+#endif /* EFSYS_OPT_RX_SCALE */
+
extern __checkReturn efx_rc_t
ef10_rx_prefix_pktlen(
__in efx_nic_t *enp,
__in uint8_t *buffer,
__out uint16_t *lengthp);
-#endif /* EFSYS_OPT_RX_SCALE */
-
extern void
ef10_rx_qpost(
__in efx_rxq_t *erp,
diff --git a/sys/dev/sfxge/common/hunt_mac.c b/sys/dev/sfxge/common/hunt_mac.c
index 358c4d9..a36a11a 100644
--- a/sys/dev/sfxge/common/hunt_mac.c
+++ b/sys/dev/sfxge/common/hunt_mac.c
@@ -38,26 +38,21 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_HUNTINGTON
__checkReturn efx_rc_t
-hunt_mac_poll(
+ef10_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;
+ ef10_link_state_t els;
efx_rc_t rc;
- if ((rc = hunt_phy_get_link(enp, &hls)) != 0)
+ if ((rc = ef10_phy_get_link(enp, &els)) != 0)
goto fail1;
- epp->ep_adv_cap_mask = hls.hls_adv_cap_mask;
- epp->ep_fcntl = hls.hls_fcntl;
+ epp->ep_adv_cap_mask = els.els_adv_cap_mask;
+ epp->ep_fcntl = els.els_fcntl;
- *link_modep = hls.hls_link_mode;
+ *link_modep = els.els_link_mode;
return (0);
@@ -70,26 +65,21 @@ fail1:
}
__checkReturn efx_rc_t
-hunt_mac_up(
+ef10_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;
+ ef10_link_state_t els;
efx_rc_t rc;
/*
- * Because Huntington doesn't *require* polling, we can't rely on
- * hunt_mac_poll() being executed to populate epp->ep_mac_up.
+ * Because EF10 doesn't *require* polling, we can't rely on
+ * ef10_mac_poll() being executed to populate epp->ep_mac_up.
*/
- if ((rc = hunt_phy_get_link(enp, &hls)) != 0)
+ if ((rc = ef10_phy_get_link(enp, &els)) != 0)
goto fail1;
- *mac_upp = hls.hls_mac_up;
+ *mac_upp = els.els_mac_up;
return (0);
@@ -100,7 +90,7 @@ fail1:
}
/*
- * Huntington uses MC_CMD_VADAPTOR_SET_MAC to set the
+ * EF10 adapters use 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
@@ -144,7 +134,7 @@ fail1:
}
__checkReturn efx_rc_t
-hunt_mac_addr_set(
+ef10_mac_addr_set(
__in efx_nic_t *enp)
{
efx_rc_t rc;
@@ -153,8 +143,11 @@ hunt_mac_addr_set(
if (rc != ENOTSUP)
goto fail1;
- /* Fallback for older firmware without Vadapter support */
- if ((rc = hunt_mac_reconfigure(enp)) != 0)
+ /*
+ * Fallback for older Huntington firmware without Vadapter
+ * support.
+ */
+ if ((rc = ef10_mac_reconfigure(enp)) != 0)
goto fail2;
}
@@ -169,8 +162,76 @@ fail1:
return (rc);
}
+static __checkReturn efx_rc_t
+efx_mcdi_mtu_set(
+ __in efx_nic_t *enp,
+ __in uint32_t mtu)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_SET_MAC_EXT_IN_LEN,
+ MC_CMD_SET_MAC_OUT_LEN)];
+ efx_rc_t 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_EXT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN;
+
+ /* Only configure the MTU in this call to MC_CMD_SET_MAC */
+ MCDI_IN_SET_DWORD(req, SET_MAC_EXT_IN_MTU, mtu);
+ MCDI_IN_POPULATE_DWORD_1(req, SET_MAC_EXT_IN_CONTROL,
+ SET_MAC_EXT_IN_CFG_MTU, 1);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+ef10_mac_pdu_set(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_rc_t rc;
+
+ if (encp->enc_enhanced_set_mac_supported) {
+ if ((rc = efx_mcdi_mtu_set(enp, epp->ep_mac_pdu)) != 0)
+ goto fail1;
+ } else {
+ /*
+ * Fallback for older Huntington firmware, which always
+ * configure all of the parameters to MC_CMD_SET_MAC. This isn't
+ * suitable for setting the MTU on unpriviliged functions.
+ */
+ if ((rc = ef10_mac_reconfigure(enp)) != 0)
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
__checkReturn efx_rc_t
-hunt_mac_reconfigure(
+ef10_mac_reconfigure(
__in efx_nic_t *enp)
{
efx_port_t *epp = &(enp->en_port);
@@ -197,6 +258,8 @@ hunt_mac_reconfigure(
* 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.
+ *
+ * FIXME: Does REJECT_UNCST behave the same way on Medford?
*/
MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT,
SET_MAC_IN_REJECT_UNCST, 0,
@@ -247,16 +310,15 @@ fail1:
}
__checkReturn efx_rc_t
-hunt_mac_multicast_list_set(
+ef10_mac_multicast_list_set(
__in efx_nic_t *enp)
{
efx_port_t *epp = &(enp->en_port);
efx_mac_ops_t *emop = epp->ep_emop;
efx_rc_t rc;
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
-
- /* FIXME: Insert filters for multicast list */
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
+ enp->en_family == EFX_FAMILY_MEDFORD);
if ((rc = emop->emo_reconfigure(enp)) != 0)
goto fail1;
@@ -270,7 +332,7 @@ fail1:
}
__checkReturn efx_rc_t
-hunt_mac_filter_default_rxq_set(
+ef10_mac_filter_default_rxq_set(
__in efx_nic_t *enp,
__in efx_rxq_t *erp,
__in boolean_t using_rss)
@@ -304,7 +366,7 @@ fail1:
}
void
-hunt_mac_filter_default_rxq_clear(
+ef10_mac_filter_default_rxq_clear(
__in efx_nic_t *enp)
{
efx_port_t *epp = &(enp->en_port);
@@ -322,23 +384,18 @@ hunt_mac_filter_default_rxq_clear(
#if EFSYS_OPT_LOOPBACK
__checkReturn efx_rc_t
-hunt_mac_loopback_set(
+ef10_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;
efx_rc_t rc;
- /* The PHY object handles this on Huntington */
+ /* The PHY object handles this on EF10 */
old_loopback_type = epp->ep_loopback_type;
old_loopback_link_mode = epp->ep_loopback_link_mode;
epp->ep_loopback_type = loopback_type;
@@ -362,12 +419,12 @@ fail1:
#if EFSYS_OPT_MAC_STATS
-#define HUNT_MAC_STAT_READ(_esmp, _field, _eqp) \
+#define EF10_MAC_STAT_READ(_esmp, _field, _eqp) \
EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp)
__checkReturn efx_rc_t
-hunt_mac_stats_update(
+ef10_mac_stats_update(
__in efx_nic_t *enp,
__in efsys_mem_t *esmp,
__inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat,
@@ -381,301 +438,301 @@ hunt_mac_stats_update(
/* 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,
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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,
+ EF10_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,
+ EF10_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);
+ EF10_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);
+ EF10_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,
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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,
+ EF10_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,
+ EF10_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,
+ EF10_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,
+ EF10_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,
+ EF10_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,
+ EF10_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,
+ EF10_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);
+ EF10_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);
+ EF10_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,
+ EF10_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,
+ EF10_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,
+ EF10_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,
+ EF10_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,
+ EF10_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,
+ EF10_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);
+ EF10_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);
+ EF10_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);
+ EF10_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,
+ EF10_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 */
diff --git a/sys/dev/sfxge/common/hunt_mcdi.c b/sys/dev/sfxge/common/hunt_mcdi.c
index 1cccb23..f39e977 100644
--- a/sys/dev/sfxge/common/hunt_mcdi.c
+++ b/sys/dev/sfxge/common/hunt_mcdi.c
@@ -43,37 +43,6 @@ __FBSDID("$FreeBSD$");
#error "WITH_MCDI_V2 required for EF10 MCDIv2 commands."
#endif
-typedef enum efx_mcdi_header_type_e {
- EFX_MCDI_HEADER_TYPE_V1, /* MCDIv0 (BootROM), MCDIv1 commands */
- EFX_MCDI_HEADER_TYPE_V2, /* MCDIv2 commands */
-} efx_mcdi_header_type_t;
-
-/*
- * Return the header format to use for sending an MCDI request.
- *
- * An MCDIv1 (Siena compatible) command should use MCDIv2 encapsulation if the
- * request input buffer or response output buffer are too large for the MCDIv1
- * format. An MCDIv2 command must always be sent using MCDIv2 encapsulation.
- */
-#define EFX_MCDI_HEADER_TYPE(_cmd, _length) \
- ((((_cmd) & ~EFX_MASK32(MCDI_HEADER_CODE)) || \
- ((_length) & ~EFX_MASK32(MCDI_HEADER_DATALEN))) ? \
- EFX_MCDI_HEADER_TYPE_V2 : EFX_MCDI_HEADER_TYPE_V1)
-
-
-/*
- * MCDI Header NOT_EPOCH flag
- * ==========================
- * A new epoch begins at initial startup or after an MC reboot, and defines when
- * the MC should reject stale MCDI requests.
- *
- * The first MCDI request sent by the host should contain NOT_EPOCH=0, and all
- * subsequent requests (until the next MC reboot) should contain NOT_EPOCH=1.
- *
- * After rebooting the MC will fail all requests with NOT_EPOCH=1 by writing a
- * response with ERROR=1 and DATALEN=0 until a request is seen with NOT_EPOCH=0.
- */
-
__checkReturn efx_rc_t
ef10_mcdi_init(
@@ -139,7 +108,7 @@ ef10_mcdi_fini(
emip->emi_new_epoch = B_FALSE;
}
-static void
+ void
ef10_mcdi_send_request(
__in efx_nic_t *enp,
__in void *hdrp,
@@ -181,118 +150,6 @@ ef10_mcdi_send_request(
EFX_BAR_WRITED(enp, ER_DZ_MC_DB_HWRD_REG, &dword, B_FALSE);
}
- void
-ef10_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)
-{
-#if EFSYS_OPT_MCDI_LOGGING
- const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
-#endif /* EFSYS_OPT_MCDI_LOGGING */
- efx_mcdi_header_type_t hdr_type;
- efx_dword_t hdr[2];
- size_t hdr_len;
- unsigned int xflags;
-
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
- enp->en_family == EFX_FAMILY_MEDFORD);
-
- xflags = 0;
- if (ev_cpl)
- xflags |= MCDI_HEADER_XFLAGS_EVREQ;
-
- hdr_type = EFX_MCDI_HEADER_TYPE(emrp->emr_cmd,
- MAX(emrp->emr_in_length, emrp->emr_out_length));
-
- if (hdr_type == EFX_MCDI_HEADER_TYPE_V2) {
- /* Construct MCDI v2 header */
- hdr_len = sizeof (hdr);
- EFX_POPULATE_DWORD_8(hdr[0],
- MCDI_HEADER_CODE, MC_CMD_V2_EXTN,
- MCDI_HEADER_RESYNC, 1,
- MCDI_HEADER_DATALEN, 0,
- MCDI_HEADER_SEQ, seq,
- MCDI_HEADER_NOT_EPOCH, new_epoch ? 0 : 1,
- MCDI_HEADER_ERROR, 0,
- MCDI_HEADER_RESPONSE, 0,
- MCDI_HEADER_XFLAGS, xflags);
-
- EFX_POPULATE_DWORD_2(hdr[1],
- MC_CMD_V2_EXTN_IN_EXTENDED_CMD, emrp->emr_cmd,
- MC_CMD_V2_EXTN_IN_ACTUAL_LEN, emrp->emr_in_length);
- } else {
- /* Construct MCDI v1 header */
- hdr_len = sizeof (hdr[0]);
- EFX_POPULATE_DWORD_8(hdr[0],
- MCDI_HEADER_CODE, emrp->emr_cmd,
- MCDI_HEADER_RESYNC, 1,
- MCDI_HEADER_DATALEN, emrp->emr_in_length,
- MCDI_HEADER_SEQ, seq,
- MCDI_HEADER_NOT_EPOCH, new_epoch ? 0 : 1,
- MCDI_HEADER_ERROR, 0,
- MCDI_HEADER_RESPONSE, 0,
- MCDI_HEADER_XFLAGS, xflags);
- }
-
-#if EFSYS_OPT_MCDI_LOGGING
- if (emtp->emt_logger != NULL) {
- emtp->emt_logger(emtp->emt_context, EFX_LOG_MCDI_REQUEST,
- &hdr, hdr_len,
- emrp->emr_in_buf, emrp->emr_in_length);
- }
-#endif /* EFSYS_OPT_MCDI_LOGGING */
-
- ef10_mcdi_send_request(enp, &hdr[0], hdr_len,
- emrp->emr_in_buf, emrp->emr_in_length);
-}
-
- void
-ef10_mcdi_request_copyout(
- __in efx_nic_t *enp,
- __in efx_mcdi_req_t *emrp)
-{
-#if EFSYS_OPT_MCDI_LOGGING
- const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
-#endif /* EFSYS_OPT_MCDI_LOGGING */
- efx_dword_t hdr[2];
- unsigned int hdr_len;
- size_t bytes;
-
- if (emrp->emr_out_buf == NULL)
- return;
-
- /* Read the command header to detect MCDI response format */
- hdr_len = sizeof (hdr[0]);
- ef10_mcdi_read_response(enp, &hdr[0], 0, hdr_len);
- if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) {
- /*
- * Read the actual payload length. The length given in the event
- * is only correct for responses with the V1 format.
- */
- ef10_mcdi_read_response(enp, &hdr[1], hdr_len, sizeof (hdr[1]));
- hdr_len += sizeof (hdr[1]);
-
- emrp->emr_out_length_used = EFX_DWORD_FIELD(hdr[1],
- MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
- }
-
- /* Copy payload out into caller supplied buffer */
- bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length);
- ef10_mcdi_read_response(enp, emrp->emr_out_buf, hdr_len, bytes);
-
-#if EFSYS_OPT_MCDI_LOGGING
- if (emtp->emt_logger != NULL) {
- emtp->emt_logger(emtp->emt_context,
- EFX_LOG_MCDI_RESPONSE,
- &hdr, hdr_len,
- emrp->emr_out_buf, bytes);
- }
-#endif /* EFSYS_OPT_MCDI_LOGGING */
-}
-
__checkReturn boolean_t
ef10_mcdi_poll_response(
__in efx_nic_t *enp)
diff --git a/sys/dev/sfxge/common/hunt_nic.c b/sys/dev/sfxge/common/hunt_nic.c
index d87f3cd..7f0c068 100644
--- a/sys/dev/sfxge/common/hunt_nic.c
+++ b/sys/dev/sfxge/common/hunt_nic.c
@@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$");
#include "ef10_tlv_layout.h"
-static __checkReturn efx_rc_t
+ __checkReturn efx_rc_t
efx_mcdi_get_port_assignment(
__in efx_nic_t *enp,
__out uint32_t *portp)
@@ -85,7 +85,7 @@ fail1:
return (rc);
}
-static __checkReturn efx_rc_t
+ __checkReturn efx_rc_t
efx_mcdi_get_port_modes(
__in efx_nic_t *enp,
__out uint32_t *modesp)
@@ -112,7 +112,10 @@ efx_mcdi_get_port_modes(
goto fail1;
}
- /* Accept pre-Medford size (8 bytes - no CurrentMode field) */
+ /*
+ * Require only Modes and DefaultMode fields.
+ * (CurrentMode field was added for Medford)
+ */
if (req.emr_out_length_used <
MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST) {
rc = EMSGSIZE;
@@ -205,7 +208,7 @@ fail1:
return (rc);
}
-static __checkReturn efx_rc_t
+ __checkReturn efx_rc_t
efx_mcdi_get_mac_address_pf(
__in efx_nic_t *enp,
__out_ecount_opt(6) uint8_t mac_addrp[6])
@@ -263,7 +266,7 @@ fail1:
return (rc);
}
-static __checkReturn efx_rc_t
+ __checkReturn efx_rc_t
efx_mcdi_get_mac_address_vf(
__in efx_nic_t *enp,
__out_ecount_opt(6) uint8_t mac_addrp[6])
@@ -326,7 +329,7 @@ fail1:
return (rc);
}
-static __checkReturn efx_rc_t
+ __checkReturn efx_rc_t
efx_mcdi_get_clock(
__in efx_nic_t *enp,
__out uint32_t *sys_freqp)
@@ -376,7 +379,7 @@ fail1:
return (rc);
}
-static __checkReturn efx_rc_t
+ __checkReturn efx_rc_t
efx_mcdi_get_vector_cfg(
__in efx_nic_t *enp,
__out_opt uint32_t *vec_basep,
@@ -427,8 +430,8 @@ fail1:
static __checkReturn efx_rc_t
efx_mcdi_get_capabilities(
__in efx_nic_t *enp,
- __out efx_dword_t *flagsp,
- __out efx_dword_t *flags2p)
+ __out uint32_t *flagsp,
+ __out uint32_t *flags2p)
{
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN,
@@ -454,13 +457,12 @@ efx_mcdi_get_capabilities(
goto fail2;
}
- *flagsp = *MCDI_OUT2(req, efx_dword_t, GET_CAPABILITIES_OUT_FLAGS1);
+ *flagsp = MCDI_OUT_DWORD(req, GET_CAPABILITIES_OUT_FLAGS1);
if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_V2_OUT_LEN)
- EFX_ZERO_DWORD(*flags2p);
+ *flags2p = 0;
else
- *flags2p = *MCDI_OUT2(req, efx_dword_t,
- GET_CAPABILITIES_V2_OUT_FLAGS2);
+ *flags2p = MCDI_OUT_DWORD(req, GET_CAPABILITIES_V2_OUT_FLAGS2);
return (0);
@@ -889,76 +891,75 @@ ef10_nic_pio_unlink(
return (efx_mcdi_unlink_piobuf(enp, vi_index));
}
-static __checkReturn efx_rc_t
+ __checkReturn efx_rc_t
ef10_get_datapath_caps(
__in efx_nic_t *enp)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_dword_t datapath_capabilities;
- efx_dword_t datapath_capabilities_v2;
+ uint32_t flags;
+ uint32_t flags2;
efx_rc_t rc;
- if ((rc = efx_mcdi_get_capabilities(enp, &datapath_capabilities,
- &datapath_capabilities_v2)) != 0)
+ if ((rc = efx_mcdi_get_capabilities(enp, &flags, &flags2)) != 0)
goto fail1;
+#define CAP_FLAG(flags1, field) \
+ ((flags1) & (1 << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## field ## _LBN)))
+
+#define CAP_FLAG2(flags2, field) \
+ ((flags2) & (1 << (MC_CMD_GET_CAPABILITIES_V2_OUT_ ## field ## _LBN)))
+
/*
* Huntington RXDP firmware inserts a 0 or 14 byte prefix.
* We only support the 14 byte prefix here.
*/
- if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
- GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14) != 1) {
+ if (CAP_FLAG(flags, RX_PREFIX_LEN_14) == 0) {
rc = ENOTSUP;
goto fail2;
}
encp->enc_rx_prefix_size = 14;
/* Check if the firmware supports TSO */
- if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
- GET_CAPABILITIES_OUT_TX_TSO) == 1)
- encp->enc_fw_assisted_tso_enabled = B_TRUE;
- else
- encp->enc_fw_assisted_tso_enabled = B_FALSE;
+ encp->enc_fw_assisted_tso_enabled =
+ CAP_FLAG(flags, TX_TSO) ? B_TRUE : B_FALSE;
+
+ /* Check if the firmware supports FATSOv2 */
+ encp->enc_fw_assisted_tso_v2_enabled =
+ CAP_FLAG2(flags2, TX_TSO_V2) ? B_TRUE : B_FALSE;
/* Check if the firmware has vadapter/vport/vswitch support */
- if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
- GET_CAPABILITIES_OUT_EVB) == 1)
- encp->enc_datapath_cap_evb = B_TRUE;
- else
- encp->enc_datapath_cap_evb = B_FALSE;
+ encp->enc_datapath_cap_evb =
+ CAP_FLAG(flags, EVB) ? B_TRUE : B_FALSE;
/* Check if the firmware supports VLAN insertion */
- if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
- GET_CAPABILITIES_OUT_TX_VLAN_INSERTION) == 1)
- encp->enc_hw_tx_insert_vlan_enabled = B_TRUE;
- else
- encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
+ encp->enc_hw_tx_insert_vlan_enabled =
+ CAP_FLAG(flags, TX_VLAN_INSERTION) ? B_TRUE : B_FALSE;
/* Check if the firmware supports RX event batching */
- if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
- GET_CAPABILITIES_OUT_RX_BATCHING) == 1) {
- encp->enc_rx_batching_enabled = B_TRUE;
+ encp->enc_rx_batching_enabled =
+ CAP_FLAG(flags, RX_BATCHING) ? B_TRUE : B_FALSE;
+
+ if (encp->enc_rx_batching_enabled)
encp->enc_rx_batch_max = 16;
- } else {
- encp->enc_rx_batching_enabled = B_FALSE;
- }
/* Check if the firmware supports disabling scatter on RXQs */
- if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
- GET_CAPABILITIES_OUT_RX_DISABLE_SCATTER) == 1) {
- encp->enc_rx_disable_scatter_supported = B_TRUE;
- } else {
- encp->enc_rx_disable_scatter_supported = B_FALSE;
- }
+ encp->enc_rx_disable_scatter_supported =
+ CAP_FLAG(flags, RX_DISABLE_SCATTER) ? B_TRUE : B_FALSE;
/* Check if the firmware supports set mac with running filters */
- if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
- GET_CAPABILITIES_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED)
- == 1) {
- encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
- } else {
- encp->enc_allow_set_mac_with_installed_filters = B_FALSE;
- }
+ encp->enc_allow_set_mac_with_installed_filters =
+ CAP_FLAG(flags, VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED) ?
+ B_TRUE : B_FALSE;
+
+ /*
+ * Check if firmware supports the extended MC_CMD_SET_MAC, which allows
+ * specifying which parameters to configure.
+ */
+ encp->enc_enhanced_set_mac_supported =
+ CAP_FLAG(flags, SET_MAC_ENHANCED) ? B_TRUE : B_FALSE;
+
+#undef CAP_FLAG
+#undef CAP_FLAG2
return (0);
@@ -970,6 +971,42 @@ fail1:
return (rc);
}
+
+ __checkReturn efx_rc_t
+ef10_get_privilege_mask(
+ __in efx_nic_t *enp,
+ __out uint32_t *maskp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint32_t mask;
+ efx_rc_t rc;
+
+ if ((rc = efx_mcdi_privilege_mask(enp, encp->enc_pf, encp->enc_vf,
+ &mask)) != 0) {
+ if (rc != ENOTSUP)
+ goto fail1;
+
+ /* Fallback for old firmware without privilege mask support */
+ if (EFX_PCI_FUNCTION_IS_PF(encp)) {
+ /* Assume PF has admin privilege */
+ mask = EF10_LEGACY_PF_PRIVILEGE_MASK;
+ } else {
+ /* VF is always unprivileged by default */
+ mask = EF10_LEGACY_VF_PRIVILEGE_MASK;
+ }
+ }
+
+ *maskp = mask;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+
/*
* The external port mapping is a one-based numbering of the external
* connectors on the board. It does not distinguish off-board separated
@@ -992,6 +1029,13 @@ static struct {
(1 << TLV_PORT_MODE_10G_10G_10G_10G),
1
},
+ {
+ EFX_FAMILY_MEDFORD,
+ (1 << TLV_PORT_MODE_10G) |
+ (1 << TLV_PORT_MODE_10G_10G) |
+ (1 << TLV_PORT_MODE_10G_10G_10G_10G),
+ 1
+ },
/* Supported modes requiring 2 outputs per port */
{
EFX_FAMILY_HUNTINGTON,
@@ -1000,18 +1044,25 @@ static struct {
(1 << TLV_PORT_MODE_40G_10G_10G) |
(1 << TLV_PORT_MODE_10G_10G_40G),
2
- }
- /*
- * NOTE: Medford modes will require 4 outputs per port:
- * TLV_PORT_MODE_10G_10G_10G_10G_Q
- * TLV_PORT_MODE_10G_10G_10G_10G_Q2
- * The Q2 mode routes outputs to external port 2. Support for this
- * will require a new field specifying the number to add after
- * scaling by stride. This is fixed at 1 currently.
- */
+ },
+ {
+ EFX_FAMILY_MEDFORD,
+ (1 << TLV_PORT_MODE_40G) |
+ (1 << TLV_PORT_MODE_40G_40G) |
+ (1 << TLV_PORT_MODE_40G_10G_10G) |
+ (1 << TLV_PORT_MODE_10G_10G_40G),
+ 2
+ },
+ /* Supported modes requiring 4 outputs per port */
+ {
+ EFX_FAMILY_MEDFORD,
+ (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q) |
+ (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q2),
+ 4
+ },
};
-static __checkReturn efx_rc_t
+ __checkReturn efx_rc_t
ef10_external_port_mapping(
__in efx_nic_t *enp,
__in uint32_t port,
@@ -1064,7 +1115,7 @@ fail1:
return (rc);
}
-static __checkReturn efx_rc_t
+ __checkReturn efx_rc_t
hunt_board_cfg(
__in efx_nic_t *enp)
{
@@ -1072,7 +1123,7 @@ hunt_board_cfg(
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
uint8_t mac_addr[6];
uint32_t board_type = 0;
- hunt_link_state_t hls;
+ ef10_link_state_t els;
efx_port_t *epp = &(enp->en_port);
uint32_t port;
uint32_t pf;
@@ -1146,10 +1197,10 @@ hunt_board_cfg(
goto fail6;
/* Obtain the default PHY advertised capabilities */
- if ((rc = hunt_phy_get_link(enp, &hls)) != 0)
+ if ((rc = ef10_phy_get_link(enp, &els)) != 0)
goto fail7;
- epp->ep_default_adv_cap_mask = hls.hls_adv_cap_mask;
- epp->ep_adv_cap_mask = hls.hls_adv_cap_mask;
+ epp->ep_default_adv_cap_mask = els.els_adv_cap_mask;
+ epp->ep_adv_cap_mask = els.els_adv_cap_mask;
/*
* Enable firmware workarounds for hardware errata.
@@ -1288,20 +1339,8 @@ hunt_board_cfg(
* the privilege mask to check for sufficient privileges, as that
* can result in time-of-check/time-of-use bugs.
*/
- if ((rc = efx_mcdi_privilege_mask(enp, pf, vf, &mask)) != 0) {
- if (rc != ENOTSUP)
- goto fail13;
-
- /* Fallback for old firmware without privilege mask support */
- if (EFX_PCI_FUNCTION_IS_PF(encp)) {
- /* Assume PF has admin privilege */
- mask = HUNT_LEGACY_PF_PRIVILEGE_MASK;
- } else {
- /* VF is always unprivileged by default */
- mask = HUNT_LEGACY_VF_PRIVILEGE_MASK;
- }
- }
-
+ if ((rc = ef10_get_privilege_mask(enp, &mask)) != 0)
+ goto fail13;
encp->enc_privilege_mask = mask;
/* Get interrupt vector limits */
@@ -1320,7 +1359,7 @@ hunt_board_cfg(
* Maximum number of bytes into the frame the TCP header can start for
* firmware assisted TSO to work.
*/
- encp->enc_tx_tso_tcp_header_offset_limit = 208;
+ encp->enc_tx_tso_tcp_header_offset_limit = EF10_TCP_HEADER_OFFSET_LIMIT;
return (0);
@@ -1361,6 +1400,7 @@ fail1:
ef10_nic_probe(
__in efx_nic_t *enp)
{
+ efx_nic_ops_t *enop = enp->en_enop;
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
efx_rc_t rc;
@@ -1380,7 +1420,7 @@ ef10_nic_probe(
if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
goto fail3;
- if ((rc = hunt_board_cfg(enp)) != 0)
+ if ((rc = enop->eno_board_cfg(enp)) != 0)
if (rc != EACCES)
goto fail4;
diff --git a/sys/dev/sfxge/common/hunt_nvram.c b/sys/dev/sfxge/common/hunt_nvram.c
index 35c5ddd..dd471f4 100644
--- a/sys/dev/sfxge/common/hunt_nvram.c
+++ b/sys/dev/sfxge/common/hunt_nvram.c
@@ -598,8 +598,9 @@ ef10_nvram_read_tlv_segment(
}
/* Read initial chunk of the segment, starting at offset */
- if ((rc = ef10_nvram_partn_read(enp, partn, seg_offset, seg_data,
- EF10_NVRAM_CHUNK)) != 0) {
+ if ((rc = ef10_nvram_partn_read_mode(enp, partn, seg_offset, seg_data,
+ EF10_NVRAM_CHUNK,
+ MC_CMD_NVRAM_READ_IN_V2_TARGET_CURRENT)) != 0) {
goto fail2;
}
@@ -624,10 +625,11 @@ ef10_nvram_read_tlv_segment(
/* Read the remaining segment content */
if (total_length > EF10_NVRAM_CHUNK) {
- if ((rc = ef10_nvram_partn_read(enp, partn,
+ if ((rc = ef10_nvram_partn_read_mode(enp, partn,
seg_offset + EF10_NVRAM_CHUNK,
seg_data + EF10_NVRAM_CHUNK,
- total_length - EF10_NVRAM_CHUNK)) != 0)
+ total_length - EF10_NVRAM_CHUNK,
+ MC_CMD_NVRAM_READ_IN_V2_TARGET_CURRENT)) != 0)
goto fail6;
}
@@ -1321,12 +1323,13 @@ fail1:
}
__checkReturn efx_rc_t
-ef10_nvram_partn_read(
+ef10_nvram_partn_read_mode(
__in efx_nic_t *enp,
__in uint32_t partn,
__in unsigned int offset,
__out_bcount(size) caddr_t data,
- __in size_t size)
+ __in size_t size,
+ __in uint32_t mode)
{
size_t chunk;
efx_rc_t rc;
@@ -1335,7 +1338,7 @@ ef10_nvram_partn_read(
chunk = MIN(size, EF10_NVRAM_CHUNK);
if ((rc = efx_mcdi_nvram_read(enp, partn, offset,
- data, chunk)) != 0) {
+ data, chunk, mode)) != 0) {
goto fail1;
}
@@ -1353,6 +1356,22 @@ fail1:
}
__checkReturn efx_rc_t
+ef10_nvram_partn_read(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ /*
+ * Read requests which come in through the EFX API expect to
+ * read the current, active partition.
+ */
+ return ef10_nvram_partn_read_mode(enp, partn, offset, data, size,
+ MC_CMD_NVRAM_READ_IN_V2_TARGET_CURRENT);
+}
+
+ __checkReturn efx_rc_t
ef10_nvram_partn_erase(
__in efx_nic_t *enp,
__in uint32_t partn,
@@ -1541,7 +1560,11 @@ static ef10_parttbl_entry_t hunt_parttbl[] = {
{NVRAM_PARTITION_TYPE_FPGA_BACKUP, 1, EFX_NVRAM_FPGA_BACKUP},
{NVRAM_PARTITION_TYPE_FPGA_BACKUP, 2, EFX_NVRAM_FPGA_BACKUP},
{NVRAM_PARTITION_TYPE_FPGA_BACKUP, 3, EFX_NVRAM_FPGA_BACKUP},
- {NVRAM_PARTITION_TYPE_FPGA_BACKUP, 4, EFX_NVRAM_FPGA_BACKUP}
+ {NVRAM_PARTITION_TYPE_FPGA_BACKUP, 4, EFX_NVRAM_FPGA_BACKUP},
+ {NVRAM_PARTITION_TYPE_LICENSE, 1, EFX_NVRAM_LICENSE},
+ {NVRAM_PARTITION_TYPE_LICENSE, 2, EFX_NVRAM_LICENSE},
+ {NVRAM_PARTITION_TYPE_LICENSE, 3, EFX_NVRAM_LICENSE},
+ {NVRAM_PARTITION_TYPE_LICENSE, 4, EFX_NVRAM_LICENSE}
};
static ef10_parttbl_entry_t medford_parttbl[] = {
@@ -1572,7 +1595,11 @@ static ef10_parttbl_entry_t medford_parttbl[] = {
{NVRAM_PARTITION_TYPE_FPGA_BACKUP, 1, EFX_NVRAM_FPGA_BACKUP},
{NVRAM_PARTITION_TYPE_FPGA_BACKUP, 2, EFX_NVRAM_FPGA_BACKUP},
{NVRAM_PARTITION_TYPE_FPGA_BACKUP, 3, EFX_NVRAM_FPGA_BACKUP},
- {NVRAM_PARTITION_TYPE_FPGA_BACKUP, 4, EFX_NVRAM_FPGA_BACKUP}
+ {NVRAM_PARTITION_TYPE_FPGA_BACKUP, 4, EFX_NVRAM_FPGA_BACKUP},
+ {NVRAM_PARTITION_TYPE_LICENSE, 1, EFX_NVRAM_LICENSE},
+ {NVRAM_PARTITION_TYPE_LICENSE, 2, EFX_NVRAM_LICENSE},
+ {NVRAM_PARTITION_TYPE_LICENSE, 3, EFX_NVRAM_LICENSE},
+ {NVRAM_PARTITION_TYPE_LICENSE, 4, EFX_NVRAM_LICENSE}
};
static __checkReturn efx_rc_t
@@ -1707,56 +1734,23 @@ fail1:
#endif /* EFSYS_OPT_DIAG */
__checkReturn efx_rc_t
-ef10_nvram_size(
- __in efx_nic_t *enp,
- __in efx_nvram_type_t type,
- __out size_t *sizep)
-{
- uint32_t partn;
- efx_rc_t rc;
-
- if ((rc = ef10_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
- if ((rc = ef10_nvram_partn_size(enp, partn, sizep)) != 0)
- goto fail2;
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- *sizep = 0;
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-ef10_nvram_get_version(
+ef10_nvram_partn_get_version(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
+ __in uint32_t partn,
__out uint32_t *subtypep,
__out_ecount(4) uint16_t version[4])
{
- uint32_t partn;
efx_rc_t rc;
- if ((rc = ef10_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
/* FIXME: get highest partn version from all ports */
/* FIXME: return partn description if available */
if ((rc = efx_mcdi_nvram_metadata(enp, partn, subtypep,
version, NULL, 0)) != 0)
- goto fail2;
+ goto fail1;
return (0);
-fail2:
- EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
@@ -1764,111 +1758,21 @@ fail1:
}
__checkReturn efx_rc_t
-ef10_nvram_rw_start(
+ef10_nvram_partn_rw_start(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
+ __in uint32_t partn,
__out size_t *chunk_sizep)
{
- uint32_t partn;
efx_rc_t rc;
- if ((rc = ef10_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
if ((rc = ef10_nvram_partn_lock(enp, partn)) != 0)
- goto fail2;
+ goto fail1;
if (chunk_sizep != NULL)
*chunk_sizep = EF10_NVRAM_CHUNK;
return (0);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-ef10_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)
-{
- uint32_t partn;
- efx_rc_t rc;
-
- if ((rc = ef10_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
- if ((rc = ef10_nvram_partn_read(enp, partn, offset, data, size)) != 0)
- goto fail2;
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-ef10_nvram_erase(
- __in efx_nic_t *enp,
- __in efx_nvram_type_t type)
-{
- uint32_t partn;
- size_t size;
- efx_rc_t rc;
-
- if ((rc = ef10_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
- if ((rc = ef10_nvram_partn_size(enp, partn, &size)) != 0)
- goto fail2;
-
- if ((rc = ef10_nvram_partn_erase(enp, partn, 0, size)) != 0)
- goto fail3;
-
- return (0);
-
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-ef10_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)
-{
- uint32_t partn;
- efx_rc_t rc;
-
- if ((rc = ef10_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
- if ((rc = ef10_nvram_partn_write(enp, partn, offset, data, size)) != 0)
- goto fail2;
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
@@ -1876,40 +1780,11 @@ fail1:
}
void
-ef10_nvram_rw_finish(
- __in efx_nic_t *enp,
- __in efx_nvram_type_t type)
-{
- uint32_t partn;
- efx_rc_t rc;
-
- if ((rc = ef10_nvram_type_to_partn(enp, type, &partn)) == 0)
- ef10_nvram_partn_unlock(enp, partn);
-}
-
- __checkReturn efx_rc_t
-ef10_nvram_set_version(
+ef10_nvram_partn_rw_finish(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
- __in_ecount(4) uint16_t version[4])
+ __in uint32_t partn)
{
- uint32_t partn;
- efx_rc_t rc;
-
- if ((rc = ef10_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
- if ((rc = ef10_nvram_partn_set_version(enp, partn, version)) != 0)
- goto fail2;
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
+ ef10_nvram_partn_unlock(enp, partn);
}
#endif /* EFSYS_OPT_NVRAM */
diff --git a/sys/dev/sfxge/common/hunt_phy.c b/sys/dev/sfxge/common/hunt_phy.c
index c25e820..a6b7faa 100644
--- a/sys/dev/sfxge/common/hunt_phy.c
+++ b/sys/dev/sfxge/common/hunt_phy.c
@@ -37,15 +37,10 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_HUNTINGTON
static void
-hunt_phy_decode_cap(
+mcdi_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;
@@ -76,7 +71,7 @@ hunt_phy_decode_cap(
}
static void
-hunt_phy_decode_link_mode(
+mcdi_phy_decode_link_mode(
__in efx_nic_t *enp,
__in uint32_t link_flags,
__in unsigned int speed,
@@ -84,11 +79,6 @@ hunt_phy_decode_link_mode(
__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 &
@@ -127,16 +117,11 @@ hunt_phy_decode_link_mode(
void
-hunt_phy_link_ev(
+ef10_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;
@@ -167,10 +152,10 @@ hunt_phy_link_ev(
}
link_flags = MCDI_EV_FIELD(eqp, LINKCHANGE_LINK_FLAGS);
- hunt_phy_decode_link_mode(enp, link_flags, speed,
+ mcdi_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),
+ mcdi_phy_decode_cap(MCDI_EV_FIELD(eqp, LINKCHANGE_LP_CAP),
&lp_cap_mask);
/*
@@ -191,19 +176,17 @@ hunt_phy_link_ev(
}
__checkReturn efx_rc_t
-hunt_phy_power(
+ef10_phy_power(
__in efx_nic_t *enp,
__in boolean_t power)
{
- /* TBD: consider common Siena/Hunt function: essentially identical */
-
efx_rc_t rc;
if (!power)
return (0);
/* Check if the PHY is a zombie */
- if ((rc = hunt_phy_verify(enp)) != 0)
+ if ((rc = ef10_phy_verify(enp)) != 0)
goto fail1;
enp->en_reset_flags |= EFX_RESET_PHY;
@@ -217,16 +200,10 @@ fail1:
}
__checkReturn efx_rc_t
-hunt_phy_get_link(
+ef10_phy_get_link(
__in efx_nic_t *enp,
- __out hunt_link_state_t *hlsp)
+ __out ef10_link_state_t *elsp)
{
- /*
- * 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)];
@@ -251,15 +228,15 @@ hunt_phy_get_link(
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);
+ mcdi_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_CAP),
+ &elsp->els_adv_cap_mask);
+ mcdi_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_LP_CAP),
+ &elsp->els_lp_cap_mask);
- hunt_phy_decode_link_mode(enp, MCDI_OUT_DWORD(req, GET_LINK_OUT_FLAGS),
+ mcdi_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);
+ &elsp->els_link_mode, &elsp->els_fcntl);
#if EFSYS_OPT_LOOPBACK
/* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
@@ -282,10 +259,10 @@ hunt_phy_get_link(
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);
+ elsp->els_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;
+ elsp->els_mac_up = MCDI_OUT_DWORD(req, GET_LINK_OUT_MAC_FAULT) == 0;
return (0);
@@ -298,15 +275,9 @@ fail1:
}
__checkReturn efx_rc_t
-hunt_phy_reconfigure(
+ef10_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;
@@ -428,11 +399,9 @@ fail1:
}
__checkReturn efx_rc_t
-hunt_phy_verify(
+ef10_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)];
@@ -479,7 +448,7 @@ fail1:
}
__checkReturn efx_rc_t
-hunt_phy_oui_get(
+ef10_phy_oui_get(
__in efx_nic_t *enp,
__out uint32_t *ouip)
{
@@ -491,7 +460,7 @@ hunt_phy_oui_get(
#if EFSYS_OPT_PHY_STATS
__checkReturn efx_rc_t
-hunt_phy_stats_update(
+ef10_phy_stats_update(
__in efx_nic_t *enp,
__in efsys_mem_t *esmp,
__inout_ecount(EFX_PHY_NSTATS) uint32_t *stat)
@@ -509,8 +478,8 @@ hunt_phy_stats_update(
#if EFSYS_OPT_NAMES
-extern const char *
-hunt_phy_prop_name(
+ const char *
+ef10_phy_prop_name(
__in efx_nic_t *enp,
__in unsigned int id)
{
@@ -521,8 +490,8 @@ hunt_phy_prop_name(
#endif /* EFSYS_OPT_NAMES */
-extern __checkReturn efx_rc_t
-hunt_phy_prop_get(
+ __checkReturn efx_rc_t
+ef10_phy_prop_get(
__in efx_nic_t *enp,
__in unsigned int id,
__in uint32_t flags,
@@ -533,8 +502,8 @@ hunt_phy_prop_get(
return (ENOTSUP);
}
-extern __checkReturn efx_rc_t
-hunt_phy_prop_set(
+ __checkReturn efx_rc_t
+ef10_phy_prop_set(
__in efx_nic_t *enp,
__in unsigned int id,
__in uint32_t val)
diff --git a/sys/dev/sfxge/common/hunt_tx.c b/sys/dev/sfxge/common/hunt_tx.c
index 593db88..baa7444 100755
--- a/sys/dev/sfxge/common/hunt_tx.c
+++ b/sys/dev/sfxge/common/hunt_tx.c
@@ -87,12 +87,13 @@ efx_mcdi_init_txq(
MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_LABEL, label);
MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_INSTANCE, instance);
- MCDI_IN_POPULATE_DWORD_6(req, INIT_TXQ_IN_FLAGS,
+ MCDI_IN_POPULATE_DWORD_7(req, INIT_TXQ_IN_FLAGS,
INIT_TXQ_IN_FLAG_BUFF_MODE, 0,
INIT_TXQ_IN_FLAG_IP_CSUM_DIS,
(flags & EFX_TXQ_CKSUM_IPV4) ? 0 : 1,
INIT_TXQ_IN_FLAG_TCP_CSUM_DIS,
(flags & EFX_TXQ_CKSUM_TCPUDP) ? 0 : 1,
+ INIT_TXQ_EXT_IN_FLAG_TSOV2_EN, (flags & EFX_TXQ_FATSOV2) ? 1 : 0,
INIT_TXQ_IN_FLAG_TCP_UDP_ONLY, 0,
INIT_TXQ_IN_CRC_MODE, 0,
INIT_TXQ_IN_FLAG_TIMESTAMP, 0);
@@ -589,6 +590,38 @@ hunt_tx_qdesc_tso_create(
}
void
+ef10_tx_qdesc_tso2_create(
+ __in efx_txq_t *etp,
+ __in uint16_t ipv4_id,
+ __in uint32_t tcp_seq,
+ __in uint16_t tcp_mss,
+ __out_ecount(count) efx_desc_t *edp,
+ __in int count)
+{
+ EFSYS_PROBE4(tx_desc_tso2_create, unsigned int, etp->et_index,
+ uint16_t, ipv4_id, uint32_t, tcp_seq,
+ uint16_t, tcp_mss);
+
+ EFSYS_ASSERT(count >= EFX_TX_FATSOV2_OPT_NDESCS);
+
+ EFX_POPULATE_QWORD_5(edp[0].ed_eq,
+ ESF_DZ_TX_DESC_IS_OPT, 1,
+ ESF_DZ_TX_OPTION_TYPE,
+ ESE_DZ_TX_OPTION_DESC_TSO,
+ ESF_DZ_TX_TSO_OPTION_TYPE,
+ ESE_DZ_TX_TSO_OPTION_DESC_FATSO2A,
+ ESF_DZ_TX_TSO_IP_ID, ipv4_id,
+ ESF_DZ_TX_TSO_TCP_SEQNO, tcp_seq);
+ EFX_POPULATE_QWORD_4(edp[1].ed_eq,
+ ESF_DZ_TX_DESC_IS_OPT, 1,
+ ESF_DZ_TX_OPTION_TYPE,
+ ESE_DZ_TX_OPTION_DESC_TSO,
+ ESF_DZ_TX_TSO_OPTION_TYPE,
+ ESE_DZ_TX_TSO_OPTION_DESC_FATSO2B,
+ ESF_DZ_TX_TSO_TCP_MSS, tcp_mss);
+}
+
+ void
ef10_tx_qdesc_vlantci_create(
__in efx_txq_t *etp,
__in uint16_t tci,
diff --git a/sys/dev/sfxge/common/hunt_vpd.c b/sys/dev/sfxge/common/hunt_vpd.c
index 58e9a66..41b4b83 100644
--- a/sys/dev/sfxge/common/hunt_vpd.c
+++ b/sys/dev/sfxge/common/hunt_vpd.c
@@ -48,13 +48,20 @@ ef10_vpd_init(
caddr_t svpd;
size_t svpd_size;
uint32_t pci_pf;
+ uint32_t tag;
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD);
- pci_pf = enp->en_nic_cfg.enc_pf;
+ if (enp->en_nic_cfg.enc_vpd_is_global) {
+ tag = TLV_TAG_GLOBAL_STATIC_VPD;
+ } else {
+ pci_pf = enp->en_nic_cfg.enc_pf;
+ tag = TLV_TAG_PF_STATIC_VPD(pci_pf);
+ }
+
/*
* The VPD interface exposes VPD resources from the combined static and
* dynamic VPD storage. As the static VPD configuration should *never*
@@ -64,8 +71,7 @@ ef10_vpd_init(
svpd_size = 0;
rc = ef10_nvram_partn_read_tlv(enp,
NVRAM_PARTITION_TYPE_STATIC_CONFIG,
- TLV_TAG_PF_STATIC_VPD(pci_pf),
- &svpd, &svpd_size);
+ tag, &svpd, &svpd_size);
if (rc != 0) {
if (rc == EACCES) {
/* Unpriviledged functions cannot access VPD */
@@ -132,17 +138,22 @@ ef10_vpd_read(
caddr_t dvpd;
size_t dvpd_size;
uint32_t pci_pf;
+ uint32_t tag;
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD);
- pci_pf = enp->en_nic_cfg.enc_pf;
+ if (enp->en_nic_cfg.enc_vpd_is_global) {
+ tag = TLV_TAG_GLOBAL_DYNAMIC_VPD;
+ } else {
+ pci_pf = enp->en_nic_cfg.enc_pf;
+ tag = TLV_TAG_PF_DYNAMIC_VPD(pci_pf);
+ }
if ((rc = ef10_nvram_partn_read_tlv(enp,
NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG,
- TLV_TAG_PF_DYNAMIC_VPD(pci_pf),
- &dvpd, &dvpd_size)) != 0)
+ tag, &dvpd, &dvpd_size)) != 0)
goto fail1;
if (dvpd_size > size) {
@@ -210,6 +221,13 @@ ef10_vpd_verify(
if (dcont == 0)
break;
+ /*
+ * Skip the RV keyword. It should be present in both the static
+ * and dynamic cfg sectors.
+ */
+ if (dtag == EFX_VPD_RO && dkey == EFX_VPD_KEYWORD('R', 'V'))
+ continue;
+
scont = 0;
_NOTE(CONSTANTCONDITION)
while (1) {
@@ -389,12 +407,18 @@ ef10_vpd_write(
{
size_t vpd_length;
uint32_t pci_pf;
+ uint32_t tag;
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD);
- pci_pf = enp->en_nic_cfg.enc_pf;
+ if (enp->en_nic_cfg.enc_vpd_is_global) {
+ tag = TLV_TAG_GLOBAL_DYNAMIC_VPD;
+ } else {
+ pci_pf = enp->en_nic_cfg.enc_pf;
+ tag = TLV_TAG_PF_DYNAMIC_VPD(pci_pf);
+ }
/* Determine total length of new dynamic VPD */
if ((rc = efx_vpd_hunk_length(data, size, &vpd_length)) != 0)
@@ -403,8 +427,7 @@ ef10_vpd_write(
/* Store new dynamic VPD in all segments in DYNAMIC_CONFIG partition */
if ((rc = ef10_nvram_partn_write_segment_tlv(enp,
NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG,
- TLV_TAG_PF_DYNAMIC_VPD(pci_pf),
- data, vpd_length, B_TRUE)) != 0) {
+ tag, data, vpd_length, B_TRUE)) != 0) {
goto fail2;
}
diff --git a/sys/dev/sfxge/common/medford_impl.h b/sys/dev/sfxge/common/medford_impl.h
index 11084dc..59ea35f 100644
--- a/sys/dev/sfxge/common/medford_impl.h
+++ b/sys/dev/sfxge/common/medford_impl.h
@@ -37,7 +37,29 @@
extern "C" {
#endif
+/* Alignment requirement for value written to RX WPTR:
+ * the WPTR must be aligned to an 8 descriptor boundary
+ *
+ * FIXME: Is this the same on Medford as Huntington?
+ */
+#define MEDFORD_RX_WPTR_ALIGN 8
+
+
+
+#ifndef ER_EZ_TX_PIOBUF_SIZE
+#define ER_EZ_TX_PIOBUF_SIZE 4096
+#endif
+
+
#define MEDFORD_PIOBUF_NBUFS (16)
+#define MEDFORD_PIOBUF_SIZE (ER_EZ_TX_PIOBUF_SIZE)
+
+#define MEDFORD_MIN_PIO_ALLOC_SIZE (MEDFORD_PIOBUF_SIZE / 32)
+
+
+extern __checkReturn efx_rc_t
+medford_board_cfg(
+ __in efx_nic_t *enp);
#ifdef __cplusplus
diff --git a/sys/dev/sfxge/common/medford_nic.c b/sys/dev/sfxge/common/medford_nic.c
index 68c8184..7c176b5 100644
--- a/sys/dev/sfxge/common/medford_nic.c
+++ b/sys/dev/sfxge/common/medford_nic.c
@@ -39,7 +39,273 @@ __FBSDID("$FreeBSD$");
#include "ef10_tlv_layout.h"
+static __checkReturn efx_rc_t
+efx_mcdi_get_rxdp_config(
+ __in efx_nic_t *enp,
+ __out uint32_t *end_paddingp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_RXDP_CONFIG_IN_LEN,
+ MC_CMD_GET_RXDP_CONFIG_OUT_LEN)];
+ uint32_t end_padding;
+ efx_rc_t rc;
+ memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_RXDP_CONFIG;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_RXDP_CONFIG_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_RXDP_CONFIG_OUT_LEN;
+ efx_mcdi_execute(enp, &req);
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (MCDI_OUT_DWORD_FIELD(req, GET_RXDP_CONFIG_OUT_DATA,
+ GET_RXDP_CONFIG_OUT_PAD_HOST_DMA) == 0) {
+ /* RX DMA end padding is disabled */
+ end_padding = 0;
+ } else {
+ switch(MCDI_OUT_DWORD_FIELD(req, GET_RXDP_CONFIG_OUT_DATA,
+ GET_RXDP_CONFIG_OUT_PAD_HOST_LEN)) {
+ case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_64:
+ end_padding = 64;
+ break;
+ case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_128:
+ end_padding = 128;
+ break;
+ case MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_256:
+ end_padding = 256;
+ break;
+ default:
+ rc = ENOTSUP;
+ goto fail2;
+ }
+ }
+
+ *end_paddingp = end_padding;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+medford_board_cfg(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint8_t mac_addr[6] = { 0 };
+ uint32_t board_type = 0;
+ ef10_link_state_t els;
+ efx_port_t *epp = &(enp->en_port);
+ uint32_t port;
+ uint32_t pf;
+ uint32_t vf;
+ uint32_t mask;
+ uint32_t flags;
+ uint32_t sysclk;
+ uint32_t base, nvec;
+ uint32_t end_padding;
+ efx_rc_t rc;
+
+ /*
+ * FIXME: Likely to be incomplete and incorrect.
+ * Parts of this should be shared with Huntington.
+ */
+
+ if ((rc = efx_mcdi_get_port_assignment(enp, &port)) != 0)
+ goto fail1;
+
+ /*
+ * NOTE: The MCDI protocol numbers ports from zero.
+ * The common code MCDI interface numbers ports from one.
+ */
+ emip->emi_port = port + 1;
+
+ if ((rc = ef10_external_port_mapping(enp, port,
+ &encp->enc_external_port)) != 0)
+ goto fail2;
+
+ /*
+ * Get PCIe function number from firmware (used for
+ * per-function privilege and dynamic config info).
+ * - PCIe PF: pf = PF number, vf = 0xffff.
+ * - PCIe VF: pf = parent PF, vf = VF number.
+ */
+ if ((rc = efx_mcdi_get_function_info(enp, &pf, &vf)) != 0)
+ goto fail3;
+
+ encp->enc_pf = pf;
+ encp->enc_vf = vf;
+
+ /* MAC address for this function */
+ if (EFX_PCI_FUNCTION_IS_PF(encp)) {
+ rc = efx_mcdi_get_mac_address_pf(enp, mac_addr);
+ if ((rc == 0) && (mac_addr[0] & 0x02)) {
+ /*
+ * If the static config does not include a global MAC
+ * address pool then the board may return a locally
+ * administered MAC address (this should only happen on
+ * incorrectly programmed boards).
+ */
+ rc = EINVAL;
+ }
+ } else {
+ rc = efx_mcdi_get_mac_address_vf(enp, mac_addr);
+ }
+ if (rc != 0)
+ goto fail4;
+
+ EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
+
+ /* Board configuration */
+ rc = efx_mcdi_get_board_cfg(enp, &board_type, NULL, NULL);
+ if (rc != 0) {
+ /* Unprivileged functions may not be able to read board cfg */
+ if (rc == EACCES)
+ board_type = 0;
+ else
+ goto fail5;
+ }
+
+ encp->enc_board_type = board_type;
+ encp->enc_clk_mult = 1; /* not used for Medford */
+
+ /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
+ if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
+ goto fail6;
+
+ /* Obtain the default PHY advertised capabilities */
+ if ((rc = ef10_phy_get_link(enp, &els)) != 0)
+ goto fail7;
+ epp->ep_default_adv_cap_mask = els.els_adv_cap_mask;
+ epp->ep_adv_cap_mask = els.els_adv_cap_mask;
+
+ if (EFX_PCI_FUNCTION_IS_VF(encp)) {
+ /*
+ * Interrupt testing does not work for VFs. See bug50084.
+ * FIXME: Does this still apply to Medford?
+ */
+ encp->enc_bug41750_workaround = B_TRUE;
+ }
+
+ /* Chained multicast is always enabled on Medford */
+ encp->enc_bug26807_workaround = B_TRUE;
+
+ /* Get sysclk frequency (in MHz). */
+ if ((rc = efx_mcdi_get_clock(enp, &sysclk)) != 0)
+ goto fail8;
+
+ /*
+ * The timer quantum is 1536 sysclk cycles, documented for the
+ * EV_TMR_VAL field of EV_TIMER_TBL. Scale for MHz and ns units.
+ */
+ encp->enc_evq_timer_quantum_ns = 1536000UL / sysclk; /* 1536 cycles */
+ encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
+ FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
+
+ /* Check capabilities of running datapath firmware */
+ if ((rc = ef10_get_datapath_caps(enp)) != 0)
+ goto fail9;
+
+ /* Alignment for receive packet DMA buffers */
+ encp->enc_rx_buf_align_start = 1;
+
+ /* Get the RX DMA end padding alignment configuration */
+ if ((rc = efx_mcdi_get_rxdp_config(enp, &end_padding)) != 0)
+ goto fail10;
+ encp->enc_rx_buf_align_end = end_padding;
+
+ /* Alignment for WPTR updates */
+ encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN;
+
+ /*
+ * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
+ * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
+ * resources (allocated to this PCIe function), which is zero until
+ * after we have allocated VIs.
+ */
+ encp->enc_evq_limit = 1024;
+ encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
+ encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
+
+ encp->enc_buftbl_limit = 0xFFFFFFFF;
+
+ encp->enc_piobuf_limit = MEDFORD_PIOBUF_NBUFS;
+ encp->enc_piobuf_size = MEDFORD_PIOBUF_SIZE;
+ encp->enc_piobuf_min_alloc_size = MEDFORD_MIN_PIO_ALLOC_SIZE;
+
+ /*
+ * Get the current privilege mask. Note that this may be modified
+ * dynamically, so this value is informational only. DO NOT use
+ * the privilege mask to check for sufficient privileges, as that
+ * can result in time-of-check/time-of-use bugs.
+ */
+ if ((rc = ef10_get_privilege_mask(enp, &mask)) != 0)
+ goto fail11;
+ encp->enc_privilege_mask = mask;
+
+ /* Get interrupt vector limits */
+ if ((rc = efx_mcdi_get_vector_cfg(enp, &base, &nvec, NULL)) != 0) {
+ if (EFX_PCI_FUNCTION_IS_PF(encp))
+ goto fail12;
+
+ /* Ignore error (cannot query vector limits from a VF). */
+ base = 0;
+ nvec = 1024;
+ }
+ encp->enc_intr_vec_base = base;
+ encp->enc_intr_limit = nvec;
+
+ /*
+ * Maximum number of bytes into the frame the TCP header can start for
+ * firmware assisted TSO to work.
+ */
+ encp->enc_tx_tso_tcp_header_offset_limit = EF10_TCP_HEADER_OFFSET_LIMIT;
+
+ /*
+ * Medford stores a single global copy of VPD, not per-PF as on
+ * Huntington.
+ */
+ encp->enc_vpd_is_global = B_TRUE;
+
+ return (0);
+
+fail12:
+ EFSYS_PROBE(fail12);
+fail11:
+ EFSYS_PROBE(fail11);
+fail10:
+ EFSYS_PROBE(fail10);
+fail9:
+ EFSYS_PROBE(fail9);
+fail8:
+ EFSYS_PROBE(fail8);
+fail7:
+ EFSYS_PROBE(fail7);
+fail6:
+ EFSYS_PROBE(fail6);
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
#endif /* EFSYS_OPT_MEDFORD */
diff --git a/sys/dev/sfxge/common/siena_flash.h b/sys/dev/sfxge/common/siena_flash.h
index 48ddfac..143a14e 100644
--- a/sys/dev/sfxge/common/siena_flash.h
+++ b/sys/dev/sfxge/common/siena_flash.h
@@ -115,14 +115,14 @@ typedef struct siena_mc_boot_hdr_s { /* GENERATED BY scripts/genfwdef */
efx_word_t checksum; /* of whole header area + firmware image */
efx_word_t firmware_version_d;
efx_byte_t mcfw_subtype;
- efx_byte_t reserved_a[1]; /* (set to 0) */
+ efx_byte_t generation; /* Valid for medford, SBZ for earlier chips */
efx_dword_t firmware_text_offset; /* offset to firmware .text */
efx_dword_t firmware_text_size; /* length of firmware .text, in bytes */
efx_dword_t firmware_data_offset; /* offset to firmware .data */
efx_dword_t firmware_data_size; /* length of firmware .data, in bytes */
efx_byte_t spi_rate; /* SPI rate for reading image, 0 is BootROM default */
efx_byte_t spi_phase_adj; /* SPI SDO/SCL phase adjustment, 0 is default (no adj) */
- efx_word_t reserved_b[1]; /* (set to 0) */
+ efx_word_t xpm_sector; /* The sector that contains the key, or 0xffff if unsigned (medford) SBZ (earlier) */
efx_dword_t reserved_c[7]; /* (set to 0) */
} siena_mc_boot_hdr_t;
diff --git a/sys/dev/sfxge/common/siena_impl.h b/sys/dev/sfxge/common/siena_impl.h
index 639ac6b..4c80cd6 100644
--- a/sys/dev/sfxge/common/siena_impl.h
+++ b/sys/dev/sfxge/common/siena_impl.h
@@ -114,12 +114,12 @@ siena_mcdi_init(
__in const efx_mcdi_transport_t *mtp);
extern void
-siena_mcdi_request_copyin(
+siena_mcdi_send_request(
__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);
+ __in void *hdrp,
+ __in size_t hdr_len,
+ __in void *sdup,
+ __in size_t sdu_len);
extern __checkReturn boolean_t
siena_mcdi_poll_response(
@@ -132,11 +132,6 @@ siena_mcdi_read_response(
__in size_t offset,
__in size_t length);
-extern void
-siena_mcdi_request_copyout(
- __in efx_nic_t *enp,
- __in efx_mcdi_req_t *emrp);
-
extern efx_rc_t
siena_mcdi_poll_reboot(
__in efx_nic_t *enp);
@@ -156,39 +151,10 @@ siena_mcdi_feature_supported(
#if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
extern __checkReturn efx_rc_t
-siena_nvram_partn_size(
- __in efx_nic_t *enp,
- __in uint32_t partn,
- __out size_t *sizep);
-
-extern __checkReturn efx_rc_t
siena_nvram_partn_lock(
__in efx_nic_t *enp,
__in uint32_t partn);
-extern __checkReturn efx_rc_t
-siena_nvram_partn_read(
- __in efx_nic_t *enp,
- __in uint32_t partn,
- __in unsigned int offset,
- __out_bcount(size) caddr_t data,
- __in size_t size);
-
-extern __checkReturn efx_rc_t
-siena_nvram_partn_erase(
- __in efx_nic_t *enp,
- __in uint32_t partn,
- __in unsigned int offset,
- __in size_t size);
-
-extern __checkReturn efx_rc_t
-siena_nvram_partn_write(
- __in efx_nic_t *enp,
- __in uint32_t 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,
@@ -215,67 +181,69 @@ siena_nvram_test(
#endif /* EFSYS_OPT_DIAG */
extern __checkReturn efx_rc_t
-siena_nvram_size(
- __in efx_nic_t *enp,
- __in efx_nvram_type_t type,
- __out size_t *sizep);
-
-extern __checkReturn efx_rc_t
siena_nvram_get_subtype(
__in efx_nic_t *enp,
__in uint32_t partn,
__out uint32_t *subtypep);
extern __checkReturn efx_rc_t
-siena_nvram_get_version(
+siena_nvram_type_to_partn(
__in efx_nic_t *enp,
__in efx_nvram_type_t type,
- __out uint32_t *subtypep,
- __out_ecount(4) uint16_t version[4]);
+ __out uint32_t *partnp);
extern __checkReturn efx_rc_t
-siena_nvram_rw_start(
+siena_nvram_partn_size(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
- __out size_t *pref_chunkp);
+ __in uint32_t partn,
+ __out size_t *sizep);
extern __checkReturn efx_rc_t
-siena_nvram_read_chunk(
+siena_nvram_partn_rw_start(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
+ __in uint32_t partn,
+ __out size_t *chunk_sizep);
+
+extern __checkReturn efx_rc_t
+siena_nvram_partn_read(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
__in unsigned int offset,
__out_bcount(size) caddr_t data,
__in size_t size);
-extern __checkReturn efx_rc_t
-siena_nvram_erase(
+extern __checkReturn efx_rc_t
+siena_nvram_partn_erase(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type);
+ __in uint32_t partn,
+ __in unsigned int offset,
+ __in size_t size);
extern __checkReturn efx_rc_t
-siena_nvram_write_chunk(
+siena_nvram_partn_write(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
+ __in uint32_t partn,
__in unsigned int offset,
- __in_bcount(size) caddr_t data,
+ __out_bcount(size) caddr_t data,
__in size_t size);
extern void
-siena_nvram_rw_finish(
+siena_nvram_partn_rw_finish(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type);
+ __in uint32_t partn);
extern __checkReturn efx_rc_t
-siena_nvram_set_version(
+siena_nvram_partn_get_version(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
- __in_ecount(4) uint16_t version[4]);
+ __in uint32_t partn,
+ __out uint32_t *subtypep,
+ __out_ecount(4) uint16_t version[4]);
extern __checkReturn efx_rc_t
-siena_nvram_type_to_partn(
+siena_nvram_partn_set_version(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
- __out uint32_t *partnp);
+ __in uint32_t partn,
+ __in_ecount(4) uint16_t version[4]);
#endif /* EFSYS_OPT_NVRAM */
diff --git a/sys/dev/sfxge/common/siena_mcdi.c b/sys/dev/sfxge/common/siena_mcdi.c
index f3af2bf6f..4fb2b6c 100644
--- a/sys/dev/sfxge/common/siena_mcdi.c
+++ b/sys/dev/sfxge/common/siena_mcdi.c
@@ -52,7 +52,7 @@ __FBSDID("$FreeBSD$");
: MC_SMEM_P1_STATUS_OFST >> 2)
-static void
+ void
siena_mcdi_send_request(
__in efx_nic_t *enp,
__in void *hdrp,
@@ -89,79 +89,6 @@ siena_mcdi_send_request(
EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, dbr, &dword, B_FALSE);
}
- 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)
-{
-#if EFSYS_OPT_MCDI_LOGGING
- const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
-#endif
- efx_dword_t hdr;
- size_t hdr_len;
- unsigned int xflags;
-
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
- _NOTE(ARGUNUSED(new_epoch))
-
- xflags = 0;
- if (ev_cpl)
- xflags |= MCDI_HEADER_XFLAGS_EVREQ;
-
- /* Construct the header */
- hdr_len = sizeof (hdr);
- EFX_POPULATE_DWORD_6(hdr,
- MCDI_HEADER_CODE, emrp->emr_cmd,
- MCDI_HEADER_RESYNC, 1,
- MCDI_HEADER_DATALEN, emrp->emr_in_length,
- MCDI_HEADER_SEQ, seq,
- MCDI_HEADER_RESPONSE, 0,
- MCDI_HEADER_XFLAGS, xflags);
-
-#if EFSYS_OPT_MCDI_LOGGING
- if (emtp->emt_logger != NULL) {
- emtp->emt_logger(emtp->emt_context, EFX_LOG_MCDI_REQUEST,
- &hdr, sizeof (hdr),
- emrp->emr_in_buf, emrp->emr_in_length);
- }
-#endif /* EFSYS_OPT_MCDI_LOGGING */
-
- siena_mcdi_send_request(enp, &hdr, hdr_len,
- emrp->emr_in_buf, emrp->emr_in_length);
-}
-
- void
-siena_mcdi_request_copyout(
- __in efx_nic_t *enp,
- __in efx_mcdi_req_t *emrp)
-{
-#if EFSYS_OPT_MCDI_LOGGING
- const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
- efx_dword_t hdr;
-#endif
- size_t bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length);
-
- /* Copy payload out if caller supplied buffer */
- if (emrp->emr_out_buf != NULL) {
- siena_mcdi_read_response(enp, emrp->emr_out_buf,
- sizeof (efx_dword_t), bytes);
- }
-
-#if EFSYS_OPT_MCDI_LOGGING
- if (emtp->emt_logger != NULL) {
- siena_mcdi_read_response(enp, &hdr, 0, sizeof (hdr));
-
- emtp->emt_logger(emtp->emt_context,
- EFX_LOG_MCDI_RESPONSE,
- &hdr, sizeof (hdr),
- emrp->emr_out_buf, bytes);
- }
-#endif /* EFSYS_OPT_MCDI_LOGGING */
-}
-
efx_rc_t
siena_mcdi_poll_reboot(
__in efx_nic_t *enp)
diff --git a/sys/dev/sfxge/common/siena_nic.c b/sys/dev/sfxge/common/siena_nic.c
index 70e7b5d..59e1283 100644
--- a/sys/dev/sfxge/common/siena_nic.c
+++ b/sys/dev/sfxge/common/siena_nic.c
@@ -169,6 +169,7 @@ siena_board_cfg(
encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
encp->enc_fw_assisted_tso_enabled = B_FALSE;
+ encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
return (0);
diff --git a/sys/dev/sfxge/common/siena_nvram.c b/sys/dev/sfxge/common/siena_nvram.c
index 8f107b4..9708e0c 100644
--- a/sys/dev/sfxge/common/siena_nvram.c
+++ b/sys/dev/sfxge/common/siena_nvram.c
@@ -99,8 +99,8 @@ siena_nvram_partn_read(
while (size > 0) {
chunk = MIN(size, SIENA_NVRAM_CHUNK);
- if ((rc = efx_mcdi_nvram_read(enp, partn, offset,
- data, chunk)) != 0) {
+ if ((rc = efx_mcdi_nvram_read(enp, partn, offset, data, chunk,
+ MC_CMD_NVRAM_READ_IN_V2_DEFAULT)) != 0) {
goto fail1;
}
@@ -227,6 +227,8 @@ static siena_parttbl_entry_t siena_parttbl[] = {
{MC_CMD_NVRAM_TYPE_FC_FW, 2, EFX_NVRAM_FCFW},
{MC_CMD_NVRAM_TYPE_CPLD, 1, EFX_NVRAM_CPLD},
{MC_CMD_NVRAM_TYPE_CPLD, 2, EFX_NVRAM_CPLD},
+ {MC_CMD_NVRAM_TYPE_LICENSE, 1, EFX_NVRAM_LICENSE},
+ {MC_CMD_NVRAM_TYPE_LICENSE, 2, EFX_NVRAM_LICENSE}
};
__checkReturn efx_rc_t
@@ -291,32 +293,6 @@ fail1:
#endif /* EFSYS_OPT_DIAG */
- __checkReturn efx_rc_t
-siena_nvram_size(
- __in efx_nic_t *enp,
- __in efx_nvram_type_t type,
- __out size_t *sizep)
-{
- uint32_t partn;
- efx_rc_t rc;
-
- if ((rc = siena_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
- if ((rc = siena_nvram_partn_size(enp, partn, sizep)) != 0)
- goto fail2;
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- *sizep = 0;
-
- return (rc);
-}
#define SIENA_DYNAMIC_CFG_SIZE(_nitems) \
(sizeof (siena_mc_dynamic_config_hdr_t) + ((_nitems) * \
@@ -506,29 +482,25 @@ fail1:
}
__checkReturn efx_rc_t
-siena_nvram_get_version(
+siena_nvram_partn_get_version(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
+ __in uint32_t partn,
__out uint32_t *subtypep,
__out_ecount(4) uint16_t version[4])
{
siena_mc_dynamic_config_hdr_t *dcfg;
siena_parttbl_entry_t *entry;
uint32_t dcfg_partn;
- uint32_t partn;
unsigned int i;
efx_rc_t rc;
- if ((rc = siena_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
if ((1 << partn) & ~enp->en_u.siena.enu_partn_mask) {
rc = ENOTSUP;
- goto fail2;
+ goto fail1;
}
if ((rc = siena_nvram_get_subtype(enp, partn, subtypep)) != 0)
- goto fail3;
+ goto fail2;
/*
* Some partitions are accessible from both ports (for instance BOOTROM)
@@ -537,6 +509,7 @@ siena_nvram_get_version(
*/
version[0] = version[1] = version[2] = version[3] = 0;
for (i = 0; i < EFX_ARRAY_SIZE(siena_parttbl); i++) {
+ siena_mc_fw_version_t *verp;
unsigned int nitems;
uint16_t temp[4];
size_t length;
@@ -559,32 +532,27 @@ siena_nvram_get_version(
if ((rc = siena_nvram_get_dynamic_cfg(enp, dcfg_partn,
B_FALSE, &dcfg, &length)) != 0)
- goto fail4;
+ goto fail3;
nitems = EFX_DWORD_FIELD(dcfg->num_fw_version_items,
EFX_DWORD_0);
if (nitems < entry->partn)
goto done;
- temp[0] = EFX_WORD_FIELD(dcfg->fw_version[partn].version_w,
- EFX_WORD_0);
- temp[1] = EFX_WORD_FIELD(dcfg->fw_version[partn].version_x,
- EFX_WORD_0);
- temp[2] = EFX_WORD_FIELD(dcfg->fw_version[partn].version_y,
- EFX_WORD_0);
- temp[3] = EFX_WORD_FIELD(dcfg->fw_version[partn].version_z,
- EFX_WORD_0);
+ verp = &dcfg->fw_version[partn];
+ temp[0] = EFX_WORD_FIELD(verp->version_w, EFX_WORD_0);
+ temp[1] = EFX_WORD_FIELD(verp->version_x, EFX_WORD_0);
+ temp[2] = EFX_WORD_FIELD(verp->version_y, EFX_WORD_0);
+ temp[3] = EFX_WORD_FIELD(verp->version_z, EFX_WORD_0);
if (memcmp(version, temp, sizeof (temp)) < 0)
memcpy(version, temp, sizeof (temp));
- done:
+done:
EFSYS_KMEM_FREE(enp->en_esip, length, dcfg);
}
return (0);
-fail4:
- EFSYS_PROBE(fail4);
fail3:
EFSYS_PROBE(fail3);
fail2:
@@ -596,111 +564,21 @@ fail1:
}
__checkReturn efx_rc_t
-siena_nvram_rw_start(
+siena_nvram_partn_rw_start(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
+ __in uint32_t partn,
__out size_t *chunk_sizep)
{
- uint32_t partn;
efx_rc_t rc;
- if ((rc = siena_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
if ((rc = siena_nvram_partn_lock(enp, partn)) != 0)
- goto fail2;
+ goto fail1;
if (chunk_sizep != NULL)
*chunk_sizep = SIENA_NVRAM_CHUNK;
return (0);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-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)
-{
- uint32_t partn;
- efx_rc_t rc;
-
- if ((rc = siena_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
- if ((rc = siena_nvram_partn_read(enp, partn, offset, data, size)) != 0)
- goto fail2;
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-siena_nvram_erase(
- __in efx_nic_t *enp,
- __in efx_nvram_type_t type)
-{
- size_t size;
- uint32_t partn;
- efx_rc_t rc;
-
- if ((rc = siena_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
- if ((rc = siena_nvram_partn_size(enp, partn, &size)) != 0)
- goto fail2;
-
- if ((rc = siena_nvram_partn_erase(enp, partn, 0, size)) != 0)
- goto fail3;
-
- return (0);
-
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
- __checkReturn efx_rc_t
-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)
-{
- uint32_t partn;
- efx_rc_t rc;
-
- if ((rc = siena_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
- if ((rc = siena_nvram_partn_write(enp, partn, offset, data, size)) != 0)
- goto fail2;
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
@@ -708,27 +586,23 @@ fail1:
}
void
-siena_nvram_rw_finish(
+siena_nvram_partn_rw_finish(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type)
+ __in uint32_t partn)
{
- uint32_t partn;
- efx_rc_t rc;
-
- if ((rc = siena_nvram_type_to_partn(enp, type, &partn)) == 0)
- siena_nvram_partn_unlock(enp, partn);
+ siena_nvram_partn_unlock(enp, partn);
}
__checkReturn efx_rc_t
-siena_nvram_set_version(
+siena_nvram_partn_set_version(
__in efx_nic_t *enp,
- __in efx_nvram_type_t type,
+ __in uint32_t partn,
__in_ecount(4) uint16_t version[4])
{
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
siena_mc_dynamic_config_hdr_t *dcfg = NULL;
siena_mc_fw_version_t *fwverp;
- uint32_t dcfg_partn, partn;
+ uint32_t dcfg_partn;
size_t dcfg_size;
unsigned int hdr_length;
unsigned int vpd_length;
@@ -741,15 +615,12 @@ siena_nvram_set_version(
size_t length;
efx_rc_t rc;
- if ((rc = siena_nvram_type_to_partn(enp, type, &partn)) != 0)
- goto fail1;
-
dcfg_partn = (emip->emi_port == 1)
? MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0
: MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1;
if ((rc = siena_nvram_partn_size(enp, dcfg_partn, &dcfg_size)) != 0)
- goto fail2;
+ goto fail1;
if ((rc = siena_nvram_partn_lock(enp, dcfg_partn)) != 0)
goto fail2;
diff --git a/sys/dev/sfxge/common/siena_vpd.c b/sys/dev/sfxge/common/siena_vpd.c
index 9a07f91..7a7ce67 100644
--- a/sys/dev/sfxge/common/siena_vpd.c
+++ b/sys/dev/sfxge/common/siena_vpd.c
@@ -326,6 +326,13 @@ siena_vpd_verify(
if (dcont == 0)
break;
+ /*
+ * Skip the RV keyword. It should be present in both the static
+ * and dynamic cfg sectors.
+ */
+ if (dtag == EFX_VPD_RO && dkey == EFX_VPD_KEYWORD('R', 'V'))
+ continue;
+
scont = 0;
_NOTE(CONSTANTCONDITION)
while (1) {
diff --git a/sys/dev/sfxge/sfxge.h b/sys/dev/sfxge/sfxge.h
index bea1eba..9cf8f07 100644
--- a/sys/dev/sfxge/sfxge.h
+++ b/sys/dev/sfxge/sfxge.h
@@ -283,7 +283,10 @@ struct sfxge_softc {
unsigned int rxq_count;
unsigned int txq_count;
- int tso_fw_assisted;
+ unsigned int tso_fw_assisted;
+#define SFXGE_FATSOV1 (1 << 0)
+#define SFXGE_FATSOV2 (1 << 1)
+
#if EFSYS_OPT_MCDI_LOGGING
int mcdi_logging;
#endif
diff --git a/sys/dev/sfxge/sfxge_tx.c b/sys/dev/sfxge/sfxge_tx.c
index 780ed26..6ae5a07 100644
--- a/sys/dev/sfxge/sfxge_tx.c
+++ b/sys/dev/sfxge/sfxge_tx.c
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
+#include <sys/limits.h>
#include <net/bpf.h>
#include <net/ethernet.h>
@@ -96,11 +97,11 @@ SYSCTL_INT(_hw_sfxge, OID_AUTO, tx_dpl_put_max, CTLFLAG_RDTUN,
"Maximum number of any packets in deferred packet put-list");
#define SFXGE_PARAM_TSO_FW_ASSISTED SFXGE_PARAM(tso_fw_assisted)
-static int sfxge_tso_fw_assisted = 1;
+static int sfxge_tso_fw_assisted = (SFXGE_FATSOV1 | SFXGE_FATSOV2);
TUNABLE_INT(SFXGE_PARAM_TSO_FW_ASSISTED, &sfxge_tso_fw_assisted);
SYSCTL_INT(_hw_sfxge, OID_AUTO, tso_fw_assisted, CTLFLAG_RDTUN,
&sfxge_tso_fw_assisted, 0,
- "Use FW-assisted TSO if supported by NIC firmware");
+ "Bitmask of FW-assisted TSO allowed to use if supported by NIC firmware");
static const struct {
@@ -850,6 +851,8 @@ struct sfxge_tso_state {
unsigned out_len; /* Remaining length in current segment */
unsigned seqnum; /* Current sequence number */
unsigned packet_space; /* Remaining space in current packet */
+ unsigned segs_space; /* Remaining number of DMA segments
+ for the packet (FATSOv2 only) */
/* Input position */
uint64_t dma_addr; /* DMA address of current position */
@@ -952,7 +955,7 @@ static void tso_start(struct sfxge_txq *txq, struct sfxge_tso_state *tso,
struct tcphdr th_copy;
#endif
- tso->fw_assisted = txq->sc->tso_fw_assisted;
+ tso->fw_assisted = txq->tso_fw_assisted;
tso->mbuf = mbuf;
/* Find network protocol and header */
@@ -1059,6 +1062,8 @@ static void tso_fill_packet_with_fragment(struct sfxge_txq *txq,
{
efx_desc_t *desc;
int n;
+ uint64_t dma_addr = tso->dma_addr;
+ boolean_t eop;
if (tso->in_len == 0 || tso->packet_space == 0)
return;
@@ -1066,20 +1071,38 @@ static void tso_fill_packet_with_fragment(struct sfxge_txq *txq,
KASSERT(tso->in_len > 0, ("TSO input length went negative"));
KASSERT(tso->packet_space > 0, ("TSO packet space went negative"));
- n = min(tso->in_len, tso->packet_space);
+ if (tso->fw_assisted & SFXGE_FATSOV2) {
+ n = tso->in_len;
+ tso->out_len -= n;
+ tso->seqnum += n;
+ tso->in_len = 0;
+ if (n < tso->packet_space) {
+ tso->packet_space -= n;
+ tso->segs_space--;
+ } else {
+ tso->packet_space = tso->seg_size -
+ (n - tso->packet_space) % tso->seg_size;
+ tso->segs_space =
+ EFX_TX_FATSOV2_DMA_SEGS_PER_PKT_MAX - 1 -
+ (tso->packet_space != tso->seg_size);
+ }
+ } else {
+ n = min(tso->in_len, tso->packet_space);
+ tso->packet_space -= n;
+ tso->out_len -= n;
+ tso->dma_addr += n;
+ tso->in_len -= n;
+ }
- tso->packet_space -= n;
- tso->out_len -= n;
- tso->in_len -= n;
+ /*
+ * It is OK to use binary OR below to avoid extra branching
+ * since all conditions may always be checked.
+ */
+ eop = (tso->out_len == 0) | (tso->packet_space == 0) |
+ (tso->segs_space == 0);
desc = &txq->pend_desc[txq->n_pend_desc++];
- efx_tx_qdesc_dma_create(txq->common,
- tso->dma_addr,
- n,
- tso->out_len == 0 || tso->packet_space == 0,
- desc);
-
- tso->dma_addr += n;
+ efx_tx_qdesc_dma_create(txq->common, dma_addr, n, eop, desc);
}
/* Callback from bus_dmamap_load() for long TSO headers. */
@@ -1112,28 +1135,47 @@ static int tso_start_new_packet(struct sfxge_txq *txq,
int rc;
if (tso->fw_assisted) {
- uint8_t tcp_flags = tso->tcp_flags;
-
- if (tso->out_len > tso->seg_size)
- tcp_flags &= ~(TH_FIN | TH_PUSH);
-
- /* TSO option descriptor */
- desc = &txq->pend_desc[txq->n_pend_desc++];
- efx_tx_qdesc_tso_create(txq->common,
- tso->packet_id,
- tso->seqnum,
- tcp_flags,
- desc++);
- KASSERT(txq->stmp[id].flags == 0, ("stmp flags are not 0"));
- id = (id + 1) & txq->ptr_mask;
+ if (tso->fw_assisted & SFXGE_FATSOV2) {
+ /* Add 2 FATSOv2 option descriptors */
+ desc = &txq->pend_desc[txq->n_pend_desc];
+ efx_tx_qdesc_tso2_create(txq->common,
+ tso->packet_id,
+ tso->seqnum,
+ tso->seg_size,
+ desc,
+ EFX_TX_FATSOV2_OPT_NDESCS);
+ desc += EFX_TX_FATSOV2_OPT_NDESCS;
+ txq->n_pend_desc += EFX_TX_FATSOV2_OPT_NDESCS;
+ KASSERT(txq->stmp[id].flags == 0, ("stmp flags are not 0"));
+ id = (id + EFX_TX_FATSOV2_OPT_NDESCS) & txq->ptr_mask;
+
+ tso->segs_space =
+ EFX_TX_FATSOV2_DMA_SEGS_PER_PKT_MAX - 1;
+ } else {
+ uint8_t tcp_flags = tso->tcp_flags;
+
+ if (tso->out_len > tso->seg_size)
+ tcp_flags &= ~(TH_FIN | TH_PUSH);
+
+ /* Add FATSOv1 option descriptor */
+ desc = &txq->pend_desc[txq->n_pend_desc++];
+ efx_tx_qdesc_tso_create(txq->common,
+ tso->packet_id,
+ tso->seqnum,
+ tcp_flags,
+ desc++);
+ KASSERT(txq->stmp[id].flags == 0, ("stmp flags are not 0"));
+ id = (id + 1) & txq->ptr_mask;
+
+ tso->seqnum += tso->seg_size;
+ tso->segs_space = UINT_MAX;
+ }
/* Header DMA descriptor */
*desc = tso->header_desc;
txq->n_pend_desc++;
KASSERT(txq->stmp[id].flags == 0, ("stmp flags are not 0"));
id = (id + 1) & txq->ptr_mask;
-
- tso->seqnum += tso->seg_size;
} else {
/* Allocate a DMA-mapped header buffer. */
if (__predict_true(tso->header_len <= TSOH_STD_SIZE)) {
@@ -1215,6 +1257,8 @@ static int tso_start_new_packet(struct sfxge_txq *txq,
0,
desc);
id = (id + 1) & txq->ptr_mask;
+
+ tso->segs_space = UINT_MAX;
}
tso->packet_space = tso->seg_size;
txq->tso_packets++;
@@ -1264,15 +1308,19 @@ sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf,
}
/* End of packet? */
- if (tso.packet_space == 0) {
+ if ((tso.packet_space == 0) | (tso.segs_space == 0)) {
+ unsigned int n_fatso_opt_desc =
+ (tso.fw_assisted & SFXGE_FATSOV2) ?
+ EFX_TX_FATSOV2_OPT_NDESCS :
+ (tso.fw_assisted & SFXGE_FATSOV1) ? 1 : 0;
+
/* If the queue is now full due to tiny MSS,
* or we can't create another header, discard
* the remainder of the input mbuf but do not
* roll back the work we have done.
*/
- if (txq->n_pend_desc + tso.fw_assisted +
- 1 /* header */ + n_dma_seg >
- txq->max_pkt_desc) {
+ if (txq->n_pend_desc + n_fatso_opt_desc +
+ 1 /* header */ + n_dma_seg > txq->max_pkt_desc) {
txq->tso_pdrop_too_many++;
break;
}
@@ -1407,12 +1455,67 @@ sfxge_tx_qstop(struct sfxge_softc *sc, unsigned int index)
SFXGE_TXQ_UNLOCK(txq);
}
+/*
+ * Estimate maximum number of Tx descriptors required for TSO packet.
+ * With minimum MSS and maximum mbuf length we might need more (even
+ * than a ring-ful of descriptors), but this should not happen in
+ * practice except due to deliberate attack. In that case we will
+ * truncate the output at a packet boundary.
+ */
+static unsigned int
+sfxge_tx_max_pkt_desc(const struct sfxge_softc *sc, enum sfxge_txq_type type,
+ unsigned int tso_fw_assisted)
+{
+ /* One descriptor for every input fragment */
+ unsigned int max_descs = SFXGE_TX_MAPPING_MAX_SEG;
+ unsigned int sw_tso_max_descs;
+ unsigned int fa_tso_v1_max_descs = 0;
+ unsigned int fa_tso_v2_max_descs = 0;
+
+ /* VLAN tagging Tx option descriptor may be required */
+ if (efx_nic_cfg_get(sc->enp)->enc_hw_tx_insert_vlan_enabled)
+ max_descs++;
+
+ if (type == SFXGE_TXQ_IP_TCP_UDP_CKSUM) {
+ /*
+ * Plus header and payload descriptor for each output segment.
+ * Minus one since header fragment is already counted.
+ * Even if FATSO is used, we should be ready to fallback
+ * to do it in the driver.
+ */
+ sw_tso_max_descs = SFXGE_TSO_MAX_SEGS * 2 - 1;
+
+ /* FW assisted TSOv1 requires one more descriptor per segment
+ * in comparison to SW TSO */
+ if (tso_fw_assisted & SFXGE_FATSOV1)
+ fa_tso_v1_max_descs =
+ sw_tso_max_descs + SFXGE_TSO_MAX_SEGS;
+
+ /* FW assisted TSOv2 requires 3 (2 FATSO plus header) extra
+ * descriptors per superframe limited by number of DMA fetches
+ * per packet. The first packet header is already counted.
+ */
+ if (tso_fw_assisted & SFXGE_FATSOV2) {
+ fa_tso_v2_max_descs =
+ howmany(SFXGE_TX_MAPPING_MAX_SEG,
+ EFX_TX_FATSOV2_DMA_SEGS_PER_PKT_MAX - 1) *
+ (EFX_TX_FATSOV2_OPT_NDESCS + 1) - 1;
+ }
+
+ max_descs += MAX(sw_tso_max_descs,
+ MAX(fa_tso_v1_max_descs, fa_tso_v2_max_descs));
+ }
+
+ return (max_descs);
+}
+
static int
sfxge_tx_qstart(struct sfxge_softc *sc, unsigned int index)
{
struct sfxge_txq *txq;
efsys_mem_t *esmp;
uint16_t flags;
+ unsigned int tso_fw_assisted;
struct sfxge_evq *evq;
unsigned int desc_index;
int rc;
@@ -1434,6 +1537,7 @@ sfxge_tx_qstart(struct sfxge_softc *sc, unsigned int index)
return (rc);
/* Determine the kind of queue we are creating. */
+ tso_fw_assisted = 0;
switch (txq->type) {
case SFXGE_TXQ_NON_CKSUM:
flags = 0;
@@ -1443,6 +1547,9 @@ sfxge_tx_qstart(struct sfxge_softc *sc, unsigned int index)
break;
case SFXGE_TXQ_IP_TCP_UDP_CKSUM:
flags = EFX_TXQ_CKSUM_IPV4 | EFX_TXQ_CKSUM_TCPUDP;
+ tso_fw_assisted = sc->tso_fw_assisted;
+ if (tso_fw_assisted & SFXGE_FATSOV2)
+ flags |= EFX_TXQ_FATSOV2;
break;
default:
KASSERT(0, ("Impossible TX queue"));
@@ -1453,8 +1560,19 @@ sfxge_tx_qstart(struct sfxge_softc *sc, unsigned int index)
/* Create the common code transmit queue. */
if ((rc = efx_tx_qcreate(sc->enp, index, txq->type, esmp,
sc->txq_entries, txq->buf_base_id, flags, evq->common,
- &txq->common, &desc_index)) != 0)
- goto fail;
+ &txq->common, &desc_index)) != 0) {
+ /* Retry if no FATSOv2 resources, otherwise fail */
+ if ((rc != ENOSPC) || (~flags & EFX_TXQ_FATSOV2))
+ goto fail;
+
+ /* Looks like all FATSOv2 contexts are used */
+ flags &= ~EFX_TXQ_FATSOV2;
+ tso_fw_assisted &= ~SFXGE_FATSOV2;
+ if ((rc = efx_tx_qcreate(sc->enp, index, txq->type, esmp,
+ sc->txq_entries, txq->buf_base_id, flags, evq->common,
+ &txq->common, &desc_index)) != 0)
+ goto fail;
+ }
/* Initialise queue descriptor indexes */
txq->added = txq->pending = txq->completed = txq->reaped = desc_index;
@@ -1466,6 +1584,10 @@ sfxge_tx_qstart(struct sfxge_softc *sc, unsigned int index)
txq->init_state = SFXGE_TXQ_STARTED;
txq->flush_state = SFXGE_FLUSH_REQUIRED;
+ txq->tso_fw_assisted = tso_fw_assisted;
+
+ txq->max_pkt_desc = sfxge_tx_max_pkt_desc(sc, txq->type,
+ tso_fw_assisted);
SFXGE_TXQ_UNLOCK(txq);
@@ -1574,38 +1696,6 @@ sfxge_tx_qfini(struct sfxge_softc *sc, unsigned int index)
free(txq, M_SFXGE);
}
-/*
- * Estimate maximum number of Tx descriptors required for TSO packet.
- * With minimum MSS and maximum mbuf length we might need more (even
- * than a ring-ful of descriptors), but this should not happen in
- * practice except due to deliberate attack. In that case we will
- * truncate the output at a packet boundary.
- */
-static unsigned int
-sfxge_tx_max_pkt_desc(const struct sfxge_softc *sc, enum sfxge_txq_type type)
-{
- /* One descriptor for every input fragment */
- unsigned int max_descs = SFXGE_TX_MAPPING_MAX_SEG;
-
- /* VLAN tagging Tx option descriptor may be required */
- if (efx_nic_cfg_get(sc->enp)->enc_hw_tx_insert_vlan_enabled)
- max_descs++;
-
- if (type == SFXGE_TXQ_IP_TCP_UDP_CKSUM) {
- /*
- * Plus header and payload descriptor for each output segment.
- * Minus one since header fragment is already counted.
- */
- max_descs += SFXGE_TSO_MAX_SEGS * 2 - 1;
-
- /* FW assisted TSO requires one more descriptor per segment */
- if (sc->tso_fw_assisted)
- max_descs += SFXGE_TSO_MAX_SEGS;
- }
-
- return (max_descs);
-}
-
static int
sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index,
enum sfxge_txq_type type, unsigned int evq_index)
@@ -1735,8 +1825,6 @@ sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index,
txq->init_state = SFXGE_TXQ_INITIALIZED;
txq->hw_vlan_tci = 0;
- txq->max_pkt_desc = sfxge_tx_max_pkt_desc(sc, type);
-
return (0);
fail_txq_stat_init:
@@ -1852,10 +1940,12 @@ sfxge_tx_init(struct sfxge_softc *sc)
sc->txq_count = SFXGE_TXQ_NTYPES - 1 + sc->intr.n_alloc;
sc->tso_fw_assisted = sfxge_tso_fw_assisted;
- if (sc->tso_fw_assisted)
- sc->tso_fw_assisted =
- (encp->enc_features & EFX_FEATURE_FW_ASSISTED_TSO) &&
- (encp->enc_fw_assisted_tso_enabled);
+ if ((~encp->enc_features & EFX_FEATURE_FW_ASSISTED_TSO) ||
+ (!encp->enc_fw_assisted_tso_enabled))
+ sc->tso_fw_assisted &= ~SFXGE_FATSOV1;
+ if ((~encp->enc_features & EFX_FEATURE_FW_ASSISTED_TSO_V2) ||
+ (!encp->enc_fw_assisted_tso_v2_enabled))
+ sc->tso_fw_assisted &= ~SFXGE_FATSOV2;
sc->txqs_node = SYSCTL_ADD_NODE(
device_get_sysctl_ctx(sc->dev),
diff --git a/sys/dev/sfxge/sfxge_tx.h b/sys/dev/sfxge/sfxge_tx.h
index 816856a..ce5d3c4 100644
--- a/sys/dev/sfxge/sfxge_tx.h
+++ b/sys/dev/sfxge/sfxge_tx.h
@@ -170,6 +170,7 @@ struct sfxge_txq {
struct sfxge_softc *sc;
enum sfxge_txq_state init_state;
enum sfxge_flush_state flush_state;
+ unsigned int tso_fw_assisted;
enum sfxge_txq_type type;
unsigned int txq_index;
unsigned int evq_index;
diff --git a/sys/dev/sfxge/sfxge_version.h b/sys/dev/sfxge/sfxge_version.h
index 9d93e79..dbc23ba 100644
--- a/sys/dev/sfxge/sfxge_version.h
+++ b/sys/dev/sfxge/sfxge_version.h
@@ -36,6 +36,6 @@
#ifndef _SFXGE_VERSION_H
#define _SFXGE_VERSION_H
-#define SFXGE_VERSION_STRING "v4.5.3.1002"
+#define SFXGE_VERSION_STRING "v4.8.0.1019"
#endif /* _SFXGE_DRIVER_VERSION_H */
OpenPOWER on IntegriCloud