aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
authorLuca Boccassi <luca.boccassi@gmail.com>2018-11-01 11:59:50 +0000
committerLuca Boccassi <luca.boccassi@gmail.com>2018-11-01 12:00:19 +0000
commit8d01b9cd70a67cdafd5b965a70420c3bd7fb3f82 (patch)
tree208e3bc33c220854d89d010e3abf720a2e62e546 /drivers/net/sfc
parentb63264c8342e6a1b6971c79550d2af2024b6a4de (diff)
New upstream version 18.11-rc1upstream/18.11-rc1
Change-Id: Iaa71986dd6332e878d8f4bf493101b2bbc6313bb Signed-off-by: Luca Boccassi <luca.boccassi@gmail.com>
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/base/ef10_ev.c38
-rw-r--r--drivers/net/sfc/base/ef10_filter.c64
-rw-r--r--drivers/net/sfc/base/ef10_image.c5
-rw-r--r--drivers/net/sfc/base/ef10_impl.h68
-rw-r--r--drivers/net/sfc/base/ef10_intr.c5
-rw-r--r--drivers/net/sfc/base/ef10_mac.c30
-rw-r--r--drivers/net/sfc/base/ef10_nic.c277
-rw-r--r--drivers/net/sfc/base/ef10_nvram.c161
-rw-r--r--drivers/net/sfc/base/ef10_phy.c105
-rw-r--r--drivers/net/sfc/base/ef10_rx.c89
-rw-r--r--drivers/net/sfc/base/ef10_signed_image_layout.h8
-rw-r--r--drivers/net/sfc/base/ef10_tx.c38
-rw-r--r--drivers/net/sfc/base/efx.h353
-rw-r--r--drivers/net/sfc/base/efx_annote.h103
-rw-r--r--drivers/net/sfc/base/efx_bootcfg.c641
-rw-r--r--drivers/net/sfc/base/efx_filter.c90
-rw-r--r--drivers/net/sfc/base/efx_impl.h10
-rw-r--r--drivers/net/sfc/base/efx_lic.c91
-rw-r--r--drivers/net/sfc/base/efx_mcdi.c168
-rw-r--r--drivers/net/sfc/base/efx_mcdi.h19
-rw-r--r--drivers/net/sfc/base/efx_mon.c745
-rw-r--r--drivers/net/sfc/base/efx_nic.c54
-rw-r--r--drivers/net/sfc/base/efx_nvram.c71
-rw-r--r--drivers/net/sfc/base/efx_phy.c60
-rw-r--r--drivers/net/sfc/base/efx_port.c2
-rw-r--r--drivers/net/sfc/base/efx_rx.c225
-rw-r--r--drivers/net/sfc/base/efx_tunnel.c6
-rw-r--r--drivers/net/sfc/base/efx_tx.c19
-rw-r--r--drivers/net/sfc/base/hunt_nic.c19
-rw-r--r--drivers/net/sfc/base/mc_driver_pcol_strs.h102
-rw-r--r--drivers/net/sfc/base/mcdi_mon.c381
-rw-r--r--drivers/net/sfc/base/mcdi_mon.h5
-rw-r--r--drivers/net/sfc/base/medford2_nic.c15
-rw-r--r--drivers/net/sfc/base/medford_nic.c15
-rw-r--r--drivers/net/sfc/base/meson.build3
-rw-r--r--drivers/net/sfc/base/siena_mac.c9
-rw-r--r--drivers/net/sfc/base/siena_nic.c7
-rw-r--r--drivers/net/sfc/base/siena_nvram.c5
-rw-r--r--drivers/net/sfc/base/siena_phy.c28
-rw-r--r--drivers/net/sfc/efsys.h38
-rw-r--r--drivers/net/sfc/sfc_dp_tx.h5
-rw-r--r--drivers/net/sfc/sfc_ef10_essb_rx.c16
-rw-r--r--drivers/net/sfc/sfc_ef10_rx.c227
-rw-r--r--drivers/net/sfc/sfc_ef10_tx.c364
-rw-r--r--drivers/net/sfc/sfc_ethdev.c25
-rw-r--r--drivers/net/sfc/sfc_rx.c33
-rw-r--r--drivers/net/sfc/sfc_tso.c25
-rw-r--r--drivers/net/sfc/sfc_tso.h23
-rw-r--r--drivers/net/sfc/sfc_tx.c12
49 files changed, 3727 insertions, 1175 deletions
diff --git a/drivers/net/sfc/base/ef10_ev.c b/drivers/net/sfc/base/ef10_ev.c
index 7f89a7bf..cdf835f0 100644
--- a/drivers/net/sfc/base/ef10_ev.c
+++ b/drivers/net/sfc/base/ef10_ev.c
@@ -73,11 +73,10 @@ efx_mcdi_set_evq_tmr(
__in uint32_t timer_ns)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_SET_EVQ_TMR_IN_LEN,
- MC_CMD_SET_EVQ_TMR_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_EVQ_TMR_IN_LEN,
+ MC_CMD_SET_EVQ_TMR_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_EVQ_TMR;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_SET_EVQ_TMR_IN_LEN;
@@ -123,9 +122,9 @@ efx_mcdi_init_evq(
__in boolean_t low_latency)
{
efx_mcdi_req_t req;
- uint8_t payload[
- MAX(MC_CMD_INIT_EVQ_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
- MC_CMD_INIT_EVQ_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload,
+ MC_CMD_INIT_EVQ_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
+ MC_CMD_INIT_EVQ_OUT_LEN);
efx_qword_t *dma_addr;
uint64_t addr;
int npages;
@@ -140,7 +139,6 @@ efx_mcdi_init_evq(
goto fail1;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_INIT_EVQ;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_INIT_EVQ_IN_LEN(npages);
@@ -260,9 +258,9 @@ efx_mcdi_init_evq_v2(
__in uint32_t flags)
{
efx_mcdi_req_t req;
- uint8_t payload[
- MAX(MC_CMD_INIT_EVQ_V2_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
- MC_CMD_INIT_EVQ_V2_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload,
+ MC_CMD_INIT_EVQ_V2_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
+ MC_CMD_INIT_EVQ_V2_OUT_LEN);
boolean_t interrupting;
unsigned int evq_type;
efx_qword_t *dma_addr;
@@ -277,7 +275,6 @@ efx_mcdi_init_evq_v2(
goto fail1;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_INIT_EVQ;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_INIT_EVQ_V2_IN_LEN(npages);
@@ -384,11 +381,10 @@ efx_mcdi_fini_evq(
__in uint32_t instance)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_FINI_EVQ_IN_LEN,
- MC_CMD_FINI_EVQ_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FINI_EVQ_IN_LEN,
+ MC_CMD_FINI_EVQ_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_FINI_EVQ;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_FINI_EVQ_IN_LEN;
@@ -603,8 +599,8 @@ efx_mcdi_driver_event(
__in efx_qword_t data)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_DRIVER_EVENT_IN_LEN,
- MC_CMD_DRIVER_EVENT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_DRIVER_EVENT_IN_LEN,
+ MC_CMD_DRIVER_EVENT_OUT_LEN);
efx_rc_t rc;
req.emr_cmd = MC_CMD_DRIVER_EVENT;
@@ -867,8 +863,9 @@ ef10_ev_rx(
EFX_EV_QSTAT_INCR(eep, EV_RX);
- /* Discard events after RXQ/TXQ errors */
- if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
+ /* Discard events after RXQ/TXQ errors, or hardware not available */
+ if (enp->en_reset_flags &
+ (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR | EFX_RESET_HW_UNAVAIL))
return (B_FALSE);
/* Basic packet information */
@@ -1068,8 +1065,9 @@ ef10_ev_tx(
EFX_EV_QSTAT_INCR(eep, EV_TX);
- /* Discard events after RXQ/TXQ errors */
- if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
+ /* Discard events after RXQ/TXQ errors, or hardware not available */
+ if (enp->en_reset_flags &
+ (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR | EFX_RESET_HW_UNAVAIL))
return (B_FALSE);
if (EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DROP_EVENT) != 0) {
diff --git a/drivers/net/sfc/base/ef10_filter.c b/drivers/net/sfc/base/ef10_filter.c
index ae872853..afe4064d 100644
--- a/drivers/net/sfc/base/ef10_filter.c
+++ b/drivers/net/sfc/base/ef10_filter.c
@@ -172,12 +172,11 @@ efx_mcdi_filter_op_add(
__inout ef10_filter_handle_t *handle)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_FILTER_OP_V3_IN_LEN,
- MC_CMD_FILTER_OP_EXT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FILTER_OP_V3_IN_LEN,
+ MC_CMD_FILTER_OP_EXT_OUT_LEN);
efx_filter_match_flags_t match_flags;
efx_rc_t rc;
- memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_FILTER_OP;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_FILTER_OP_V3_IN_LEN;
@@ -376,11 +375,10 @@ efx_mcdi_filter_op_delete(
__inout ef10_filter_handle_t *handle)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_FILTER_OP_EXT_IN_LEN,
- MC_CMD_FILTER_OP_EXT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FILTER_OP_EXT_IN_LEN,
+ MC_CMD_FILTER_OP_EXT_OUT_LEN);
efx_rc_t rc;
- memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_FILTER_OP;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_FILTER_OP_EXT_IN_LEN;
@@ -950,13 +948,12 @@ efx_mcdi_get_parser_disp_info(
__out size_t *list_lengthp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PARSER_DISP_INFO_IN_LEN,
- MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PARSER_DISP_INFO_IN_LEN,
+ MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX);
size_t matches_count;
size_t list_size;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PARSER_DISP_INFO;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_PARSER_DISP_INFO_IN_LEN;
@@ -1144,12 +1141,15 @@ ef10_filter_insert_unicast(
efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
filter_flags,
eftp->eft_default_rxq);
- efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC, addr);
+ rc = efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC,
+ addr);
+ if (rc != 0)
+ goto fail1;
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&eftp->eft_unicst_filter_indexes[eftp->eft_unicst_filter_count]);
if (rc != 0)
- goto fail1;
+ goto fail2;
eftp->eft_unicst_filter_count++;
EFSYS_ASSERT(eftp->eft_unicst_filter_count <=
@@ -1157,6 +1157,8 @@ ef10_filter_insert_unicast(
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
@@ -1175,11 +1177,13 @@ ef10_filter_insert_all_unicast(
efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
filter_flags,
eftp->eft_default_rxq);
- efx_filter_spec_set_uc_def(&spec);
+ rc = efx_filter_spec_set_uc_def(&spec);
+ if (rc != 0)
+ goto fail1;
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&eftp->eft_unicst_filter_indexes[eftp->eft_unicst_filter_count]);
if (rc != 0)
- goto fail1;
+ goto fail2;
eftp->eft_unicst_filter_count++;
EFSYS_ASSERT(eftp->eft_unicst_filter_count <=
@@ -1187,6 +1191,8 @@ ef10_filter_insert_all_unicast(
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
@@ -1228,9 +1234,21 @@ ef10_filter_insert_multicast_list(
filter_flags,
eftp->eft_default_rxq);
- efx_filter_spec_set_eth_local(&spec,
+ rc = efx_filter_spec_set_eth_local(&spec,
EFX_FILTER_SPEC_VID_UNSPEC,
&addrs[i * EFX_MAC_ADDR_LEN]);
+ if (rc != 0) {
+ if (rollback == B_TRUE) {
+ /* Only stop upon failure if told to rollback */
+ goto rollback;
+ } else {
+ /*
+ * Don't try to add a filter with a corrupt
+ * specification.
+ */
+ continue;
+ }
+ }
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&filter_index);
@@ -1253,8 +1271,12 @@ ef10_filter_insert_multicast_list(
eftp->eft_default_rxq);
EFX_MAC_BROADCAST_ADDR_SET(addr);
- efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC,
- addr);
+ rc = efx_filter_spec_set_eth_local(&spec,
+ EFX_FILTER_SPEC_VID_UNSPEC, addr);
+ if ((rc != 0) && (rollback == B_TRUE)) {
+ /* Only stop upon failure if told to rollback */
+ goto rollback;
+ }
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&filter_index);
@@ -1302,12 +1324,14 @@ ef10_filter_insert_all_multicast(
efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
filter_flags,
eftp->eft_default_rxq);
- efx_filter_spec_set_mc_def(&spec);
+ rc = efx_filter_spec_set_mc_def(&spec);
+ if (rc != 0)
+ goto fail1;
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&eftp->eft_mulcst_filter_indexes[0]);
if (rc != 0)
- goto fail1;
+ goto fail2;
eftp->eft_mulcst_filter_count = 1;
eftp->eft_using_all_mulcst = B_TRUE;
@@ -1318,6 +1342,8 @@ ef10_filter_insert_all_multicast(
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
@@ -1552,7 +1578,7 @@ ef10_filter_reconfigure(
/*
* Insert or renew unicast filters.
*
- * Frimware does not perform chaining on unicast filters. As traffic is
+ * Firmware does not perform chaining on unicast filters. As traffic is
* therefore only delivered to the first matching filter, we should
* always insert the specific filter for our MAC address, to try and
* ensure we get that traffic.
diff --git a/drivers/net/sfc/base/ef10_image.c b/drivers/net/sfc/base/ef10_image.c
index 6fb7e476..c035e0df 100644
--- a/drivers/net/sfc/base/ef10_image.c
+++ b/drivers/net/sfc/base/ef10_image.c
@@ -577,7 +577,8 @@ fail1:
__checkReturn efx_rc_t
efx_build_signed_image_write_buffer(
- __out uint8_t *bufferp,
+ __out_bcount(buffer_size)
+ uint8_t *bufferp,
__in uint32_t buffer_size,
__in efx_image_info_t *infop,
__out efx_image_header_t **headerpp)
@@ -704,7 +705,7 @@ efx_build_signed_image_write_buffer(
* results in the layout used for the data chunks and chunk headers.
*/
/* END CSTYLED */
- memset(bufferp, buffer_size, 0xFF);
+ memset(bufferp, 0xFF, buffer_size);
EFX_STATIC_ASSERT(sizeof (chunk_hdr) == SIGNED_IMAGE_CHUNK_HDR_LEN);
memset(&chunk_hdr, 0, SIGNED_IMAGE_CHUNK_HDR_LEN);
diff --git a/drivers/net/sfc/base/ef10_impl.h b/drivers/net/sfc/base/ef10_impl.h
index 4751faf1..f971063a 100644
--- a/drivers/net/sfc/base/ef10_impl.h
+++ b/drivers/net/sfc/base/ef10_impl.h
@@ -190,6 +190,14 @@ extern __checkReturn efx_rc_t
ef10_nic_init(
__in efx_nic_t *enp);
+extern __checkReturn boolean_t
+ef10_nic_hw_unavailable(
+ __in efx_nic_t *enp);
+
+extern void
+ef10_nic_set_hw_unavailable(
+ __in efx_nic_t *enp);
+
#if EFSYS_OPT_DIAG
extern __checkReturn efx_rc_t
@@ -453,7 +461,7 @@ ef10_nvram_partn_write(
__in efx_nic_t *enp,
__in uint32_t partn,
__in unsigned int offset,
- __out_bcount(size) caddr_t data,
+ __in_bcount(size) caddr_t data,
__in size_t size);
extern __checkReturn efx_rc_t
@@ -477,17 +485,21 @@ ef10_nvram_partn_set_version(
extern __checkReturn efx_rc_t
ef10_nvram_buffer_validate(
- __in efx_nic_t *enp,
__in uint32_t partn,
__in_bcount(buffer_size)
caddr_t bufferp,
__in size_t buffer_size);
+extern void
+ef10_nvram_buffer_init(
+ __out_bcount(buffer_size)
+ caddr_t bufferp,
+ __in size_t buffer_size);
+
extern __checkReturn efx_rc_t
ef10_nvram_buffer_create(
- __in efx_nic_t *enp,
- __in uint16_t partn_type,
- __in_bcount(buffer_size)
+ __in uint32_t partn_type,
+ __out_bcount(buffer_size)
caddr_t bufferp,
__in size_t buffer_size);
@@ -516,15 +528,26 @@ ef10_nvram_buffer_find_item(
__out uint32_t *lengthp);
extern __checkReturn efx_rc_t
+ef10_nvram_buffer_peek_item(
+ __in_bcount(buffer_size)
+ caddr_t bufferp,
+ __in size_t buffer_size,
+ __in uint32_t offset,
+ __out uint32_t *tagp,
+ __out uint32_t *lengthp,
+ __out uint32_t *value_offsetp);
+
+extern __checkReturn efx_rc_t
ef10_nvram_buffer_get_item(
__in_bcount(buffer_size)
caddr_t bufferp,
__in size_t buffer_size,
__in uint32_t offset,
__in uint32_t length,
- __out_bcount_part(item_max_size, *lengthp)
- caddr_t itemp,
- __in size_t item_max_size,
+ __out uint32_t *tagp,
+ __out_bcount_part(value_max_size, *lengthp)
+ caddr_t valuep,
+ __in size_t value_max_size,
__out uint32_t *lengthp);
extern __checkReturn efx_rc_t
@@ -533,7 +556,19 @@ ef10_nvram_buffer_insert_item(
caddr_t bufferp,
__in size_t buffer_size,
__in uint32_t offset,
- __in_bcount(length) caddr_t keyp,
+ __in uint32_t tag,
+ __in_bcount(length) caddr_t valuep,
+ __in uint32_t length,
+ __out uint32_t *lengthp);
+
+extern __checkReturn efx_rc_t
+ef10_nvram_buffer_modify_item(
+ __in_bcount(buffer_size)
+ caddr_t bufferp,
+ __in size_t buffer_size,
+ __in uint32_t offset,
+ __in uint32_t tag,
+ __in_bcount(length) caddr_t valuep,
__in uint32_t length,
__out uint32_t *lengthp);
@@ -558,10 +593,7 @@ ef10_nvram_buffer_finish(
/* PHY */
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;
+ efx_phy_link_state_t epls;
#if EFSYS_OPT_LOOPBACK
efx_loopback_type_t els_loopback;
#endif
@@ -597,6 +629,11 @@ ef10_phy_oui_get(
__in efx_nic_t *enp,
__out uint32_t *ouip);
+extern __checkReturn efx_rc_t
+ef10_phy_link_state_get(
+ __in efx_nic_t *enp,
+ __out efx_phy_link_state_t *eplsp);
+
#if EFSYS_OPT_PHY_STATS
extern __checkReturn efx_rc_t
@@ -1128,11 +1165,12 @@ extern __checkReturn efx_rc_t
efx_mcdi_get_port_modes(
__in efx_nic_t *enp,
__out uint32_t *modesp,
- __out_opt uint32_t *current_modep);
+ __out_opt uint32_t *current_modep,
+ __out_opt uint32_t *default_modep);
extern __checkReturn efx_rc_t
ef10_nic_get_port_mode_bandwidth(
- __in uint32_t port_mode,
+ __in efx_nic_t *enp,
__out uint32_t *bandwidth_mbpsp);
extern __checkReturn efx_rc_t
diff --git a/drivers/net/sfc/base/ef10_intr.c b/drivers/net/sfc/base/ef10_intr.c
index 1ffe266b..efa15712 100644
--- a/drivers/net/sfc/base/ef10_intr.c
+++ b/drivers/net/sfc/base/ef10_intr.c
@@ -51,8 +51,8 @@ efx_mcdi_trigger_interrupt(
__in unsigned int level)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_TRIGGER_INTERRUPT_IN_LEN,
- MC_CMD_TRIGGER_INTERRUPT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_TRIGGER_INTERRUPT_IN_LEN,
+ MC_CMD_TRIGGER_INTERRUPT_OUT_LEN);
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
@@ -64,7 +64,6 @@ efx_mcdi_trigger_interrupt(
goto fail1;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_TRIGGER_INTERRUPT;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_TRIGGER_INTERRUPT_IN_LEN;
diff --git a/drivers/net/sfc/base/ef10_mac.c b/drivers/net/sfc/base/ef10_mac.c
index 1031e836..9f10f6f7 100644
--- a/drivers/net/sfc/base/ef10_mac.c
+++ b/drivers/net/sfc/base/ef10_mac.c
@@ -22,10 +22,10 @@ ef10_mac_poll(
if ((rc = ef10_phy_get_link(enp, &els)) != 0)
goto fail1;
- epp->ep_adv_cap_mask = els.els_adv_cap_mask;
- epp->ep_fcntl = els.els_fcntl;
+ epp->ep_adv_cap_mask = els.epls.epls_adv_cap_mask;
+ epp->ep_fcntl = els.epls.epls_fcntl;
- *link_modep = els.els_link_mode;
+ *link_modep = els.epls.epls_link_mode;
return (0);
@@ -75,11 +75,10 @@ efx_mcdi_vadapter_set_mac(
{
efx_port_t *epp = &(enp->en_port);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_VADAPTOR_SET_MAC_IN_LEN,
- MC_CMD_VADAPTOR_SET_MAC_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_SET_MAC_IN_LEN,
+ MC_CMD_VADAPTOR_SET_MAC_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_VADAPTOR_SET_MAC;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_VADAPTOR_SET_MAC_IN_LEN;
@@ -141,11 +140,10 @@ efx_mcdi_mtu_set(
__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_MCDI_DECLARE_BUF(payload, 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;
@@ -178,11 +176,10 @@ efx_mcdi_mtu_get(
__out size_t *mtu)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_SET_MAC_EXT_IN_LEN,
- MC_CMD_SET_MAC_V2_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_EXT_IN_LEN,
+ MC_CMD_SET_MAC_V2_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;
@@ -274,11 +271,10 @@ ef10_mac_reconfigure(
{
efx_port_t *epp = &(enp->en_port);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_SET_MAC_IN_LEN,
- MC_CMD_SET_MAC_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_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_IN_LEN;
@@ -412,7 +408,7 @@ ef10_mac_filter_default_rxq_clear(
ef10_filter_default_rxq_clear(enp);
- efx_filter_reconfigure(enp, epp->ep_mac_addr,
+ (void) efx_filter_reconfigure(enp, epp->ep_mac_addr,
epp->ep_all_unicst, epp->ep_mulcst,
epp->ep_all_mulcst, epp->ep_brdcst,
epp->ep_mulcst_addr_list,
@@ -654,7 +650,7 @@ ef10_mac_stats_update(
EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value);
EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_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);
+ EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_LE_64_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);
diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c
index 7dbf843b..50e23b7d 100644
--- a/drivers/net/sfc/base/ef10_nic.c
+++ b/drivers/net/sfc/base/ef10_nic.c
@@ -20,15 +20,14 @@ efx_mcdi_get_port_assignment(
__out uint32_t *portp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN,
- MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN,
+ MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN);
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD ||
enp->en_family == EFX_FAMILY_MEDFORD2);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN;
@@ -63,18 +62,18 @@ fail1:
efx_mcdi_get_port_modes(
__in efx_nic_t *enp,
__out uint32_t *modesp,
- __out_opt uint32_t *current_modep)
+ __out_opt uint32_t *current_modep,
+ __out_opt uint32_t *default_modep)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PORT_MODES_IN_LEN,
- MC_CMD_GET_PORT_MODES_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PORT_MODES_IN_LEN,
+ MC_CMD_GET_PORT_MODES_OUT_LEN);
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD ||
enp->en_family == EFX_FAMILY_MEDFORD2);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PORT_MODES;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_PORT_MODES_IN_LEN;
@@ -110,6 +109,11 @@ efx_mcdi_get_port_modes(
GET_PORT_MODES_OUT_CURRENT_MODE);
}
+ if (default_modep != NULL) {
+ *default_modep = MCDI_OUT_DWORD(req,
+ GET_PORT_MODES_OUT_DEFAULT_MODE);
+ }
+
return (0);
fail3:
@@ -124,44 +128,99 @@ fail1:
__checkReturn efx_rc_t
ef10_nic_get_port_mode_bandwidth(
- __in uint32_t port_mode,
+ __in efx_nic_t *enp,
__out uint32_t *bandwidth_mbpsp)
{
+ uint32_t port_modes;
+ uint32_t current_mode;
+ efx_port_t *epp = &(enp->en_port);
+
+ uint32_t single_lane;
+ uint32_t dual_lane;
+ uint32_t quad_lane;
uint32_t bandwidth;
efx_rc_t rc;
- switch (port_mode) {
- case TLV_PORT_MODE_10G:
- bandwidth = 10000;
+ if ((rc = efx_mcdi_get_port_modes(enp, &port_modes,
+ &current_mode, NULL)) != 0) {
+ /* No port mode info available. */
+ goto fail1;
+ }
+
+ if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_25000FDX))
+ single_lane = 25000;
+ else
+ single_lane = 10000;
+
+ if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_50000FDX))
+ dual_lane = 50000;
+ else
+ dual_lane = 20000;
+
+ if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_100000FDX))
+ quad_lane = 100000;
+ else
+ quad_lane = 40000;
+
+ switch (current_mode) {
+ case TLV_PORT_MODE_1x1_NA: /* mode 0 */
+ bandwidth = single_lane;
+ break;
+ case TLV_PORT_MODE_1x2_NA: /* mode 10 */
+ case TLV_PORT_MODE_NA_1x2: /* mode 11 */
+ bandwidth = dual_lane;
+ break;
+ case TLV_PORT_MODE_1x1_1x1: /* mode 2 */
+ bandwidth = single_lane + single_lane;
+ break;
+ case TLV_PORT_MODE_4x1_NA: /* mode 4 */
+ case TLV_PORT_MODE_NA_4x1: /* mode 8 */
+ bandwidth = 4 * single_lane;
+ break;
+ case TLV_PORT_MODE_2x1_2x1: /* mode 5 */
+ bandwidth = (2 * single_lane) + (2 * single_lane);
+ break;
+ case TLV_PORT_MODE_1x2_1x2: /* mode 12 */
+ bandwidth = dual_lane + dual_lane;
+ break;
+ case TLV_PORT_MODE_1x2_2x1: /* mode 17 */
+ case TLV_PORT_MODE_2x1_1x2: /* mode 18 */
+ bandwidth = dual_lane + (2 * single_lane);
break;
- case TLV_PORT_MODE_10G_10G:
- bandwidth = 10000 * 2;
+ /* Legacy Medford-only mode. Do not use (see bug63270) */
+ case TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2: /* mode 9 */
+ bandwidth = 4 * single_lane;
break;
- case TLV_PORT_MODE_10G_10G_10G_10G:
- case TLV_PORT_MODE_10G_10G_10G_10G_Q:
- case TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2:
- case TLV_PORT_MODE_10G_10G_10G_10G_Q2:
- bandwidth = 10000 * 4;
+ case TLV_PORT_MODE_1x4_NA: /* mode 1 */
+ case TLV_PORT_MODE_NA_1x4: /* mode 22 */
+ bandwidth = quad_lane;
break;
- case TLV_PORT_MODE_40G:
- bandwidth = 40000;
+ case TLV_PORT_MODE_2x2_NA: /* mode 13 */
+ case TLV_PORT_MODE_NA_2x2: /* mode 14 */
+ bandwidth = 2 * dual_lane;
break;
- case TLV_PORT_MODE_40G_40G:
- bandwidth = 40000 * 2;
+ case TLV_PORT_MODE_1x4_2x1: /* mode 6 */
+ case TLV_PORT_MODE_2x1_1x4: /* mode 7 */
+ bandwidth = quad_lane + (2 * single_lane);
break;
- case TLV_PORT_MODE_40G_10G_10G:
- case TLV_PORT_MODE_10G_10G_40G:
- bandwidth = 40000 + (10000 * 2);
+ case TLV_PORT_MODE_1x4_1x2: /* mode 15 */
+ case TLV_PORT_MODE_1x2_1x4: /* mode 16 */
+ bandwidth = quad_lane + dual_lane;
+ break;
+ case TLV_PORT_MODE_1x4_1x4: /* mode 3 */
+ bandwidth = quad_lane + quad_lane;
break;
default:
rc = EINVAL;
- goto fail1;
+ goto fail2;
}
*bandwidth_mbpsp = bandwidth;
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
@@ -174,13 +233,12 @@ efx_mcdi_vadaptor_alloc(
__in uint32_t port_id)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_VADAPTOR_ALLOC_IN_LEN,
- MC_CMD_VADAPTOR_ALLOC_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_ALLOC_IN_LEN,
+ MC_CMD_VADAPTOR_ALLOC_OUT_LEN);
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_vport_id, ==, EVB_PORT_ID_NULL);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_VADAPTOR_ALLOC;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_VADAPTOR_ALLOC_IN_LEN;
@@ -213,11 +271,10 @@ efx_mcdi_vadaptor_free(
__in uint32_t port_id)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_VADAPTOR_FREE_IN_LEN,
- MC_CMD_VADAPTOR_FREE_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_FREE_IN_LEN,
+ MC_CMD_VADAPTOR_FREE_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_VADAPTOR_FREE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_VADAPTOR_FREE_IN_LEN;
@@ -247,15 +304,14 @@ efx_mcdi_get_mac_address_pf(
__out_ecount_opt(6) uint8_t mac_addrp[6])
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_MAC_ADDRESSES_IN_LEN,
- MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_MAC_ADDRESSES_IN_LEN,
+ MC_CMD_GET_MAC_ADDRESSES_OUT_LEN);
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD ||
enp->en_family == EFX_FAMILY_MEDFORD2);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_MAC_ADDRESSES_IN_LEN;
@@ -306,15 +362,14 @@ efx_mcdi_get_mac_address_vf(
__out_ecount_opt(6) uint8_t mac_addrp[6])
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN,
- MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN,
+ MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX);
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD ||
enp->en_family == EFX_FAMILY_MEDFORD2);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN;
@@ -371,15 +426,14 @@ efx_mcdi_get_clock(
__out uint32_t *dpcpu_freqp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_CLOCK_IN_LEN,
- MC_CMD_GET_CLOCK_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CLOCK_IN_LEN,
+ MC_CMD_GET_CLOCK_OUT_LEN);
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD ||
enp->en_family == EFX_FAMILY_MEDFORD2);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_CLOCK;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_CLOCK_IN_LEN;
@@ -429,12 +483,11 @@ efx_mcdi_get_rxdp_config(
__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)];
+ EFX_MCDI_DECLARE_BUF(payload, 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;
@@ -489,11 +542,10 @@ efx_mcdi_get_vector_cfg(
__out_opt uint32_t *vf_nvecp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_VECTOR_CFG_IN_LEN,
- MC_CMD_GET_VECTOR_CFG_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_VECTOR_CFG_IN_LEN,
+ MC_CMD_GET_VECTOR_CFG_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_VECTOR_CFG;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_VECTOR_CFG_IN_LEN;
@@ -539,8 +591,8 @@ efx_mcdi_alloc_vis(
__out uint32_t *vi_shiftp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_ALLOC_VIS_IN_LEN,
- MC_CMD_ALLOC_VIS_EXT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_VIS_IN_LEN,
+ MC_CMD_ALLOC_VIS_EXT_OUT_LEN);
efx_rc_t rc;
if (vi_countp == NULL) {
@@ -548,7 +600,6 @@ efx_mcdi_alloc_vis(
goto fail1;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_ALLOC_VIS;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_ALLOC_VIS_IN_LEN;
@@ -631,8 +682,8 @@ efx_mcdi_alloc_piobuf(
__out efx_piobuf_handle_t *handlep)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_ALLOC_PIOBUF_IN_LEN,
- MC_CMD_ALLOC_PIOBUF_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ALLOC_PIOBUF_IN_LEN,
+ MC_CMD_ALLOC_PIOBUF_OUT_LEN);
efx_rc_t rc;
if (handlep == NULL) {
@@ -640,7 +691,6 @@ efx_mcdi_alloc_piobuf(
goto fail1;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_ALLOC_PIOBUF;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN;
@@ -679,11 +729,10 @@ efx_mcdi_free_piobuf(
__in efx_piobuf_handle_t handle)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_FREE_PIOBUF_IN_LEN,
- MC_CMD_FREE_PIOBUF_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FREE_PIOBUF_IN_LEN,
+ MC_CMD_FREE_PIOBUF_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_FREE_PIOBUF;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN;
@@ -714,11 +763,10 @@ efx_mcdi_link_piobuf(
__in efx_piobuf_handle_t handle)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_LINK_PIOBUF_IN_LEN,
- MC_CMD_LINK_PIOBUF_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LINK_PIOBUF_IN_LEN,
+ MC_CMD_LINK_PIOBUF_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_LINK_PIOBUF;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN;
@@ -749,11 +797,10 @@ efx_mcdi_unlink_piobuf(
__in uint32_t vi_index)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_UNLINK_PIOBUF_IN_LEN,
- MC_CMD_UNLINK_PIOBUF_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_UNLINK_PIOBUF_IN_LEN,
+ MC_CMD_UNLINK_PIOBUF_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_UNLINK_PIOBUF;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN;
@@ -806,7 +853,7 @@ fail1:
for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
- efx_mcdi_free_piobuf(enp, *handlep);
+ (void) efx_mcdi_free_piobuf(enp, *handlep);
*handlep = EFX_PIOBUF_HANDLE_INVALID;
}
enp->en_arch.ef10.ena_piobuf_count = 0;
@@ -823,7 +870,7 @@ ef10_nic_free_piobufs(
for (i = 0; i < enp->en_arch.ef10.ena_piobuf_count; i++) {
handlep = &enp->en_arch.ef10.ena_piobuf_handle[i];
- efx_mcdi_free_piobuf(enp, *handlep);
+ (void) efx_mcdi_free_piobuf(enp, *handlep);
*handlep = EFX_PIOBUF_HANDLE_INVALID;
}
enp->en_arch.ef10.ena_piobuf_count = 0;
@@ -951,11 +998,10 @@ ef10_mcdi_get_pf_count(
__out uint32_t *pf_countp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PF_COUNT_IN_LEN,
- MC_CMD_GET_PF_COUNT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PF_COUNT_IN_LEN,
+ MC_CMD_GET_PF_COUNT_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PF_COUNT;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_PF_COUNT_IN_LEN;
@@ -995,15 +1041,14 @@ ef10_get_datapath_caps(
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN,
- MC_CMD_GET_CAPABILITIES_V5_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CAPABILITIES_IN_LEN,
+ MC_CMD_GET_CAPABILITIES_V5_OUT_LEN);
efx_rc_t rc;
if ((rc = ef10_mcdi_get_pf_count(enp, &encp->enc_hw_pf_count)) != 0)
goto fail1;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_CAPABILITIES;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN;
@@ -1041,11 +1086,13 @@ ef10_get_datapath_caps(
}
encp->enc_rx_prefix_size = 14;
+#if EFSYS_OPT_RX_SCALE
/* Check if the firmware supports additional RSS modes */
if (CAP_FLAGS1(req, ADDITIONAL_RSS_MODES))
encp->enc_rx_scale_additional_modes_supported = B_TRUE;
else
encp->enc_rx_scale_additional_modes_supported = B_FALSE;
+#endif /* EFSYS_OPT_RX_SCALE */
/* Check if the firmware supports TSO */
if (CAP_FLAGS1(req, TX_TSO))
@@ -1251,6 +1298,7 @@ ef10_get_datapath_caps(
else
encp->enc_hlb_counters = B_FALSE;
+#if EFSYS_OPT_RX_SCALE
if (CAP_FLAGS1(req, RX_RSS_LIMITED)) {
/* Only one exclusive RSS context is available per port. */
encp->enc_rx_scale_max_exclusive_contexts = 1;
@@ -1300,6 +1348,8 @@ ef10_get_datapath_caps(
*/
encp->enc_rx_scale_l4_hash_supported = B_TRUE;
}
+#endif /* EFSYS_OPT_RX_SCALE */
+
/* Check if the firmware supports "FLAG" and "MARK" filter actions */
if (CAP_FLAGS2(req, FILTER_ACTION_FLAG))
encp->enc_filter_action_flag_supported = B_TRUE;
@@ -1323,8 +1373,10 @@ ef10_get_datapath_caps(
return (0);
+#if EFSYS_OPT_RX_SCALE
fail5:
EFSYS_PROBE(fail5);
+#endif /* EFSYS_OPT_RX_SCALE */
fail4:
EFSYS_PROBE(fail4);
fail3:
@@ -1478,8 +1530,8 @@ static struct ef10_external_port_map_s {
*/
{
EFX_FAMILY_MEDFORD,
- (1U << TLV_PORT_MODE_10G) | /* mode 0 */
- (1U << TLV_PORT_MODE_10G_10G), /* mode 2 */
+ (1U << TLV_PORT_MODE_1x1_NA) | /* mode 0 */
+ (1U << TLV_PORT_MODE_1x1_1x1), /* mode 2 */
1, /* ports per cage */
1 /* first cage */
},
@@ -1493,10 +1545,10 @@ static struct ef10_external_port_map_s {
*/
{
EFX_FAMILY_MEDFORD,
- (1U << TLV_PORT_MODE_40G) | /* mode 1 */
- (1U << TLV_PORT_MODE_40G_40G) | /* mode 3 */
- (1U << TLV_PORT_MODE_40G_10G_10G) | /* mode 6 */
- (1U << TLV_PORT_MODE_10G_10G_40G) | /* mode 7 */
+ (1U << TLV_PORT_MODE_1x4_NA) | /* mode 1 */
+ (1U << TLV_PORT_MODE_1x4_1x4) | /* mode 3 */
+ (1U << TLV_PORT_MODE_1x4_2x1) | /* mode 6 */
+ (1U << TLV_PORT_MODE_2x1_1x4) | /* mode 7 */
/* Do not use 10G_10G_10G_10G_Q1_Q2 (see bug63270) */
(1U << TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2), /* mode 9 */
2, /* ports per cage */
@@ -1512,9 +1564,9 @@ static struct ef10_external_port_map_s {
*/
{
EFX_FAMILY_MEDFORD,
- (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q) | /* mode 5 */
+ (1U << TLV_PORT_MODE_2x1_2x1) | /* mode 5 */
/* Do not use 10G_10G_10G_10G_Q1 (see bug63270) */
- (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q1), /* mode 4 */
+ (1U << TLV_PORT_MODE_4x1_NA), /* mode 4 */
4, /* ports per cage */
1 /* first cage */
},
@@ -1528,7 +1580,7 @@ static struct ef10_external_port_map_s {
*/
{
EFX_FAMILY_MEDFORD,
- (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q2), /* mode 8 */
+ (1U << TLV_PORT_MODE_NA_4x1), /* mode 8 */
4, /* ports per cage */
2 /* first cage */
},
@@ -1635,13 +1687,14 @@ ef10_external_port_mapping(
int32_t count = 1; /* Default 1-1 mapping */
int32_t offset = 1; /* Default starting external port number */
- if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, &current)) != 0) {
+ if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, &current,
+ NULL)) != 0) {
/*
* No current port mode information (i.e. Huntington)
* - infer mapping from available modes
*/
if ((rc = efx_mcdi_get_port_modes(enp,
- &port_modes, NULL)) != 0) {
+ &port_modes, NULL, NULL)) != 0) {
/*
* No port mode information available
* - use default mapping
@@ -1781,11 +1834,26 @@ ef10_nic_board_cfg(
if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
goto fail6;
+ /*
+ * Firmware with support for *_FEC capability bits does not
+ * report that the corresponding *_FEC_REQUESTED bits are supported.
+ * Add them here so that drivers understand that they are supported.
+ */
+ if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_BASER_FEC))
+ epp->ep_phy_cap_mask |=
+ (1u << EFX_PHY_CAP_BASER_FEC_REQUESTED);
+ if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_RS_FEC))
+ epp->ep_phy_cap_mask |=
+ (1u << EFX_PHY_CAP_RS_FEC_REQUESTED);
+ if (epp->ep_phy_cap_mask & (1u << EFX_PHY_CAP_25G_BASER_FEC))
+ epp->ep_phy_cap_mask |=
+ (1u << EFX_PHY_CAP_25G_BASER_FEC_REQUESTED);
+
/* 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;
+ epp->ep_default_adv_cap_mask = els.epls.epls_adv_cap_mask;
+ epp->ep_adv_cap_mask = els.epls.epls_adv_cap_mask;
/* Check capabilities of running datapath firmware */
if ((rc = ef10_get_datapath_caps(enp)) != 0)
@@ -2039,8 +2107,8 @@ ef10_nic_reset(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_ENTITY_RESET_IN_LEN,
- MC_CMD_ENTITY_RESET_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_ENTITY_RESET_IN_LEN,
+ MC_CMD_ENTITY_RESET_OUT_LEN);
efx_rc_t rc;
/* ef10_nic_reset() is called to recover from BADASSERT failures. */
@@ -2049,7 +2117,6 @@ ef10_nic_reset(
if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
goto fail2;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_ENTITY_RESET;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN;
@@ -2314,6 +2381,36 @@ fail1:
return (rc);
}
+ __checkReturn boolean_t
+ef10_nic_hw_unavailable(
+ __in efx_nic_t *enp)
+{
+ efx_dword_t dword;
+
+ if (enp->en_reset_flags & EFX_RESET_HW_UNAVAIL)
+ return (B_TRUE);
+
+ EFX_BAR_READD(enp, ER_DZ_BIU_MC_SFT_STATUS_REG, &dword, B_FALSE);
+ if (EFX_DWORD_FIELD(dword, EFX_DWORD_0) == 0xffffffff)
+ goto unavail;
+
+ return (B_FALSE);
+
+unavail:
+ ef10_nic_set_hw_unavailable(enp);
+
+ return (B_TRUE);
+}
+
+ void
+ef10_nic_set_hw_unavailable(
+ __in efx_nic_t *enp)
+{
+ EFSYS_PROBE(hw_unavail);
+ enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL;
+}
+
+
void
ef10_nic_fini(
__in efx_nic_t *enp)
@@ -2386,11 +2483,10 @@ efx_mcdi_get_nic_global(
__out uint32_t *valuep)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_NIC_GLOBAL_IN_LEN,
- MC_CMD_GET_NIC_GLOBAL_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_NIC_GLOBAL_IN_LEN,
+ MC_CMD_GET_NIC_GLOBAL_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_NIC_GLOBAL;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_NIC_GLOBAL_IN_LEN;
@@ -2430,10 +2526,9 @@ efx_mcdi_set_nic_global(
__in uint32_t value)
{
efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_SET_NIC_GLOBAL_IN_LEN];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_NIC_GLOBAL_IN_LEN, 0);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_NIC_GLOBAL;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_SET_NIC_GLOBAL_IN_LEN;
diff --git a/drivers/net/sfc/base/ef10_nvram.c b/drivers/net/sfc/base/ef10_nvram.c
index 2883ec8f..8d1b64f2 100644
--- a/drivers/net/sfc/base/ef10_nvram.c
+++ b/drivers/net/sfc/base/ef10_nvram.c
@@ -203,14 +203,14 @@ tlv_validate_state(
if (tlv_tag(cursor) != TLV_TAG_END) {
/* Check current item has space for tag and length */
- if (cursor->current > (cursor->limit - 2)) {
+ if (cursor->current > (cursor->limit - 1)) {
cursor->current = NULL;
rc = EFAULT;
goto fail3;
}
- /* Check we have value data for current item and another tag */
- if (tlv_next_item_ptr(cursor) > (cursor->limit - 1)) {
+ /* Check we have value data for current item and an END tag */
+ if (tlv_next_item_ptr(cursor) > cursor->limit) {
cursor->current = NULL;
rc = EFAULT;
goto fail4;
@@ -635,7 +635,6 @@ fail1:
/* Validate buffer contents (before writing to flash) */
__checkReturn efx_rc_t
ef10_nvram_buffer_validate(
- __in efx_nic_t *enp,
__in uint32_t partn,
__in_bcount(partn_size) caddr_t partn_data,
__in size_t partn_size)
@@ -648,7 +647,6 @@ ef10_nvram_buffer_validate(
int pos;
efx_rc_t rc;
- _NOTE(ARGUNUSED(enp, partn))
EFX_STATIC_ASSERT(sizeof (*header) <= EF10_NVRAM_CHUNK);
if ((partn_data == NULL) || (partn_size == 0)) {
@@ -675,26 +673,32 @@ ef10_nvram_buffer_validate(
goto fail4;
}
+ /* Check partition header matches partn */
+ if (__LE_TO_CPU_16(header->type_id) != partn) {
+ rc = EINVAL;
+ goto fail5;
+ }
+
/* Check partition ends with PARTITION_TRAILER and END tags */
if ((rc = tlv_find(&cursor, TLV_TAG_PARTITION_TRAILER)) != 0) {
rc = EINVAL;
- goto fail5;
+ goto fail6;
}
trailer = (struct tlv_partition_trailer *)tlv_item(&cursor);
if ((rc = tlv_advance(&cursor)) != 0) {
rc = EINVAL;
- goto fail6;
+ goto fail7;
}
if (tlv_tag(&cursor) != TLV_TAG_END) {
rc = EINVAL;
- goto fail7;
+ goto fail8;
}
/* Check generation counts are consistent */
if (trailer->generation != header->generation) {
rc = EINVAL;
- goto fail8;
+ goto fail9;
}
/* Verify partition checksum */
@@ -704,11 +708,13 @@ ef10_nvram_buffer_validate(
}
if (cksum != 0) {
rc = EINVAL;
- goto fail9;
+ goto fail10;
}
return (0);
+fail10:
+ EFSYS_PROBE(fail10);
fail9:
EFSYS_PROBE(fail9);
fail8:
@@ -731,13 +737,24 @@ fail1:
return (rc);
}
+ void
+ef10_nvram_buffer_init(
+ __out_bcount(buffer_size)
+ caddr_t bufferp,
+ __in size_t buffer_size)
+{
+ uint32_t *buf = (uint32_t *)bufferp;
+
+ memset(buf, 0xff, buffer_size);
+ tlv_init_block(buf);
+}
__checkReturn efx_rc_t
ef10_nvram_buffer_create(
- __in efx_nic_t *enp,
- __in uint16_t partn_type,
- __in_bcount(partn_size) caddr_t partn_data,
+ __in uint32_t partn_type,
+ __out_bcount(partn_size)
+ caddr_t partn_data,
__in size_t partn_size)
{
uint32_t *buf = (uint32_t *)partn_data;
@@ -753,9 +770,8 @@ ef10_nvram_buffer_create(
goto fail1;
}
- memset(buf, 0xff, partn_size);
+ ef10_nvram_buffer_init(partn_data, partn_size);
- tlv_init_block(buf);
if ((rc = tlv_init_cursor(&cursor, buf,
(uint32_t *)((uint8_t *)buf + partn_size),
buf)) != 0) {
@@ -787,7 +803,7 @@ ef10_nvram_buffer_create(
goto fail6;
/* Check that the partition is valid. */
- if ((rc = ef10_nvram_buffer_validate(enp, partn_type,
+ if ((rc = ef10_nvram_buffer_validate(partn_type,
partn_data, partn_size)) != 0)
goto fail7;
@@ -959,22 +975,65 @@ ef10_nvram_buffer_find_item(
}
__checkReturn efx_rc_t
+ef10_nvram_buffer_peek_item(
+ __in_bcount(buffer_size)
+ caddr_t bufferp,
+ __in size_t buffer_size,
+ __in uint32_t offset,
+ __out uint32_t *tagp,
+ __out uint32_t *lengthp,
+ __out uint32_t *value_offsetp)
+{
+ efx_rc_t rc;
+ tlv_cursor_t cursor;
+ uint32_t tag;
+
+ if ((rc = tlv_init_cursor_at_offset(&cursor, (uint8_t *)bufferp,
+ buffer_size, offset)) != 0) {
+ goto fail1;
+ }
+
+ tag = tlv_tag(&cursor);
+ *tagp = tag;
+ if (tag == TLV_TAG_END) {
+ /*
+ * To allow stepping over the END tag, report the full tag
+ * length and a zero length value.
+ */
+ *lengthp = sizeof (tag);
+ *value_offsetp = sizeof (tag);
+ } else {
+ *lengthp = byte_offset(tlv_next_item_ptr(&cursor),
+ cursor.current);
+ *value_offsetp = byte_offset((uint32_t *)tlv_value(&cursor),
+ cursor.current);
+ }
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
ef10_nvram_buffer_get_item(
__in_bcount(buffer_size)
caddr_t bufferp,
__in size_t buffer_size,
__in uint32_t offset,
__in uint32_t length,
- __out_bcount_part(item_max_size, *lengthp)
- caddr_t itemp,
- __in size_t item_max_size,
+ __out uint32_t *tagp,
+ __out_bcount_part(value_max_size, *lengthp)
+ caddr_t valuep,
+ __in size_t value_max_size,
__out uint32_t *lengthp)
{
efx_rc_t rc;
tlv_cursor_t cursor;
- uint32_t item_length;
+ uint32_t value_length;
- if (item_max_size < length) {
+ if (buffer_size < (offset + length)) {
rc = ENOSPC;
goto fail1;
}
@@ -984,14 +1043,15 @@ ef10_nvram_buffer_get_item(
goto fail2;
}
- item_length = tlv_length(&cursor);
- if (length < item_length) {
+ value_length = tlv_length(&cursor);
+ if (value_max_size < value_length) {
rc = ENOSPC;
goto fail3;
}
- memcpy(itemp, tlv_value(&cursor), item_length);
+ memcpy(valuep, tlv_value(&cursor), value_length);
- *lengthp = item_length;
+ *tagp = tlv_tag(&cursor);
+ *lengthp = value_length;
return (0);
@@ -1011,7 +1071,45 @@ ef10_nvram_buffer_insert_item(
caddr_t bufferp,
__in size_t buffer_size,
__in uint32_t offset,
- __in_bcount(length) caddr_t keyp,
+ __in uint32_t tag,
+ __in_bcount(length) caddr_t valuep,
+ __in uint32_t length,
+ __out uint32_t *lengthp)
+{
+ efx_rc_t rc;
+ tlv_cursor_t cursor;
+
+ if ((rc = tlv_init_cursor_at_offset(&cursor, (uint8_t *)bufferp,
+ buffer_size, offset)) != 0) {
+ goto fail1;
+ }
+
+ rc = tlv_insert(&cursor, tag, (uint8_t *)valuep, length);
+
+ if (rc != 0)
+ goto fail2;
+
+ *lengthp = byte_offset(tlv_next_item_ptr(&cursor),
+ cursor.current);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+ef10_nvram_buffer_modify_item(
+ __in_bcount(buffer_size)
+ caddr_t bufferp,
+ __in size_t buffer_size,
+ __in uint32_t offset,
+ __in uint32_t tag,
+ __in_bcount(length) caddr_t valuep,
__in uint32_t length,
__out uint32_t *lengthp)
{
@@ -1023,7 +1121,7 @@ ef10_nvram_buffer_insert_item(
goto fail1;
}
- rc = tlv_insert(&cursor, TLV_TAG_LICENSE, (uint8_t *)keyp, length);
+ rc = tlv_modify(&cursor, tag, (uint8_t *)valuep, length);
if (rc != 0) {
goto fail2;
@@ -1042,6 +1140,7 @@ fail1:
return (rc);
}
+
__checkReturn efx_rc_t
ef10_nvram_buffer_delete_item(
__in_bcount(buffer_size)
@@ -1808,7 +1907,7 @@ ef10_nvram_partn_write_segment_tlv(
goto fail7;
/* Unlock the partition */
- ef10_nvram_partn_unlock(enp, partn, NULL);
+ (void) ef10_nvram_partn_unlock(enp, partn, NULL);
EFSYS_KMEM_FREE(enp->en_esip, partn_size, partn_data);
@@ -1823,7 +1922,7 @@ fail5:
fail4:
EFSYS_PROBE(fail4);
- ef10_nvram_partn_unlock(enp, partn, NULL);
+ (void) ef10_nvram_partn_unlock(enp, partn, NULL);
fail3:
EFSYS_PROBE(fail3);
@@ -2000,7 +2099,7 @@ ef10_nvram_partn_write(
__in efx_nic_t *enp,
__in uint32_t partn,
__in unsigned int offset,
- __out_bcount(size) caddr_t data,
+ __in_bcount(size) caddr_t data,
__in size_t size)
{
size_t chunk;
@@ -2168,6 +2267,8 @@ static ef10_parttbl_entry_t medford2_parttbl[] = {
PARTN_MAP_ENTRY(LICENSE, ALL, LICENSE),
PARTN_MAP_ENTRY(EXPANSION_UEFI, ALL, UEFIROM),
PARTN_MAP_ENTRY(MUM_FIRMWARE, ALL, MUM_FIRMWARE),
+ PARTN_MAP_ENTRY(DYNCONFIG_DEFAULTS, ALL, DYNCONFIG_DEFAULTS),
+ PARTN_MAP_ENTRY(ROMCONFIG_DEFAULTS, ALL, ROMCONFIG_DEFAULTS),
};
static __checkReturn efx_rc_t
diff --git a/drivers/net/sfc/base/ef10_phy.c b/drivers/net/sfc/base/ef10_phy.c
index 84acb70a..84ccdde5 100644
--- a/drivers/net/sfc/base/ef10_phy.c
+++ b/drivers/net/sfc/base/ef10_phy.c
@@ -98,8 +98,10 @@ mcdi_phy_decode_link_mode(
__in uint32_t link_flags,
__in unsigned int speed,
__in unsigned int fcntl,
+ __in uint32_t fec,
__out efx_link_mode_t *link_modep,
- __out unsigned int *fcntlp)
+ __out unsigned int *fcntlp,
+ __out efx_phy_fec_type_t *fecp)
{
boolean_t fd = !!(link_flags &
(1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));
@@ -141,6 +143,22 @@ mcdi_phy_decode_link_mode(
EFSYS_PROBE1(mc_pcol_error, int, fcntl);
*fcntlp = 0;
}
+
+ switch (fec) {
+ case MC_CMD_FEC_NONE:
+ *fecp = EFX_PHY_FEC_NONE;
+ break;
+ case MC_CMD_FEC_BASER:
+ *fecp = EFX_PHY_FEC_BASER;
+ break;
+ case MC_CMD_FEC_RS:
+ *fecp = EFX_PHY_FEC_RS;
+ break;
+ default:
+ EFSYS_PROBE1(mc_pcol_error, int, fec);
+ *fecp = EFX_PHY_FEC_NONE;
+ break;
+ }
}
@@ -154,6 +172,7 @@ ef10_phy_link_ev(
unsigned int link_flags;
unsigned int speed;
unsigned int fcntl;
+ efx_phy_fec_type_t fec = MC_CMD_FEC_NONE;
efx_link_mode_t link_mode;
uint32_t lp_cap_mask;
@@ -191,7 +210,8 @@ ef10_phy_link_ev(
link_flags = MCDI_EV_FIELD(eqp, LINKCHANGE_LINK_FLAGS);
mcdi_phy_decode_link_mode(enp, link_flags, speed,
MCDI_EV_FIELD(eqp, LINKCHANGE_FCNTL),
- &link_mode, &fcntl);
+ MC_CMD_FEC_NONE, &link_mode,
+ &fcntl, &fec);
mcdi_phy_decode_cap(MCDI_EV_FIELD(eqp, LINKCHANGE_LP_CAP),
&lp_cap_mask);
@@ -242,16 +262,16 @@ ef10_phy_get_link(
__out ef10_link_state_t *elsp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_LINK_IN_LEN,
- MC_CMD_GET_LINK_OUT_LEN)];
+ uint32_t fec;
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LINK_IN_LEN,
+ MC_CMD_GET_LINK_OUT_V2_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_LINK;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_LINK_IN_LEN;
req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_GET_LINK_OUT_LEN;
+ req.emr_out_length = MC_CMD_GET_LINK_OUT_V2_LEN;
efx_mcdi_execute(enp, &req);
@@ -266,14 +286,28 @@ ef10_phy_get_link(
}
mcdi_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_CAP),
- &elsp->els_adv_cap_mask);
+ &elsp->epls.epls_adv_cap_mask);
mcdi_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_LP_CAP),
- &elsp->els_lp_cap_mask);
+ &elsp->epls.epls_lp_cap_mask);
+
+ if (req.emr_out_length_used < MC_CMD_GET_LINK_OUT_V2_LEN)
+ fec = MC_CMD_FEC_NONE;
+ else
+ fec = MCDI_OUT_DWORD(req, GET_LINK_OUT_V2_FEC_TYPE);
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),
- &elsp->els_link_mode, &elsp->els_fcntl);
+ fec, &elsp->epls.epls_link_mode,
+ &elsp->epls.epls_fcntl, &elsp->epls.epls_fec);
+
+ if (req.emr_out_length_used < MC_CMD_GET_LINK_OUT_V2_LEN) {
+ elsp->epls.epls_ld_cap_mask = 0;
+ } else {
+ mcdi_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_V2_LD_CAP),
+ &elsp->epls.epls_ld_cap_mask);
+ }
+
#if EFSYS_OPT_LOOPBACK
/*
@@ -301,8 +335,8 @@ ef10_phy_reconfigure(
{
efx_port_t *epp = &(enp->en_port);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_SET_LINK_IN_LEN,
- MC_CMD_SET_LINK_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_LINK_IN_LEN,
+ MC_CMD_SET_LINK_OUT_LEN);
uint32_t cap_mask;
#if EFSYS_OPT_PHY_LED_CONTROL
unsigned int led_mode;
@@ -316,7 +350,6 @@ ef10_phy_reconfigure(
if (supported == B_FALSE)
goto out;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_LINK;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_SET_LINK_IN_LEN;
@@ -464,12 +497,11 @@ ef10_phy_verify(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PHY_STATE_IN_LEN,
- MC_CMD_GET_PHY_STATE_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PHY_STATE_IN_LEN,
+ MC_CMD_GET_PHY_STATE_OUT_LEN);
uint32_t state;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PHY_STATE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_PHY_STATE_IN_LEN;
@@ -518,6 +550,29 @@ ef10_phy_oui_get(
return (ENOTSUP);
}
+ __checkReturn efx_rc_t
+ef10_phy_link_state_get(
+ __in efx_nic_t *enp,
+ __out efx_phy_link_state_t *eplsp)
+{
+ efx_rc_t rc;
+ ef10_link_state_t els;
+
+ /* Obtain the active link state */
+ if ((rc = ef10_phy_get_link(enp, &els)) != 0)
+ goto fail1;
+
+ *eplsp = els.epls;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+
#if EFSYS_OPT_PHY_STATS
__checkReturn efx_rc_t
@@ -583,22 +638,34 @@ ef10_bist_poll(
unsigned long *valuesp,
__in size_t count)
{
+ /*
+ * MCDI_CTL_SDU_LEN_MAX_V1 is large enough cover all BIST results,
+ * whilst not wasting stack.
+ */
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_POLL_BIST_IN_LEN,
+ MCDI_CTL_SDU_LEN_MAX_V1);
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN,
- MCDI_CTL_SDU_LEN_MAX)];
uint32_t value_mask = 0;
uint32_t result;
efx_rc_t rc;
+ EFX_STATIC_ASSERT(MC_CMD_POLL_BIST_OUT_LEN <=
+ MCDI_CTL_SDU_LEN_MAX_V1);
+ EFX_STATIC_ASSERT(MC_CMD_POLL_BIST_OUT_SFT9001_LEN <=
+ MCDI_CTL_SDU_LEN_MAX_V1);
+ EFX_STATIC_ASSERT(MC_CMD_POLL_BIST_OUT_MRSFP_LEN <=
+ MCDI_CTL_SDU_LEN_MAX_V1);
+ EFX_STATIC_ASSERT(MC_CMD_POLL_BIST_OUT_MEM_LEN <=
+ MCDI_CTL_SDU_LEN_MAX_V1);
+
_NOTE(ARGUNUSED(type))
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_POLL_BIST;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN;
req.emr_out_buf = payload;
- req.emr_out_length = MCDI_CTL_SDU_LEN_MAX;
+ req.emr_out_length = MCDI_CTL_SDU_LEN_MAX_V1;
efx_mcdi_execute(enp, &req);
diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c
index 313a3691..3c8f4f3b 100644
--- a/drivers/net/sfc/base/ef10_rx.c
+++ b/drivers/net/sfc/base/ef10_rx.c
@@ -29,8 +29,8 @@ efx_mcdi_init_rxq(
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_INIT_RXQ_V3_IN_LEN,
- MC_CMD_INIT_RXQ_V3_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_INIT_RXQ_V3_IN_LEN,
+ MC_CMD_INIT_RXQ_V3_OUT_LEN);
int npages = EFX_RXQ_NBUFS(ndescs);
int i;
efx_qword_t *dma_addr;
@@ -73,7 +73,6 @@ efx_mcdi_init_rxq(
want_outer_classes = B_FALSE;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_INIT_RXQ;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_INIT_RXQ_V3_IN_LEN;
@@ -146,11 +145,10 @@ efx_mcdi_fini_rxq(
__in uint32_t instance)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_FINI_RXQ_IN_LEN,
- MC_CMD_FINI_RXQ_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FINI_RXQ_IN_LEN,
+ MC_CMD_FINI_RXQ_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_FINI_RXQ;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_FINI_RXQ_IN_LEN;
@@ -188,8 +186,8 @@ efx_mcdi_rss_context_alloc(
__out uint32_t *rss_contextp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN,
- MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN,
+ MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN);
uint32_t rss_context;
uint32_t context_type;
efx_rc_t rc;
@@ -211,7 +209,6 @@ efx_mcdi_rss_context_alloc(
goto fail2;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_RSS_CONTEXT_ALLOC;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN;
@@ -274,8 +271,8 @@ efx_mcdi_rss_context_free(
__in uint32_t rss_context)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_FREE_IN_LEN,
- MC_CMD_RSS_CONTEXT_FREE_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_FREE_IN_LEN,
+ MC_CMD_RSS_CONTEXT_FREE_OUT_LEN);
efx_rc_t rc;
if (rss_context == EF10_RSS_CONTEXT_INVALID) {
@@ -283,7 +280,6 @@ efx_mcdi_rss_context_free(
goto fail1;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_RSS_CONTEXT_FREE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_RSS_CONTEXT_FREE_IN_LEN;
@@ -318,14 +314,9 @@ efx_mcdi_rss_context_set_flags(
__in efx_rx_hash_type_t type)
{
efx_nic_cfg_t *encp = &enp->en_nic_cfg;
- efx_rx_hash_type_t type_ipv4;
- efx_rx_hash_type_t type_ipv4_tcp;
- efx_rx_hash_type_t type_ipv6;
- efx_rx_hash_type_t type_ipv6_tcp;
- efx_rx_hash_type_t modes;
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN,
- MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN,
+ MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN);
efx_rc_t rc;
EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_TCP_LBN ==
@@ -350,7 +341,6 @@ efx_mcdi_rss_context_set_flags(
goto fail1;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_FLAGS;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN;
@@ -360,57 +350,38 @@ efx_mcdi_rss_context_set_flags(
MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID,
rss_context);
- type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE) | EFX_RX_HASH(IPV4_TCP, 2TUPLE) |
- EFX_RX_HASH(IPV4_UDP, 2TUPLE);
- type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE);
- type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE) | EFX_RX_HASH(IPV6_TCP, 2TUPLE) |
- EFX_RX_HASH(IPV6_UDP, 2TUPLE);
- type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE);
-
- /*
- * Create a copy of the original hash type.
- * The copy will be used to fill in RSS_MODE bits and
- * may be cleared beforehand. The original variable
- * and, thus, EN bits will remain unaffected.
- */
- modes = type;
-
/*
* If the firmware lacks support for additional modes, RSS_MODE
* fields must contain zeros, otherwise the operation will fail.
*/
if (encp->enc_rx_scale_additional_modes_supported == B_FALSE)
- modes = 0;
-
-#define EXTRACT_RSS_MODE(_type, _class) \
- (EFX_EXTRACT_NATIVE(_type, 0, 31, \
- EFX_LOW_BIT(EFX_RX_CLASS_##_class), \
- EFX_HIGH_BIT(EFX_RX_CLASS_##_class)) & \
- EFX_MASK32(EFX_RX_CLASS_##_class))
+ type &= EFX_RX_HASH_LEGACY_MASK;
MCDI_IN_POPULATE_DWORD_10(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS,
RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN,
- ((type & type_ipv4) == type_ipv4) ? 1 : 0,
+ (type & EFX_RX_HASH_IPV4) ? 1 : 0,
RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN,
- ((type & type_ipv4_tcp) == type_ipv4_tcp) ? 1 : 0,
+ (type & EFX_RX_HASH_TCPIPV4) ? 1 : 0,
RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN,
- ((type & type_ipv6) == type_ipv6) ? 1 : 0,
+ (type & EFX_RX_HASH_IPV6) ? 1 : 0,
RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN,
- ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0,
+ (type & EFX_RX_HASH_TCPIPV6) ? 1 : 0,
RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE,
- EXTRACT_RSS_MODE(modes, IPV4_TCP),
+ (type >> EFX_RX_CLASS_IPV4_TCP_LBN) &
+ EFX_MASK32(EFX_RX_CLASS_IPV4_TCP),
RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE,
- EXTRACT_RSS_MODE(modes, IPV4_UDP),
+ (type >> EFX_RX_CLASS_IPV4_UDP_LBN) &
+ EFX_MASK32(EFX_RX_CLASS_IPV4_UDP),
RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE,
- EXTRACT_RSS_MODE(modes, IPV4),
+ (type >> EFX_RX_CLASS_IPV4_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV4),
RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE,
- EXTRACT_RSS_MODE(modes, IPV6_TCP),
+ (type >> EFX_RX_CLASS_IPV6_TCP_LBN) &
+ EFX_MASK32(EFX_RX_CLASS_IPV6_TCP),
RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE,
- EXTRACT_RSS_MODE(modes, IPV6_UDP),
+ (type >> EFX_RX_CLASS_IPV6_UDP_LBN) &
+ EFX_MASK32(EFX_RX_CLASS_IPV6_UDP),
RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE,
- EXTRACT_RSS_MODE(modes, IPV6));
-
-#undef EXTRACT_RSS_MODE
+ (type >> EFX_RX_CLASS_IPV6_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV6));
efx_mcdi_execute(enp, &req);
@@ -439,8 +410,8 @@ efx_mcdi_rss_context_set_key(
__in size_t n)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN,
- MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN,
+ MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN);
efx_rc_t rc;
if (rss_context == EF10_RSS_CONTEXT_INVALID) {
@@ -448,7 +419,6 @@ efx_mcdi_rss_context_set_key(
goto fail1;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_KEY;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN;
@@ -496,8 +466,8 @@ efx_mcdi_rss_context_set_table(
__in size_t n)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN,
- MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN,
+ MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN);
uint8_t *req_table;
int i, rc;
@@ -506,7 +476,6 @@ efx_mcdi_rss_context_set_table(
goto fail1;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_TABLE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN;
diff --git a/drivers/net/sfc/base/ef10_signed_image_layout.h b/drivers/net/sfc/base/ef10_signed_image_layout.h
index a35d1601..c25ffe2f 100644
--- a/drivers/net/sfc/base/ef10_signed_image_layout.h
+++ b/drivers/net/sfc/base/ef10_signed_image_layout.h
@@ -4,6 +4,14 @@
* All rights reserved.
*/
+/*
+ * This is NOT the original source file. Do NOT edit it.
+ * To update the image layout headers, please edit the copy in
+ * the sfregistry repo and then, in that repo,
+ * "make layout_headers" or "make export" to
+ * regenerate and export all types of headers.
+ */
+
/* These structures define the layouts for the signed firmware image binary
* saved in NVRAM. The original image is in the Cryptographic message
* syntax (CMS) format which contains the bootable firmware binary plus the
diff --git a/drivers/net/sfc/base/ef10_tx.c b/drivers/net/sfc/base/ef10_tx.c
index 7d27f710..5f3df42b 100644
--- a/drivers/net/sfc/base/ef10_tx.c
+++ b/drivers/net/sfc/base/ef10_tx.c
@@ -31,8 +31,8 @@ efx_mcdi_init_txq(
__in efsys_mem_t *esmp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_INIT_TXQ_IN_LEN(EFX_TXQ_MAX_BUFS),
- MC_CMD_INIT_TXQ_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_INIT_TXQ_IN_LEN(EFX_TXQ_MAX_BUFS),
+ MC_CMD_INIT_TXQ_OUT_LEN);
efx_qword_t *dma_addr;
uint64_t addr;
int npages;
@@ -53,7 +53,6 @@ efx_mcdi_init_txq(
goto fail2;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_INIT_TXQ;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_INIT_TXQ_IN_LEN(npages);
@@ -120,11 +119,10 @@ efx_mcdi_fini_txq(
__in uint32_t instance)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_FINI_TXQ_IN_LEN,
- MC_CMD_FINI_TXQ_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FINI_TXQ_IN_LEN,
+ MC_CMD_FINI_TXQ_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_FINI_TXQ;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_FINI_TXQ_IN_LEN;
@@ -278,7 +276,7 @@ ef10_tx_qpio_enable(
fail3:
EFSYS_PROBE(fail3);
- ef10_nic_pio_free(enp, etp->et_pio_bufnum, etp->et_pio_blknum);
+ (void) ef10_nic_pio_free(enp, etp->et_pio_bufnum, etp->et_pio_blknum);
fail2:
EFSYS_PROBE(fail2);
etp->et_pio_size = 0;
@@ -296,10 +294,12 @@ ef10_tx_qpio_disable(
if (etp->et_pio_size != 0) {
/* Unlink the piobuf from this TXQ */
- ef10_nic_pio_unlink(enp, etp->et_index);
+ if (ef10_nic_pio_unlink(enp, etp->et_index) != 0)
+ return;
/* Free the sub-allocated PIO block */
- ef10_nic_pio_free(enp, etp->et_pio_bufnum, etp->et_pio_blknum);
+ (void) ef10_nic_pio_free(enp, etp->et_pio_bufnum,
+ etp->et_pio_blknum);
etp->et_pio_size = 0;
etp->et_pio_write_offset = 0;
}
@@ -539,12 +539,9 @@ ef10_tx_qdesc_post(
{
unsigned int added = *addedp;
unsigned int i;
- efx_rc_t rc;
- if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
- rc = ENOSPC;
- goto fail1;
- }
+ if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1))
+ return (ENOSPC);
for (i = 0; i < ndescs; i++) {
efx_desc_t *edp = &ed[i];
@@ -564,11 +561,6 @@ ef10_tx_qdesc_post(
*addedp = added;
return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
}
void
@@ -637,22 +629,22 @@ ef10_tx_qdesc_tso2_create(
EFSYS_ASSERT(count >= EFX_TX_FATSOV2_OPT_NDESCS);
- EFX_POPULATE_QWORD_6(edp[0].ed_eq,
+ 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_OUTER_IPID, outer_ipv4_id,
ESF_DZ_TX_TSO_TCP_SEQNO, tcp_seq);
- EFX_POPULATE_QWORD_4(edp[1].ed_eq,
+ EFX_POPULATE_QWORD_5(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);
+ ESF_DZ_TX_TSO_TCP_MSS, tcp_mss,
+ ESF_DZ_TX_TSO_OUTER_IPID, outer_ipv4_id);
}
void
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 5108b9b1..8e10e893 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -7,6 +7,7 @@
#ifndef _SYS_EFX_H
#define _SYS_EFX_H
+#include "efx_annote.h"
#include "efsys.h"
#include "efx_check.h"
#include "efx_phy_ids.h"
@@ -154,6 +155,14 @@ extern __checkReturn efx_rc_t
efx_nic_reset(
__in efx_nic_t *enp);
+extern __checkReturn boolean_t
+efx_nic_hw_unavailable(
+ __in efx_nic_t *enp);
+
+extern void
+efx_nic_set_hw_unavailable(
+ __in efx_nic_t *enp);
+
#if EFSYS_OPT_DIAG
extern __checkReturn efx_rc_t
@@ -661,77 +670,74 @@ efx_mon_init(
#define EFX_MON_STATS_PAGE_SIZE 0x100
#define EFX_MON_MASK_ELEMENT_SIZE 32
-/* START MKCONFIG GENERATED MonitorHeaderStatsBlock 400fdb0517af1fca */
+/* START MKCONFIG GENERATED MonitorHeaderStatsBlock 78b65c8d5af9747b */
typedef enum efx_mon_stat_e {
- EFX_MON_STAT_2_5V,
- EFX_MON_STAT_VCCP1,
- EFX_MON_STAT_VCC,
- EFX_MON_STAT_5V,
- EFX_MON_STAT_12V,
- EFX_MON_STAT_VCCP2,
- EFX_MON_STAT_EXT_TEMP,
- EFX_MON_STAT_INT_TEMP,
- EFX_MON_STAT_AIN1,
- EFX_MON_STAT_AIN2,
- EFX_MON_STAT_INT_COOLING,
- EFX_MON_STAT_EXT_COOLING,
- EFX_MON_STAT_1V,
- EFX_MON_STAT_1_2V,
- EFX_MON_STAT_1_8V,
- EFX_MON_STAT_3_3V,
- EFX_MON_STAT_1_2VA,
- EFX_MON_STAT_VREF,
- EFX_MON_STAT_VAOE,
+ EFX_MON_STAT_CONTROLLER_TEMP,
+ EFX_MON_STAT_PHY_COMMON_TEMP,
+ EFX_MON_STAT_CONTROLLER_COOLING,
+ EFX_MON_STAT_PHY0_TEMP,
+ EFX_MON_STAT_PHY0_COOLING,
+ EFX_MON_STAT_PHY1_TEMP,
+ EFX_MON_STAT_PHY1_COOLING,
+ EFX_MON_STAT_IN_1V0,
+ EFX_MON_STAT_IN_1V2,
+ EFX_MON_STAT_IN_1V8,
+ EFX_MON_STAT_IN_2V5,
+ EFX_MON_STAT_IN_3V3,
+ EFX_MON_STAT_IN_12V0,
+ EFX_MON_STAT_IN_1V2A,
+ EFX_MON_STAT_IN_VREF,
+ EFX_MON_STAT_OUT_VAOE,
EFX_MON_STAT_AOE_TEMP,
EFX_MON_STAT_PSU_AOE_TEMP,
EFX_MON_STAT_PSU_TEMP,
- EFX_MON_STAT_FAN0,
- EFX_MON_STAT_FAN1,
- EFX_MON_STAT_FAN2,
- EFX_MON_STAT_FAN3,
- EFX_MON_STAT_FAN4,
- EFX_MON_STAT_VAOE_IN,
- EFX_MON_STAT_IAOE,
- EFX_MON_STAT_IAOE_IN,
+ EFX_MON_STAT_FAN_0,
+ EFX_MON_STAT_FAN_1,
+ EFX_MON_STAT_FAN_2,
+ EFX_MON_STAT_FAN_3,
+ EFX_MON_STAT_FAN_4,
+ EFX_MON_STAT_IN_VAOE,
+ EFX_MON_STAT_OUT_IAOE,
+ EFX_MON_STAT_IN_IAOE,
EFX_MON_STAT_NIC_POWER,
- EFX_MON_STAT_0_9V,
- EFX_MON_STAT_I0_9V,
- EFX_MON_STAT_I1_2V,
- EFX_MON_STAT_0_9V_ADC,
- EFX_MON_STAT_INT_TEMP2,
- EFX_MON_STAT_VREG_TEMP,
- EFX_MON_STAT_VREG_0_9V_TEMP,
- EFX_MON_STAT_VREG_1_2V_TEMP,
- EFX_MON_STAT_INT_VPTAT,
- EFX_MON_STAT_INT_ADC_TEMP,
- EFX_MON_STAT_EXT_VPTAT,
- EFX_MON_STAT_EXT_ADC_TEMP,
+ EFX_MON_STAT_IN_0V9,
+ EFX_MON_STAT_IN_I0V9,
+ EFX_MON_STAT_IN_I1V2,
+ EFX_MON_STAT_IN_0V9_ADC,
+ EFX_MON_STAT_CONTROLLER_2_TEMP,
+ EFX_MON_STAT_VREG_INTERNAL_TEMP,
+ EFX_MON_STAT_VREG_0V9_TEMP,
+ EFX_MON_STAT_VREG_1V2_TEMP,
+ EFX_MON_STAT_CONTROLLER_VPTAT,
+ EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP,
+ EFX_MON_STAT_CONTROLLER_VPTAT_EXTADC,
+ EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP_EXTADC,
EFX_MON_STAT_AMBIENT_TEMP,
EFX_MON_STAT_AIRFLOW,
EFX_MON_STAT_VDD08D_VSS08D_CSR,
EFX_MON_STAT_VDD08D_VSS08D_CSR_EXTADC,
EFX_MON_STAT_HOTPOINT_TEMP,
- EFX_MON_STAT_PHY_POWER_SWITCH_PORT0,
- EFX_MON_STAT_PHY_POWER_SWITCH_PORT1,
+ EFX_MON_STAT_PHY_POWER_PORT0,
+ EFX_MON_STAT_PHY_POWER_PORT1,
EFX_MON_STAT_MUM_VCC,
- EFX_MON_STAT_0V9_A,
- EFX_MON_STAT_I0V9_A,
- EFX_MON_STAT_0V9_A_TEMP,
- EFX_MON_STAT_0V9_B,
- EFX_MON_STAT_I0V9_B,
- EFX_MON_STAT_0V9_B_TEMP,
+ EFX_MON_STAT_IN_0V9_A,
+ EFX_MON_STAT_IN_I0V9_A,
+ EFX_MON_STAT_VREG_0V9_A_TEMP,
+ EFX_MON_STAT_IN_0V9_B,
+ EFX_MON_STAT_IN_I0V9_B,
+ EFX_MON_STAT_VREG_0V9_B_TEMP,
EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY,
- EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXT_ADC,
+ EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXTADC,
EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY,
- EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXT_ADC,
+ EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXTADC,
EFX_MON_STAT_CONTROLLER_MASTER_VPTAT,
EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP,
- EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXT_ADC,
- EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXT_ADC,
+ EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXTADC,
+ EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC,
EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT,
EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP,
- EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXT_ADC,
- EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXT_ADC,
+ EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXTADC,
+ EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC,
EFX_MON_STAT_SODIMM_VOUT,
EFX_MON_STAT_SODIMM_0_TEMP,
EFX_MON_STAT_SODIMM_1_TEMP,
@@ -740,12 +746,12 @@ typedef enum efx_mon_stat_e {
EFX_MON_STAT_CONTROLLER_TDIODE_TEMP,
EFX_MON_STAT_BOARD_FRONT_TEMP,
EFX_MON_STAT_BOARD_BACK_TEMP,
- EFX_MON_STAT_I1V8,
- EFX_MON_STAT_I2V5,
- EFX_MON_STAT_I3V3,
- EFX_MON_STAT_I12V0,
- EFX_MON_STAT_1_3V,
- EFX_MON_STAT_I1V3,
+ EFX_MON_STAT_IN_I1V8,
+ EFX_MON_STAT_IN_I2V5,
+ EFX_MON_STAT_IN_I3V3,
+ EFX_MON_STAT_IN_I12V0,
+ EFX_MON_STAT_IN_1V3,
+ EFX_MON_STAT_IN_I1V3,
EFX_MON_NSTATS
} efx_mon_stat_t;
@@ -759,11 +765,40 @@ typedef enum efx_mon_stat_state_e {
EFX_MON_STAT_STATE_NO_READING = 4,
} efx_mon_stat_state_t;
+typedef enum efx_mon_stat_unit_e {
+ EFX_MON_STAT_UNIT_UNKNOWN = 0,
+ EFX_MON_STAT_UNIT_BOOL,
+ EFX_MON_STAT_UNIT_TEMP_C,
+ EFX_MON_STAT_UNIT_VOLTAGE_MV,
+ EFX_MON_STAT_UNIT_CURRENT_MA,
+ EFX_MON_STAT_UNIT_POWER_W,
+ EFX_MON_STAT_UNIT_RPM,
+ EFX_MON_NUNITS
+} efx_mon_stat_unit_t;
+
typedef struct efx_mon_stat_value_s {
- uint16_t emsv_value;
- uint16_t emsv_state;
+ uint16_t emsv_value;
+ efx_mon_stat_state_t emsv_state;
+ efx_mon_stat_unit_t emsv_unit;
} efx_mon_stat_value_t;
+typedef struct efx_mon_limit_value_s {
+ uint16_t emlv_warning_min;
+ uint16_t emlv_warning_max;
+ uint16_t emlv_fatal_min;
+ uint16_t emlv_fatal_max;
+} efx_mon_stat_limits_t;
+
+typedef enum efx_mon_stat_portmask_e {
+ EFX_MON_STAT_PORTMAP_NONE = 0,
+ EFX_MON_STAT_PORTMAP_PORT0 = 1,
+ EFX_MON_STAT_PORTMAP_PORT1 = 2,
+ EFX_MON_STAT_PORTMAP_PORT2 = 3,
+ EFX_MON_STAT_PORTMAP_PORT3 = 4,
+ EFX_MON_STAT_PORTMAP_ALL = (-1),
+ EFX_MON_STAT_PORTMAP_UNKNOWN = (-2)
+} efx_mon_stat_portmask_t;
+
#if EFSYS_OPT_NAMES
extern const char *
@@ -771,14 +806,39 @@ efx_mon_stat_name(
__in efx_nic_t *enp,
__in efx_mon_stat_t id);
+extern const char *
+efx_mon_stat_description(
+ __in efx_nic_t *enp,
+ __in efx_mon_stat_t id);
+
#endif /* EFSYS_OPT_NAMES */
+extern __checkReturn boolean_t
+efx_mon_mcdi_to_efx_stat(
+ __in int mcdi_index,
+ __out efx_mon_stat_t *statp);
+
+extern __checkReturn boolean_t
+efx_mon_get_stat_unit(
+ __in efx_mon_stat_t stat,
+ __out efx_mon_stat_unit_t *unitp);
+
+extern __checkReturn boolean_t
+efx_mon_get_stat_portmap(
+ __in efx_mon_stat_t stat,
+ __out efx_mon_stat_portmask_t *maskp);
+
extern __checkReturn efx_rc_t
efx_mon_stats_update(
__in efx_nic_t *enp,
__in efsys_mem_t *esmp,
__inout_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values);
+extern __checkReturn efx_rc_t
+efx_mon_limits_update(
+ __in efx_nic_t *enp,
+ __inout_ecount(EFX_MON_NSTATS) efx_mon_stat_limits_t *values);
+
#endif /* EFSYS_OPT_MON_STATS */
extern void
@@ -970,12 +1030,39 @@ efx_phy_media_type_get(
__in efx_nic_t *enp,
__out efx_phy_media_type_t *typep);
+/*
+ * 2-wire device address of the base information in accordance with SFF-8472
+ * Diagnostic Monitoring Interface for Optical Transceivers section
+ * 4 Memory Organization.
+ */
+#define EFX_PHY_MEDIA_INFO_DEV_ADDR_SFP_BASE 0xA0
+
+/*
+ * 2-wire device address of the digital diagnostics monitoring interface
+ * in accordance with SFF-8472 Diagnostic Monitoring Interface for Optical
+ * Transceivers section 4 Memory Organization.
+ */
+#define EFX_PHY_MEDIA_INFO_DEV_ADDR_SFP_DDM 0xA2
+
+/*
+ * Hard wired 2-wire device address for QSFP+ in accordance with SFF-8436
+ * QSFP+ 10 Gbs 4X PLUGGABLE TRANSCEIVER section 7.4 Device Addressing and
+ * Operation.
+ */
+#define EFX_PHY_MEDIA_INFO_DEV_ADDR_QSFP 0xA0
+
+/*
+ * Maximum accessible data offset for PHY module information.
+ */
+#define EFX_PHY_MEDIA_INFO_MAX_OFFSET 0x100
+
+
extern __checkReturn efx_rc_t
efx_phy_module_get_info(
__in efx_nic_t *enp,
__in uint8_t dev_addr,
- __in uint8_t offset,
- __in uint8_t len,
+ __in size_t offset,
+ __in size_t len,
__out_bcount(len) uint8_t *data);
#if EFSYS_OPT_PHY_STATS
@@ -1194,6 +1281,7 @@ typedef struct efx_nic_cfg_s {
uint32_t enc_rx_prefix_size;
uint32_t enc_rx_buf_align_start;
uint32_t enc_rx_buf_align_end;
+#if EFSYS_OPT_RX_SCALE
uint32_t enc_rx_scale_max_exclusive_contexts;
/*
* Mask of supported hash algorithms.
@@ -1206,6 +1294,7 @@ typedef struct efx_nic_cfg_s {
*/
boolean_t enc_rx_scale_l4_hash_supported;
boolean_t enc_rx_scale_additional_modes_supported;
+#endif /* EFSYS_OPT_RX_SCALE */
#if EFSYS_OPT_LOOPBACK
efx_qword_t enc_loopback_types[EFX_LINK_NMODES];
#endif /* EFSYS_OPT_LOOPBACK */
@@ -1240,6 +1329,7 @@ typedef struct efx_nic_cfg_s {
boolean_t enc_bug35388_workaround;
boolean_t enc_bug41750_workaround;
boolean_t enc_bug61265_workaround;
+ boolean_t enc_bug61297_workaround;
boolean_t enc_rx_batching_enabled;
/* Maximum number of descriptors completed in an rx event. */
uint32_t enc_rx_batch_max;
@@ -1483,6 +1573,8 @@ typedef enum efx_nvram_type_e {
EFX_NVRAM_LICENSE,
EFX_NVRAM_UEFIROM,
EFX_NVRAM_MUM_FIRMWARE,
+ EFX_NVRAM_DYNCONFIG_DEFAULTS,
+ EFX_NVRAM_ROMCONFIG_DEFAULTS,
EFX_NVRAM_NTYPES,
} efx_nvram_type_t;
@@ -1608,6 +1700,87 @@ efx_bootcfg_write(
__in_bcount(size) uint8_t *data,
__in size_t size);
+
+/*
+ * Processing routines for buffers arranged in the DHCP/BOOTP option format
+ * (see https://tools.ietf.org/html/rfc1533)
+ *
+ * Summarising the format: the buffer is a sequence of options. All options
+ * begin with a tag octet, which uniquely identifies the option. Fixed-
+ * length options without data consist of only a tag octet. Only options PAD
+ * (0) and END (255) are fixed length. All other options are variable-length
+ * with a length octet following the tag octet. The value of the length
+ * octet does not include the two octets specifying the tag and length. The
+ * length octet is followed by "length" octets of data.
+ *
+ * Option data may be a sequence of sub-options in the same format. The data
+ * content of the encapsulating option is one or more encapsulated sub-options,
+ * with no terminating END tag is required.
+ *
+ * To be valid, the top-level sequence of options should be terminated by an
+ * END tag. The buffer should be padded with the PAD byte.
+ *
+ * When stored to NVRAM, the DHCP option format buffer is preceded by a
+ * checksum octet. The full buffer (including after the END tag) contributes
+ * to the checksum, hence the need to fill the buffer to the end with PAD.
+ */
+
+#define EFX_DHCP_END ((uint8_t)0xff)
+#define EFX_DHCP_PAD ((uint8_t)0)
+
+#define EFX_DHCP_ENCAP_OPT(encapsulator, encapsulated) \
+ (uint16_t)(((encapsulator) << 8) | (encapsulated))
+
+extern __checkReturn uint8_t
+efx_dhcp_csum(
+ __in_bcount(size) uint8_t const *data,
+ __in size_t size);
+
+extern __checkReturn efx_rc_t
+efx_dhcp_verify(
+ __in_bcount(size) uint8_t const *data,
+ __in size_t size,
+ __out_opt size_t *usedp);
+
+extern __checkReturn efx_rc_t
+efx_dhcp_find_tag(
+ __in_bcount(buffer_length) uint8_t *bufferp,
+ __in size_t buffer_length,
+ __in uint16_t opt,
+ __deref_out uint8_t **valuepp,
+ __out size_t *value_lengthp);
+
+extern __checkReturn efx_rc_t
+efx_dhcp_find_end(
+ __in_bcount(buffer_length) uint8_t *bufferp,
+ __in size_t buffer_length,
+ __deref_out uint8_t **endpp);
+
+
+extern __checkReturn efx_rc_t
+efx_dhcp_delete_tag(
+ __inout_bcount(buffer_length) uint8_t *bufferp,
+ __in size_t buffer_length,
+ __in uint16_t opt);
+
+extern __checkReturn efx_rc_t
+efx_dhcp_add_tag(
+ __inout_bcount(buffer_length) uint8_t *bufferp,
+ __in size_t buffer_length,
+ __in uint16_t opt,
+ __in_bcount_opt(value_length) uint8_t *valuep,
+ __in size_t value_length);
+
+extern __checkReturn efx_rc_t
+efx_dhcp_update_tag(
+ __inout_bcount(buffer_length) uint8_t *bufferp,
+ __in size_t buffer_length,
+ __in uint16_t opt,
+ __in uint8_t *value_locationp,
+ __in_bcount_opt(value_length) uint8_t *valuep,
+ __in size_t value_length);
+
+
#endif /* EFSYS_OPT_BOOTCFG */
#if EFSYS_OPT_IMAGE_LAYOUT
@@ -1689,7 +1862,8 @@ efx_check_reflash_image(
extern __checkReturn efx_rc_t
efx_build_signed_image_write_buffer(
- __out uint8_t *bufferp,
+ __out_bcount(buffer_size)
+ uint8_t *bufferp,
__in uint32_t buffer_size,
__in efx_image_info_t *infop,
__out efx_image_header_t **headerpp);
@@ -2122,7 +2296,7 @@ typedef enum efx_rx_hash_alg_e {
* - a combination of legacy flags
* - a combination of EFX_RX_HASH() flags
*/
-typedef unsigned int efx_rx_hash_type_t;
+typedef uint32_t efx_rx_hash_type_t;
typedef enum efx_rx_hash_support_e {
EFX_RX_HASH_UNAVAILABLE = 0, /* Hardware hash not inserted */
@@ -2223,7 +2397,8 @@ extern __checkReturn efx_rc_t
efx_rx_scale_hash_flags_get(
__in efx_nic_t *enp,
__in efx_rx_hash_alg_t hash_alg,
- __inout_ecount(EFX_RX_HASH_NFLAGS) unsigned int *flags,
+ __out_ecount_part(max_nflags, *nflagsp) unsigned int *flagsp,
+ __in unsigned int max_nflags,
__out unsigned int *nflagsp);
extern __checkReturn efx_rc_t
@@ -2813,9 +2988,23 @@ efx_filter_spec_set_encap_type(
__in efx_filter_inner_frame_match_t inner_frame_match);
extern __checkReturn efx_rc_t
-efx_filter_spec_set_vxlan_full(
+efx_filter_spec_set_vxlan(
+ __inout efx_filter_spec_t *spec,
+ __in const uint8_t *vni,
+ __in const uint8_t *inner_addr,
+ __in const uint8_t *outer_addr);
+
+extern __checkReturn efx_rc_t
+efx_filter_spec_set_geneve(
+ __inout efx_filter_spec_t *spec,
+ __in const uint8_t *vni,
+ __in const uint8_t *inner_addr,
+ __in const uint8_t *outer_addr);
+
+extern __checkReturn efx_rc_t
+efx_filter_spec_set_nvgre(
__inout efx_filter_spec_t *spec,
- __in const uint8_t *vxlan_id,
+ __in const uint8_t *vsid,
__in const uint8_t *inner_addr,
__in const uint8_t *outer_addr);
@@ -3057,6 +3246,32 @@ efx_nic_set_fw_subvariant(
#endif /* EFSYS_OPT_FW_SUBVARIANT_AWARE */
+typedef enum efx_phy_fec_type_e {
+ EFX_PHY_FEC_NONE = 0,
+ EFX_PHY_FEC_BASER,
+ EFX_PHY_FEC_RS
+} efx_phy_fec_type_t;
+
+extern __checkReturn efx_rc_t
+efx_phy_fec_type_get(
+ __in efx_nic_t *enp,
+ __out efx_phy_fec_type_t *typep);
+
+typedef struct efx_phy_link_state_s {
+ uint32_t epls_adv_cap_mask;
+ uint32_t epls_lp_cap_mask;
+ uint32_t epls_ld_cap_mask;
+ unsigned int epls_fcntl;
+ efx_phy_fec_type_t epls_fec;
+ efx_link_mode_t epls_link_mode;
+} efx_phy_link_state_t;
+
+extern __checkReturn efx_rc_t
+efx_phy_link_state_get(
+ __in efx_nic_t *enp,
+ __out efx_phy_link_state_t *eplsp);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/drivers/net/sfc/base/efx_annote.h b/drivers/net/sfc/base/efx_annote.h
new file mode 100644
index 00000000..607b43c7
--- /dev/null
+++ b/drivers/net/sfc/base/efx_annote.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2018 Solarflare Communications Inc.
+ * All rights reserved.
+ */
+
+#ifndef _SYS_EFX_ANNOTE_H
+#define _SYS_EFX_ANNOTE_H
+
+#if defined(_WIN32) || defined(_WIN64)
+#define EFX_HAVE_WINDOWS_ANNOTATIONS 1
+#else
+#define EFX_HAVE_WINDOWS_ANNOTATIONS 0
+#endif /* defined(_WIN32) || defined(_WIN64) */
+
+#if defined(__sun)
+#define EFX_HAVE_SOLARIS_ANNOTATIONS 1
+#else
+#define EFX_HAVE_SOLARIS_ANNOTATIONS 0
+#endif /* defined(__sun) */
+
+#if !EFX_HAVE_WINDOWS_ANNOTATIONS
+
+/* Ignore Windows SAL annotations on other platforms */
+#define __in
+#define __in_opt
+#define __in_ecount(_n)
+#define __in_ecount_opt(_n)
+#define __in_bcount(_n)
+#define __in_bcount_opt(_n)
+
+#define __out
+#define __out_opt
+#define __out_ecount(_n)
+#define __out_ecount_opt(_n)
+#define __out_ecount_part(_n, _l)
+#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
+#define __deref_inout
+
+#define __inout
+#define __inout_opt
+#define __inout_ecount(_n)
+#define __inout_ecount_opt(_n)
+#define __inout_bcount(_n)
+#define __inout_bcount_opt(_n)
+#define __inout_bcount_full_opt(_n)
+
+#define __deref_out_bcount_opt(n)
+
+#define __checkReturn
+#define __success(_x)
+
+#define __drv_when(_p, _c)
+
+#endif /* !EFX_HAVE_WINDOWS_ANNOTATIONS */
+
+#if !EFX_HAVE_SOLARIS_ANNOTATIONS
+
+#if EFX_HAVE_WINDOWS_ANNOTATIONS
+
+/*
+ * Support some SunOS/Solaris style _NOTE() annotations
+ *
+ * At present with the facilities provided in the WDL and the SAL we can only
+ * easily act upon _NOTE(ARGUNUSED(arglist)) annotations.
+ *
+ * Intermediate macros to expand individual _NOTE annotation types into
+ * something the WDK or SAL can understand. They shouldn't be used directly,
+ * for example EFX_NOTE_ARGUNUSED() is only used as an intermediate step on the
+ * transformation of _NOTE(ARGUNSED(arg1, arg2)) into
+ * UNREFERENCED_PARAMETER((arg1, arg2));
+ */
+#define EFX_NOTE_ALIGNMENT(_fname, _n)
+#define EFX_NOTE_ARGUNUSED(...) UNREFERENCED_PARAMETER((__VA_ARGS__));
+#define EFX_NOTE_CONSTANTCONDITION
+#define EFX_NOTE_CONSTCOND
+#define EFX_NOTE_EMPTY
+#define EFX_NOTE_FALLTHROUGH
+#define EFX_NOTE_FALLTHRU
+#define EFX_NOTE_LINTED(_msg)
+#define EFX_NOTE_NOTREACHED
+#define EFX_NOTE_PRINTFLIKE(_n)
+#define EFX_NOTE_SCANFLIKE(_n)
+#define EFX_NOTE_VARARGS(_n)
+
+#define _NOTE(_annotation) EFX_NOTE_ ## _annotation
+
+#else
+
+/* Ignore Solaris annotations on other platforms */
+
+#define _NOTE(_annotation)
+
+#endif /* EFX_HAVE_WINDOWS_ANNOTATIONS */
+
+#endif /* !EFX_HAVE_SOLARIS_ANNOTATIONS */
+
+#endif /* _SYS_EFX_ANNOTE_H */
diff --git a/drivers/net/sfc/base/efx_bootcfg.c b/drivers/net/sfc/base/efx_bootcfg.c
index 715e18e8..3b0401e8 100644
--- a/drivers/net/sfc/base/efx_bootcfg.c
+++ b/drivers/net/sfc/base/efx_bootcfg.c
@@ -19,8 +19,33 @@
#define BOOTCFG_PER_PF 0x800
#define BOOTCFG_PF_COUNT 16
-#define DHCP_END ((uint8_t)0xff)
-#define DHCP_PAD ((uint8_t)0)
+#define DHCP_OPT_HAS_VALUE(opt) \
+ (((opt) > EFX_DHCP_PAD) && ((opt) < EFX_DHCP_END))
+
+#define DHCP_MAX_VALUE 255
+
+#define DHCP_ENCAPSULATOR(encap_opt) ((encap_opt) >> 8)
+#define DHCP_ENCAPSULATED(encap_opt) ((encap_opt) & 0xff)
+#define DHCP_IS_ENCAP_OPT(opt) DHCP_OPT_HAS_VALUE(DHCP_ENCAPSULATOR(opt))
+
+typedef struct efx_dhcp_tag_hdr_s {
+ uint8_t tag;
+ uint8_t length;
+} efx_dhcp_tag_hdr_t;
+
+/*
+ * Length calculations for tags with value field. PAD and END
+ * have a fixed length of 1, with no length or value field.
+ */
+#define DHCP_FULL_TAG_LENGTH(hdr) \
+ (sizeof (efx_dhcp_tag_hdr_t) + (hdr)->length)
+
+#define DHCP_NEXT_TAG(hdr) \
+ ((efx_dhcp_tag_hdr_t *)(((uint8_t *)(hdr)) + \
+ DHCP_FULL_TAG_LENGTH((hdr))))
+
+#define DHCP_CALC_TAG_LENGTH(payload_len) \
+ ((payload_len) + sizeof (efx_dhcp_tag_hdr_t))
/* Report the layout of bootcfg sectors in NVRAM partition. */
@@ -110,14 +135,11 @@ fail1:
}
-static __checkReturn uint8_t
-efx_bootcfg_csum(
- __in efx_nic_t *enp,
+ __checkReturn uint8_t
+efx_dhcp_csum(
__in_bcount(size) uint8_t const *data,
__in size_t size)
{
- _NOTE(ARGUNUSED(enp))
-
unsigned int pos;
uint8_t checksum = 0;
@@ -126,9 +148,8 @@ efx_bootcfg_csum(
return (checksum);
}
-static __checkReturn efx_rc_t
-efx_bootcfg_verify(
- __in efx_nic_t *enp,
+ __checkReturn efx_rc_t
+efx_dhcp_verify(
__in_bcount(size) uint8_t const *data,
__in size_t size,
__out_opt size_t *usedp)
@@ -144,12 +165,12 @@ efx_bootcfg_verify(
/* Consume tag */
tag = data[offset];
- if (tag == DHCP_END) {
+ if (tag == EFX_DHCP_END) {
offset++;
used = offset;
break;
}
- if (tag == DHCP_PAD) {
+ if (tag == EFX_DHCP_PAD) {
offset++;
continue;
}
@@ -171,8 +192,8 @@ efx_bootcfg_verify(
used = offset;
}
- /* Checksum the entire sector, including bytes after any DHCP_END */
- if (efx_bootcfg_csum(enp, data, size) != 0) {
+ /* Checksum the entire sector, including bytes after any EFX_DHCP_END */
+ if (efx_dhcp_csum(data, size) != 0) {
rc = EINVAL;
goto fail3;
}
@@ -193,6 +214,516 @@ fail1:
}
/*
+ * Walk the entire tag set looking for option. The sought option may be
+ * encapsulated. ENOENT indicates the walk completed without finding the
+ * option. If we run out of buffer during the walk the function will return
+ * ENOSPC.
+ */
+static efx_rc_t
+efx_dhcp_walk_tags(
+ __deref_inout uint8_t **tagpp,
+ __inout size_t *buffer_sizep,
+ __in uint16_t opt)
+{
+ efx_rc_t rc = 0;
+ boolean_t is_encap = B_FALSE;
+
+ if (DHCP_IS_ENCAP_OPT(opt)) {
+ /*
+ * Look for the encapsulator and, if found, limit ourselves
+ * to its payload. If it's not found then the entire tag
+ * cannot be found, so the encapsulated opt search is
+ * skipped.
+ */
+ rc = efx_dhcp_walk_tags(tagpp, buffer_sizep,
+ DHCP_ENCAPSULATOR(opt));
+ if (rc == 0) {
+ *buffer_sizep = ((efx_dhcp_tag_hdr_t *)*tagpp)->length;
+ (*tagpp) += sizeof (efx_dhcp_tag_hdr_t);
+ }
+ opt = DHCP_ENCAPSULATED(opt);
+ is_encap = B_TRUE;
+ }
+
+ EFSYS_ASSERT(!DHCP_IS_ENCAP_OPT(opt));
+
+ while (rc == 0) {
+ size_t size;
+
+ if (*buffer_sizep == 0) {
+ rc = ENOSPC;
+ goto fail1;
+ }
+
+ if (DHCP_ENCAPSULATED(**tagpp) == opt)
+ break;
+
+ if ((**tagpp) == EFX_DHCP_END) {
+ rc = ENOENT;
+ break;
+ } else if ((**tagpp) == EFX_DHCP_PAD) {
+ size = 1;
+ } else {
+ if (*buffer_sizep < sizeof (efx_dhcp_tag_hdr_t)) {
+ rc = ENOSPC;
+ goto fail2;
+ }
+
+ size =
+ DHCP_FULL_TAG_LENGTH((efx_dhcp_tag_hdr_t *)*tagpp);
+ }
+
+ if (size > *buffer_sizep) {
+ rc = ENOSPC;
+ goto fail3;
+ }
+
+ (*tagpp) += size;
+ (*buffer_sizep) -= size;
+
+ if ((*buffer_sizep == 0) && is_encap) {
+ /* Search within encapulator tag finished */
+ rc = ENOENT;
+ break;
+ }
+ }
+
+ /*
+ * Returns 0 if found otherwise ENOENT indicating search finished
+ * correctly
+ */
+ return (rc);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+/*
+ * Locate value buffer for option in the given buffer.
+ * Returns 0 if found, ENOENT indicating search finished
+ * correctly, otherwise search failed before completion.
+ */
+ __checkReturn efx_rc_t
+efx_dhcp_find_tag(
+ __in_bcount(buffer_length) uint8_t *bufferp,
+ __in size_t buffer_length,
+ __in uint16_t opt,
+ __deref_out uint8_t **valuepp,
+ __out size_t *value_lengthp)
+{
+ efx_rc_t rc;
+ uint8_t *tagp = bufferp;
+ size_t len = buffer_length;
+
+ rc = efx_dhcp_walk_tags(&tagp, &len, opt);
+ if (rc == 0) {
+ efx_dhcp_tag_hdr_t *hdrp;
+
+ hdrp = (efx_dhcp_tag_hdr_t *)tagp;
+ *valuepp = (uint8_t *)(&hdrp[1]);
+ *value_lengthp = hdrp->length;
+ } else if (rc != ENOENT) {
+ goto fail1;
+ }
+
+ return (rc);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+/*
+ * Locate the end tag in the given buffer.
+ * Returns 0 if found, ENOENT indicating search finished
+ * correctly but end tag was not found; otherwise search
+ * failed before completion.
+ */
+ __checkReturn efx_rc_t
+efx_dhcp_find_end(
+ __in_bcount(buffer_length) uint8_t *bufferp,
+ __in size_t buffer_length,
+ __deref_out uint8_t **endpp)
+{
+ efx_rc_t rc;
+ uint8_t *endp = bufferp;
+ size_t len = buffer_length;
+
+ rc = efx_dhcp_walk_tags(&endp, &len, EFX_DHCP_END);
+ if (rc == 0)
+ *endpp = endp;
+ else if (rc != ENOENT)
+ goto fail1;
+
+ return (rc);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+
+/*
+ * Delete the given tag from anywhere in the buffer. Copes with
+ * encapsulated tags, and updates or deletes the encapsulating opt as
+ * necessary.
+ */
+ __checkReturn efx_rc_t
+efx_dhcp_delete_tag(
+ __inout_bcount(buffer_length) uint8_t *bufferp,
+ __in size_t buffer_length,
+ __in uint16_t opt)
+{
+ efx_rc_t rc;
+ efx_dhcp_tag_hdr_t *hdrp;
+ size_t len;
+ uint8_t *startp;
+ uint8_t *endp;
+
+ len = buffer_length;
+ startp = bufferp;
+
+ if (!DHCP_OPT_HAS_VALUE(DHCP_ENCAPSULATED(opt))) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ rc = efx_dhcp_walk_tags(&startp, &len, opt);
+ if (rc != 0)
+ goto fail1;
+
+ hdrp = (efx_dhcp_tag_hdr_t *)startp;
+
+ if (DHCP_IS_ENCAP_OPT(opt)) {
+ uint8_t tag_length = DHCP_FULL_TAG_LENGTH(hdrp);
+ uint8_t *encapp = bufferp;
+ efx_dhcp_tag_hdr_t *encap_hdrp;
+
+ len = buffer_length;
+ rc = efx_dhcp_walk_tags(&encapp, &len,
+ DHCP_ENCAPSULATOR(opt));
+ if (rc != 0)
+ goto fail2;
+
+ encap_hdrp = (efx_dhcp_tag_hdr_t *)encapp;
+ if (encap_hdrp->length > tag_length) {
+ encap_hdrp->length = (uint8_t)(
+ (size_t)encap_hdrp->length - tag_length);
+ } else {
+ /* delete the encapsulating tag */
+ hdrp = encap_hdrp;
+ }
+ }
+
+ startp = (uint8_t *)hdrp;
+ endp = (uint8_t *)DHCP_NEXT_TAG(hdrp);
+
+ if (startp < bufferp) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ if (endp > &bufferp[buffer_length]) {
+ rc = EINVAL;
+ goto fail4;
+ }
+
+ memmove(startp, endp,
+ buffer_length - (endp - bufferp));
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+/*
+ * Write the tag header into write_pointp and optionally copies the payload
+ * into the space following.
+ */
+static void
+efx_dhcp_write_tag(
+ __in uint8_t *write_pointp,
+ __in uint16_t opt,
+ __in_bcount_opt(value_length)
+ uint8_t *valuep,
+ __in size_t value_length)
+{
+ efx_dhcp_tag_hdr_t *hdrp = (efx_dhcp_tag_hdr_t *)write_pointp;
+ hdrp->tag = DHCP_ENCAPSULATED(opt);
+ hdrp->length = (uint8_t)value_length;
+ if ((value_length > 0) && (valuep != NULL))
+ memcpy(&hdrp[1], valuep, value_length);
+}
+
+/*
+ * Add the given tag to the end of the buffer. Copes with creating an
+ * encapsulated tag, and updates or creates the encapsulating opt as
+ * necessary.
+ */
+ __checkReturn efx_rc_t
+efx_dhcp_add_tag(
+ __inout_bcount(buffer_length) uint8_t *bufferp,
+ __in size_t buffer_length,
+ __in uint16_t opt,
+ __in_bcount_opt(value_length) uint8_t *valuep,
+ __in size_t value_length)
+{
+ efx_rc_t rc;
+ efx_dhcp_tag_hdr_t *encap_hdrp = NULL;
+ uint8_t *insert_pointp = NULL;
+ uint8_t *endp;
+ size_t available_space;
+ size_t added_length;
+ size_t search_size;
+ uint8_t *searchp;
+
+ if (!DHCP_OPT_HAS_VALUE(DHCP_ENCAPSULATED(opt))) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ if (value_length > DHCP_MAX_VALUE) {
+ rc = EINVAL;
+ goto fail2;
+ }
+
+ if ((value_length > 0) && (valuep == NULL)) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ endp = bufferp;
+ available_space = buffer_length;
+ rc = efx_dhcp_walk_tags(&endp, &available_space, EFX_DHCP_END);
+ if (rc != 0)
+ goto fail4;
+
+ searchp = bufferp;
+ search_size = buffer_length;
+ if (DHCP_IS_ENCAP_OPT(opt)) {
+ rc = efx_dhcp_walk_tags(&searchp, &search_size,
+ DHCP_ENCAPSULATOR(opt));
+ if (rc == 0) {
+ encap_hdrp = (efx_dhcp_tag_hdr_t *)searchp;
+
+ /* Check encapsulated tag is not present */
+ search_size = encap_hdrp->length;
+ rc = efx_dhcp_walk_tags(&searchp, &search_size,
+ opt);
+ if (rc != ENOENT) {
+ rc = EINVAL;
+ goto fail5;
+ }
+
+ /* Check encapsulator will not overflow */
+ if (((size_t)encap_hdrp->length +
+ DHCP_CALC_TAG_LENGTH(value_length)) >
+ DHCP_MAX_VALUE) {
+ rc = E2BIG;
+ goto fail6;
+ }
+
+ /* Insert at start of existing encapsulator */
+ insert_pointp = (uint8_t *)&encap_hdrp[1];
+ opt = DHCP_ENCAPSULATED(opt);
+ } else if (rc == ENOENT) {
+ encap_hdrp = NULL;
+ } else {
+ goto fail7;
+ }
+ } else {
+ /* Check unencapsulated tag is not present */
+ rc = efx_dhcp_walk_tags(&searchp, &search_size,
+ opt);
+ if (rc != ENOENT) {
+ rc = EINVAL;
+ goto fail8;
+ }
+ }
+
+ if (insert_pointp == NULL) {
+ /* Insert at end of existing tags */
+ insert_pointp = endp;
+ }
+
+ /* Includes the new encapsulator tag hdr if required */
+ added_length = DHCP_CALC_TAG_LENGTH(value_length) +
+ (DHCP_IS_ENCAP_OPT(opt) ? sizeof (efx_dhcp_tag_hdr_t) : 0);
+
+ if (available_space <= added_length) {
+ rc = ENOMEM;
+ goto fail9;
+ }
+
+ memmove(insert_pointp + added_length, insert_pointp,
+ available_space - added_length);
+
+ if (DHCP_IS_ENCAP_OPT(opt)) {
+ /* Create new encapsulator header */
+ added_length -= sizeof (efx_dhcp_tag_hdr_t);
+ efx_dhcp_write_tag(insert_pointp,
+ DHCP_ENCAPSULATOR(opt), NULL, added_length);
+ insert_pointp += sizeof (efx_dhcp_tag_hdr_t);
+ } else if (encap_hdrp)
+ /* Modify existing encapsulator header */
+ encap_hdrp->length +=
+ ((uint8_t)DHCP_CALC_TAG_LENGTH(value_length));
+
+ efx_dhcp_write_tag(insert_pointp, opt, valuep, value_length);
+
+ return (0);
+
+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);
+}
+
+/*
+ * Update an existing tag to the new value. Copes with encapsulated
+ * tags, and updates the encapsulating opt as necessary.
+ */
+ __checkReturn efx_rc_t
+efx_dhcp_update_tag(
+ __inout_bcount(buffer_length) uint8_t *bufferp,
+ __in size_t buffer_length,
+ __in uint16_t opt,
+ __in uint8_t *value_locationp,
+ __in_bcount_opt(value_length) uint8_t *valuep,
+ __in size_t value_length)
+{
+ efx_rc_t rc;
+ uint8_t *write_pointp = value_locationp - sizeof (efx_dhcp_tag_hdr_t);
+ efx_dhcp_tag_hdr_t *hdrp = (efx_dhcp_tag_hdr_t *)write_pointp;
+ efx_dhcp_tag_hdr_t *encap_hdrp = NULL;
+ size_t old_length;
+
+ if (!DHCP_OPT_HAS_VALUE(DHCP_ENCAPSULATED(opt))) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ if (value_length > DHCP_MAX_VALUE) {
+ rc = EINVAL;
+ goto fail2;
+ }
+
+ if ((value_length > 0) && (valuep == NULL)) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ old_length = hdrp->length;
+
+ if (old_length < value_length) {
+ uint8_t *endp = bufferp;
+ size_t available_space = buffer_length;
+
+ rc = efx_dhcp_walk_tags(&endp, &available_space,
+ EFX_DHCP_END);
+ if (rc != 0)
+ goto fail4;
+
+ if (available_space < (value_length - old_length)) {
+ rc = EINVAL;
+ goto fail5;
+ }
+ }
+
+ if (DHCP_IS_ENCAP_OPT(opt)) {
+ uint8_t *encapp = bufferp;
+ size_t following_encap = buffer_length;
+ size_t new_length;
+
+ rc = efx_dhcp_walk_tags(&encapp, &following_encap,
+ DHCP_ENCAPSULATOR(opt));
+ if (rc != 0)
+ goto fail6;
+
+ encap_hdrp = (efx_dhcp_tag_hdr_t *)encapp;
+
+ new_length = ((size_t)encap_hdrp->length +
+ value_length - old_length);
+ /* Check encapsulator will not overflow */
+ if (new_length > DHCP_MAX_VALUE) {
+ rc = E2BIG;
+ goto fail7;
+ }
+
+ encap_hdrp->length = (uint8_t)new_length;
+ }
+
+ /*
+ * Move the following data up/down to accomodate the new payload
+ * length.
+ */
+ if (old_length != value_length) {
+ uint8_t *destp = (uint8_t *)DHCP_NEXT_TAG(hdrp) +
+ value_length - old_length;
+ size_t count = &bufferp[buffer_length] -
+ (uint8_t *)DHCP_NEXT_TAG(hdrp);
+
+ memmove(destp, DHCP_NEXT_TAG(hdrp), count);
+ }
+
+ EFSYS_ASSERT(hdrp->tag == DHCP_ENCAPSULATED(opt));
+ efx_dhcp_write_tag(write_pointp, opt, valuep, value_length);
+
+ return (0);
+
+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);
+}
+
+
+/*
* Copy bootcfg sector data to a target buffer which may differ in size.
* Optionally corrects format errors in source buffer.
*/
@@ -206,17 +737,19 @@ efx_bootcfg_copy_sector(
__in size_t data_size,
__in boolean_t handle_format_errors)
{
+ _NOTE(ARGUNUSED(enp))
+
size_t used_bytes;
efx_rc_t rc;
- /* Minimum buffer is checksum byte and DHCP_END terminator */
+ /* Minimum buffer is checksum byte and EFX_DHCP_END terminator */
if (data_size < 2) {
rc = ENOSPC;
goto fail1;
}
/* Verify that the area is correctly formatted and checksummed */
- rc = efx_bootcfg_verify(enp, sector, sector_length,
+ rc = efx_dhcp_verify(sector, sector_length,
&used_bytes);
if (!handle_format_errors) {
@@ -224,8 +757,8 @@ efx_bootcfg_copy_sector(
goto fail2;
if ((used_bytes < 2) ||
- (sector[used_bytes - 1] != DHCP_END)) {
- /* Block too short, or DHCP_END missing */
+ (sector[used_bytes - 1] != EFX_DHCP_END)) {
+ /* Block too short, or EFX_DHCP_END missing */
rc = ENOENT;
goto fail3;
}
@@ -234,24 +767,24 @@ efx_bootcfg_copy_sector(
/* Synthesize empty format on verification failure */
if (rc != 0 || used_bytes == 0) {
sector[0] = 0;
- sector[1] = DHCP_END;
+ sector[1] = EFX_DHCP_END;
used_bytes = 2;
}
- EFSYS_ASSERT(used_bytes >= 2); /* checksum and DHCP_END */
+ EFSYS_ASSERT(used_bytes >= 2); /* checksum and EFX_DHCP_END */
EFSYS_ASSERT(used_bytes <= sector_length);
EFSYS_ASSERT(sector_length >= 2);
/*
- * Legacy bootcfg sectors don't terminate with a DHCP_END character.
- * Modify the returned payload so it does.
+ * Legacy bootcfg sectors don't terminate with an EFX_DHCP_END
+ * character. Modify the returned payload so it does.
* Reinitialise the sector if there isn't room for the character.
*/
- if (sector[used_bytes - 1] != DHCP_END) {
+ if (sector[used_bytes - 1] != EFX_DHCP_END) {
if (used_bytes >= sector_length) {
sector[0] = 0;
used_bytes = 1;
}
- sector[used_bytes] = DHCP_END;
+ sector[used_bytes] = EFX_DHCP_END;
++used_bytes;
}
@@ -274,10 +807,11 @@ efx_bootcfg_copy_sector(
(void) memset(data + used_bytes, 0, data_size - used_bytes);
/*
- * The checksum includes trailing data after any DHCP_END character,
- * which we've just modified (by truncation or appending DHCP_END).
+ * The checksum includes trailing data after any EFX_DHCP_END
+ * character, which we've just modified (by truncation or appending
+ * EFX_DHCP_END).
*/
- data[0] -= efx_bootcfg_csum(enp, data, data_size);
+ data[0] -= efx_dhcp_csum(data, data_size);
return (0);
@@ -307,7 +841,7 @@ efx_bootcfg_read(
efx_rc_t rc;
uint32_t sector_number;
- /* Minimum buffer is checksum byte and DHCP_END terminator */
+ /* Minimum buffer is checksum byte and EFX_DHCP_END terminator */
if (size < 2) {
rc = ENOSPC;
goto fail1;
@@ -343,10 +877,10 @@ efx_bootcfg_read(
}
/*
- * We need to read the entire BOOTCFG sector to ensure we read all the
- * tags, because legacy bootcfg sectors are not guaranteed to end with
- * a DHCP_END character. If the user hasn't supplied a sufficiently
- * large buffer then use our own buffer.
+ * We need to read the entire BOOTCFG sector to ensure we read all
+ * tags, because legacy bootcfg sectors are not guaranteed to end
+ * with an EFX_DHCP_END character. If the user hasn't supplied a
+ * sufficiently large buffer then use our own buffer.
*/
if (sector_length > size) {
EFSYS_KMEM_ALLOC(enp->en_esip, sector_length, payload);
@@ -370,28 +904,29 @@ efx_bootcfg_read(
goto fail9;
/* Verify that the area is correctly formatted and checksummed */
- rc = efx_bootcfg_verify(enp, payload, sector_length,
+ rc = efx_dhcp_verify(payload, sector_length,
&used_bytes);
if (rc != 0 || used_bytes == 0) {
payload[0] = 0;
- payload[1] = DHCP_END;
+ payload[1] = EFX_DHCP_END;
used_bytes = 2;
}
- EFSYS_ASSERT(used_bytes >= 2); /* checksum and DHCP_END */
+ EFSYS_ASSERT(used_bytes >= 2); /* checksum and EFX_DHCP_END */
EFSYS_ASSERT(used_bytes <= sector_length);
/*
- * Legacy bootcfg sectors don't terminate with a DHCP_END character.
- * Modify the returned payload so it does. BOOTCFG_MAX_SIZE is by
- * definition large enough for any valid (per-port) bootcfg sector,
- * so reinitialise the sector if there isn't room for the character.
+ * Legacy bootcfg sectors don't terminate with an EFX_DHCP_END
+ * character. Modify the returned payload so it does.
+ * BOOTCFG_MAX_SIZE is by definition large enough for any valid
+ * (per-port) bootcfg sector, so reinitialise the sector if there
+ * isn't room for the character.
*/
- if (payload[used_bytes - 1] != DHCP_END) {
+ if (payload[used_bytes - 1] != EFX_DHCP_END) {
if (used_bytes >= sector_length)
used_bytes = 1;
- payload[used_bytes] = DHCP_END;
+ payload[used_bytes] = EFX_DHCP_END;
++used_bytes;
}
@@ -417,10 +952,10 @@ efx_bootcfg_read(
(void) memset(data + used_bytes, 0, size - used_bytes);
/*
- * The checksum includes trailing data after any DHCP_END character,
- * which we've just modified (by truncation or appending DHCP_END).
+ * The checksum includes trailing data after any EFX_DHCP_END character,
+ * which we've just modified (by truncation or appending EFX_DHCP_END).
*/
- data[0] -= efx_bootcfg_csum(enp, data, size);
+ data[0] -= efx_dhcp_csum(data, size);
return (0);
@@ -490,12 +1025,16 @@ efx_bootcfg_write(
goto fail3;
}
- if ((rc = efx_bootcfg_verify(enp, data, size, &used_bytes)) != 0)
+ if ((rc = efx_dhcp_verify(data, size, &used_bytes)) != 0)
goto fail4;
- /* The caller *must* terminate their block with a DHCP_END character */
- if ((used_bytes < 2) || ((uint8_t)data[used_bytes - 1] != DHCP_END)) {
- /* Block too short or DHCP_END missing */
+ /*
+ * The caller *must* terminate their block with a EFX_DHCP_END
+ * character
+ */
+ if ((used_bytes < 2) || ((uint8_t)data[used_bytes - 1] !=
+ EFX_DHCP_END)) {
+ /* Block too short or EFX_DHCP_END missing */
rc = ENOENT;
goto fail5;
}
@@ -528,13 +1067,13 @@ efx_bootcfg_write(
goto fail9;
/*
- * Insert the BOOTCFG sector into the partition, Zero out all data after
- * the DHCP_END tag, and adjust the checksum.
+ * Insert the BOOTCFG sector into the partition, Zero out all data
+ * after the EFX_DHCP_END tag, and adjust the checksum.
*/
(void) memset(partn_data + sector_offset, 0x0, sector_length);
(void) memcpy(partn_data + sector_offset, data, used_bytes);
- checksum = efx_bootcfg_csum(enp, data, used_bytes);
+ checksum = efx_dhcp_csum(data, used_bytes);
partn_data[sector_offset] -= checksum;
if ((rc = efx_nvram_erase(enp, EFX_NVRAM_BOOTROM_CFG)) != 0)
diff --git a/drivers/net/sfc/base/efx_filter.c b/drivers/net/sfc/base/efx_filter.c
index 412298ac..a7523b38 100644
--- a/drivers/net/sfc/base/efx_filter.c
+++ b/drivers/net/sfc/base/efx_filter.c
@@ -490,27 +490,42 @@ fail1:
}
/*
- * Specify inner and outer Ethernet address and VXLAN ID in filter
+ * Specify inner and outer Ethernet address and VNI or VSID in tunnel filter
* specification.
*/
- __checkReturn efx_rc_t
-efx_filter_spec_set_vxlan_full(
- __inout efx_filter_spec_t *spec,
- __in const uint8_t *vxlan_id,
+static __checkReturn efx_rc_t
+efx_filter_spec_set_tunnel(
+ __inout efx_filter_spec_t *spec,
+ __in efx_tunnel_protocol_t encap_type,
+ __in const uint8_t *vni_or_vsid,
__in const uint8_t *inner_addr,
__in const uint8_t *outer_addr)
{
+ efx_rc_t rc;
+
EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT3P(vxlan_id, !=, NULL);
+ EFSYS_ASSERT3P(vni_or_vsid, !=, NULL);
EFSYS_ASSERT3P(inner_addr, !=, NULL);
EFSYS_ASSERT3P(outer_addr, !=, NULL);
- if ((inner_addr == NULL) && (outer_addr == NULL))
- return (EINVAL);
+ switch (encap_type) {
+ case EFX_TUNNEL_PROTOCOL_VXLAN:
+ case EFX_TUNNEL_PROTOCOL_GENEVE:
+ case EFX_TUNNEL_PROTOCOL_NVGRE:
+ break;
+ default:
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ if ((inner_addr == NULL) && (outer_addr == NULL)) {
+ rc = EINVAL;
+ goto fail2;
+ }
- if (vxlan_id != NULL) {
+ if (vni_or_vsid != NULL) {
spec->efs_match_flags |= EFX_FILTER_MATCH_VNI_OR_VSID;
- memcpy(spec->efs_vni_or_vsid, vxlan_id, EFX_VNI_OR_VSID_LEN);
+ memcpy(spec->efs_vni_or_vsid, vni_or_vsid, EFX_VNI_OR_VSID_LEN);
}
if (outer_addr != NULL) {
spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC;
@@ -520,10 +535,63 @@ efx_filter_spec_set_vxlan_full(
spec->efs_match_flags |= EFX_FILTER_MATCH_IFRM_LOC_MAC;
memcpy(spec->efs_ifrm_loc_mac, inner_addr, EFX_MAC_ADDR_LEN);
}
+
spec->efs_match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE;
- spec->efs_encap_type = EFX_TUNNEL_PROTOCOL_VXLAN;
+ spec->efs_encap_type = encap_type;
return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+/*
+ * Specify inner and outer Ethernet address and VNI in VXLAN filter
+ * specification.
+ */
+__checkReturn efx_rc_t
+efx_filter_spec_set_vxlan(
+ __inout efx_filter_spec_t *spec,
+ __in const uint8_t *vni,
+ __in const uint8_t *inner_addr,
+ __in const uint8_t *outer_addr)
+{
+ return efx_filter_spec_set_tunnel(spec, EFX_TUNNEL_PROTOCOL_VXLAN,
+ vni, inner_addr, outer_addr);
+}
+
+/*
+ * Specify inner and outer Ethernet address and VNI in Geneve filter
+ * specification.
+ */
+__checkReturn efx_rc_t
+efx_filter_spec_set_geneve(
+ __inout efx_filter_spec_t *spec,
+ __in const uint8_t *vni,
+ __in const uint8_t *inner_addr,
+ __in const uint8_t *outer_addr)
+{
+ return efx_filter_spec_set_tunnel(spec, EFX_TUNNEL_PROTOCOL_GENEVE,
+ vni, inner_addr, outer_addr);
+}
+
+/*
+ * Specify inner and outer Ethernet address and vsid in NVGRE filter
+ * specification.
+ */
+__checkReturn efx_rc_t
+efx_filter_spec_set_nvgre(
+ __inout efx_filter_spec_t *spec,
+ __in const uint8_t *vsid,
+ __in const uint8_t *inner_addr,
+ __in const uint8_t *outer_addr)
+{
+ return efx_filter_spec_set_tunnel(spec, EFX_TUNNEL_PROTOCOL_NVGRE,
+ vsid, inner_addr, outer_addr);
}
#if EFSYS_OPT_RX_SCALE
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index 548834f9..bad23f81 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -59,6 +59,7 @@ extern "C" {
#define EFX_RESET_PHY 0x00000001
#define EFX_RESET_RXQ_ERR 0x00000002
#define EFX_RESET_TXQ_ERR 0x00000004
+#define EFX_RESET_HW_UNAVAIL 0x00000008
typedef enum efx_mac_type_e {
EFX_MAC_INVALID = 0,
@@ -223,6 +224,7 @@ typedef struct efx_phy_ops_s {
efx_rc_t (*epo_reconfigure)(efx_nic_t *);
efx_rc_t (*epo_verify)(efx_nic_t *);
efx_rc_t (*epo_oui_get)(efx_nic_t *, uint32_t *);
+ efx_rc_t (*epo_link_state_get)(efx_nic_t *, efx_phy_link_state_t *);
#if EFSYS_OPT_PHY_STATS
efx_rc_t (*epo_stats_update)(efx_nic_t *, efsys_mem_t *,
uint32_t *);
@@ -317,6 +319,8 @@ typedef struct efx_mon_ops_s {
#if EFSYS_OPT_MON_STATS
efx_rc_t (*emo_stats_update)(efx_nic_t *, efsys_mem_t *,
efx_mon_stat_value_t *);
+ efx_rc_t (*emo_limits_update)(efx_nic_t *,
+ efx_mon_stat_limits_t *);
#endif /* EFSYS_OPT_MON_STATS */
} efx_mon_ops_t;
@@ -354,6 +358,8 @@ typedef struct efx_nic_ops_s {
efx_rc_t (*eno_get_vi_pool)(efx_nic_t *, uint32_t *);
efx_rc_t (*eno_get_bar_region)(efx_nic_t *, efx_nic_region_t,
uint32_t *, size_t *);
+ boolean_t (*eno_hw_unavailable)(efx_nic_t *);
+ void (*eno_set_hw_unavailable)(efx_nic_t *);
#if EFSYS_OPT_DIAG
efx_rc_t (*eno_register_test)(efx_nic_t *);
#endif /* EFSYS_OPT_DIAG */
@@ -507,7 +513,7 @@ typedef struct efx_nvram_ops_s {
uint32_t *, uint16_t *);
efx_rc_t (*envo_partn_set_version)(efx_nic_t *, uint32_t,
uint16_t *);
- efx_rc_t (*envo_buffer_validate)(efx_nic_t *, uint32_t,
+ efx_rc_t (*envo_buffer_validate)(uint32_t,
caddr_t, size_t);
} efx_nvram_ops_t;
#endif /* EFSYS_OPT_NVRAM */
@@ -583,7 +589,7 @@ efx_mcdi_nvram_write(
__in efx_nic_t *enp,
__in uint32_t partn,
__in uint32_t offset,
- __out_bcount(size) caddr_t data,
+ __in_bcount(size) caddr_t data,
__in size_t size);
__checkReturn efx_rc_t
diff --git a/drivers/net/sfc/base/efx_lic.c b/drivers/net/sfc/base/efx_lic.c
index 49c00347..4081aef1 100644
--- a/drivers/net/sfc/base/efx_lic.c
+++ b/drivers/net/sfc/base/efx_lic.c
@@ -301,12 +301,11 @@ 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_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN, 0);
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_FC;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
@@ -347,13 +346,12 @@ efx_mcdi_fc_license_get_key_stats(
__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_MCDI_DECLARE_BUF(payload, 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;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
@@ -663,8 +661,8 @@ efx_mcdi_licensed_app_state(
__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)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
+ MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN);
uint32_t app_state;
efx_rc_t rc;
@@ -676,7 +674,6 @@ efx_mcdi_licensed_app_state(
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;
@@ -722,12 +719,11 @@ efx_mcdi_licensing_update_licenses(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_LICENSING_IN_LEN];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN, 0);
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;
@@ -765,13 +761,12 @@ efx_mcdi_licensing_get_key_stats(
__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_MCDI_DECLARE_BUF(payload, 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;
@@ -829,13 +824,12 @@ 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_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN, 0);
efx_rc_t rc;
EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
(enp->en_family == EFX_FAMILY_MEDFORD2));
- (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;
@@ -866,14 +860,13 @@ efx_mcdi_licensing_v3_report_license(
__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_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN,
+ MC_CMD_LICENSING_V3_OUT_LEN);
efx_rc_t rc;
EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
(enp->en_family == EFX_FAMILY_MEDFORD2));
- (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;
@@ -930,15 +923,14 @@ efx_mcdi_licensing_v3_app_state(
__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)];
+ EFX_MCDI_DECLARE_BUF(payload, 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) ||
(enp->en_family == EFX_FAMILY_MEDFORD2));
- (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;
@@ -990,28 +982,15 @@ efx_mcdi_licensing_v3_get_id(
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_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
+ MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX);
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_LENMAX);
- (void) memset(bufferp, 0, req.emr_out_length);
- }
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX;
efx_mcdi_execute_quiet(enp, &req);
@@ -1029,19 +1008,10 @@ efx_mcdi_licensing_v3_get_id(
*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);
+ if (bufferp != NULL) {
+ memcpy(bufferp,
+ payload + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
+ MIN(buffer_size, *lengthp));
}
return (0);
@@ -1158,10 +1128,12 @@ efx_lic_v3_read_key(
__in size_t key_max_size,
__out uint32_t *lengthp)
{
+ uint32_t tag;
+
_NOTE(ARGUNUSED(enp))
return ef10_nvram_buffer_get_item(bufferp, buffer_size,
- offset, length, keyp, key_max_size, lengthp);
+ offset, length, &tag, keyp, key_max_size, lengthp);
}
__checkReturn efx_rc_t
@@ -1179,7 +1151,7 @@ efx_lic_v3_write_key(
EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX);
return ef10_nvram_buffer_insert_item(bufferp, buffer_size,
- offset, keyp, length, lengthp);
+ offset, TLV_TAG_LICENSE, keyp, length, lengthp);
}
__checkReturn efx_rc_t
@@ -1221,8 +1193,10 @@ efx_lic_v3_create_partition(
{
efx_rc_t rc;
+ _NOTE(ARGUNUSED(enp))
+
/* Construct empty partition */
- if ((rc = ef10_nvram_buffer_create(enp,
+ if ((rc = ef10_nvram_buffer_create(
NVRAM_PARTITION_TYPE_LICENSE,
bufferp, buffer_size)) != 0) {
rc = EFAULT;
@@ -1246,13 +1220,16 @@ efx_lic_v3_finish_partition(
{
efx_rc_t rc;
+ _NOTE(ARGUNUSED(enp))
+
if ((rc = ef10_nvram_buffer_finish(bufferp,
buffer_size)) != 0) {
goto fail1;
}
/* Validate completed partition */
- if ((rc = ef10_nvram_buffer_validate(enp, NVRAM_PARTITION_TYPE_LICENSE,
+ if ((rc = ef10_nvram_buffer_validate(
+ NVRAM_PARTITION_TYPE_LICENSE,
bufferp, buffer_size)) != 0) {
goto fail2;
}
diff --git a/drivers/net/sfc/base/efx_mcdi.c b/drivers/net/sfc/base/efx_mcdi.c
index d4ebcf26..c896aa0b 100644
--- a/drivers/net/sfc/base/efx_mcdi.c
+++ b/drivers/net/sfc/base/efx_mcdi.c
@@ -496,6 +496,12 @@ efx_mcdi_request_poll(
EFSYS_ASSERT(!emip->emi_ev_cpl);
emrp = emip->emi_pending_req;
+ /* Check if hardware is unavailable */
+ if (efx_nic_hw_unavailable(enp)) {
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ return (B_FALSE);
+ }
+
/* Check for reboot atomically w.r.t efx_mcdi_request_start */
if (emip->emi_poll_cnt++ == 0) {
if ((rc = efx_mcdi_poll_reboot(enp)) != 0) {
@@ -900,10 +906,10 @@ efx_mcdi_version(
__out_opt efx_mcdi_boot_t *statusp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MAX(MC_CMD_GET_VERSION_IN_LEN,
- MC_CMD_GET_VERSION_OUT_LEN),
- MAX(MC_CMD_GET_BOOT_STATUS_IN_LEN,
- MC_CMD_GET_BOOT_STATUS_OUT_LEN))];
+ EFX_MCDI_DECLARE_BUF(payload,
+ MAX(MC_CMD_GET_VERSION_IN_LEN, MC_CMD_GET_BOOT_STATUS_IN_LEN),
+ MAX(MC_CMD_GET_VERSION_OUT_LEN,
+ MC_CMD_GET_BOOT_STATUS_OUT_LEN));
efx_word_t *ver_words;
uint16_t version[4];
uint32_t build;
@@ -912,7 +918,6 @@ efx_mcdi_version(
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_VERSION;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_VERSION_IN_LEN;
@@ -1018,12 +1023,11 @@ efx_mcdi_get_capabilities(
__out_opt uint32_t *tso2ncp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN,
- MC_CMD_GET_CAPABILITIES_V2_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CAPABILITIES_IN_LEN,
+ MC_CMD_GET_CAPABILITIES_V2_OUT_LEN);
boolean_t v2_capable;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_CAPABILITIES;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN;
@@ -1086,7 +1090,8 @@ efx_mcdi_do_reboot(
__in efx_nic_t *enp,
__in boolean_t after_assertion)
{
- uint8_t payload[MAX(MC_CMD_REBOOT_IN_LEN, MC_CMD_REBOOT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_REBOOT_IN_LEN,
+ MC_CMD_REBOOT_OUT_LEN);
efx_mcdi_req_t req;
efx_rc_t rc;
@@ -1099,7 +1104,6 @@ efx_mcdi_do_reboot(
*/
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_REBOOT;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_REBOOT_IN_LEN;
@@ -1150,8 +1154,8 @@ efx_mcdi_read_assertion(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_ASSERTS_IN_LEN,
- MC_CMD_GET_ASSERTS_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_ASSERTS_IN_LEN,
+ MC_CMD_GET_ASSERTS_OUT_LEN);
const char *reason;
unsigned int flags;
unsigned int index;
@@ -1252,11 +1256,10 @@ efx_mcdi_drv_attach(
__in boolean_t attach)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_DRV_ATTACH_IN_LEN,
- MC_CMD_DRV_ATTACH_EXT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_DRV_ATTACH_IN_LEN,
+ MC_CMD_DRV_ATTACH_EXT_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_DRV_ATTACH;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_DRV_ATTACH_IN_LEN;
@@ -1311,11 +1314,10 @@ efx_mcdi_get_board_cfg(
{
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_BOARD_CFG_IN_LEN,
- MC_CMD_GET_BOARD_CFG_OUT_LENMIN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_BOARD_CFG_IN_LEN,
+ MC_CMD_GET_BOARD_CFG_OUT_LENMIN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_BOARD_CFG;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_BOARD_CFG_IN_LEN;
@@ -1391,11 +1393,10 @@ efx_mcdi_get_resource_limits(
__out_opt uint32_t *ntxqp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_RESOURCE_LIMITS_IN_LEN,
- MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_RESOURCE_LIMITS_IN_LEN,
+ MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_RESOURCE_LIMITS;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_RESOURCE_LIMITS_IN_LEN;
@@ -1438,8 +1439,8 @@ efx_mcdi_get_phy_cfg(
efx_port_t *epp = &(enp->en_port);
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PHY_CFG_IN_LEN,
- MC_CMD_GET_PHY_CFG_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PHY_CFG_IN_LEN,
+ MC_CMD_GET_PHY_CFG_OUT_LEN);
#if EFSYS_OPT_NAMES
const char *namep;
size_t namelen;
@@ -1447,7 +1448,6 @@ efx_mcdi_get_phy_cfg(
uint32_t phy_media_type;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PHY_CFG;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_PHY_CFG_IN_LEN;
@@ -1686,11 +1686,10 @@ efx_mcdi_bist_start(
__in efx_bist_type_t type)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_START_BIST_IN_LEN,
- MC_CMD_START_BIST_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_START_BIST_IN_LEN,
+ MC_CMD_START_BIST_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_START_BIST;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_START_BIST_IN_LEN;
@@ -1749,11 +1748,10 @@ efx_mcdi_log_ctrl(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_LOG_CTRL_IN_LEN,
- MC_CMD_LOG_CTRL_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LOG_CTRL_IN_LEN,
+ MC_CMD_LOG_CTRL_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_LOG_CTRL;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_LOG_CTRL_IN_LEN;
@@ -1798,8 +1796,8 @@ efx_mcdi_mac_stats(
__in uint16_t period_ms)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_MAC_STATS_IN_LEN,
- MC_CMD_MAC_STATS_V2_OUT_DMA_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_MAC_STATS_IN_LEN,
+ MC_CMD_MAC_STATS_V2_OUT_DMA_LEN);
int clear = (action == EFX_STATS_CLEAR);
int upload = (action == EFX_STATS_UPLOAD);
int enable = (action == EFX_STATS_ENABLE_NOEVENTS);
@@ -1807,7 +1805,6 @@ efx_mcdi_mac_stats(
int disable = (action == EFX_STATS_DISABLE);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_MAC_STATS;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_MAC_STATS_IN_LEN;
@@ -1979,11 +1976,10 @@ efx_mcdi_get_function_info(
__out_opt uint32_t *vfp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_FUNCTION_INFO_IN_LEN,
- MC_CMD_GET_FUNCTION_INFO_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_FUNCTION_INFO_IN_LEN,
+ MC_CMD_GET_FUNCTION_INFO_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_FUNCTION_INFO;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_FUNCTION_INFO_IN_LEN;
@@ -2024,11 +2020,10 @@ efx_mcdi_privilege_mask(
__out uint32_t *maskp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_PRIVILEGE_MASK_IN_LEN,
- MC_CMD_PRIVILEGE_MASK_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_PRIVILEGE_MASK_IN_LEN,
+ MC_CMD_PRIVILEGE_MASK_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_PRIVILEGE_MASK;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_PRIVILEGE_MASK_IN_LEN;
@@ -2073,11 +2068,10 @@ efx_mcdi_set_workaround(
__out_opt uint32_t *flagsp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_WORKAROUND_IN_LEN,
- MC_CMD_WORKAROUND_EXT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_WORKAROUND_IN_LEN,
+ MC_CMD_WORKAROUND_EXT_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_WORKAROUND;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_WORKAROUND_IN_LEN;
@@ -2117,10 +2111,9 @@ efx_mcdi_get_workarounds(
__out_opt uint32_t *enabledp)
{
efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_GET_WORKAROUNDS_OUT_LEN];
+ EFX_MCDI_DECLARE_BUF(payload, 0, MC_CMD_GET_WORKAROUNDS_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_WORKAROUNDS;
req.emr_in_buf = NULL;
req.emr_in_length = 0;
@@ -2157,6 +2150,14 @@ fail1:
*/
#define EFX_PHY_MEDIA_INFO_PAGE_SIZE 0x80
+/*
+ * Transceiver identifiers from SFF-8024 Table 4-1.
+ */
+#define EFX_SFF_TRANSCEIVER_ID_SFP 0x03 /* SFP/SFP+/SFP28 */
+#define EFX_SFF_TRANSCEIVER_ID_QSFP 0x0c /* QSFP */
+#define EFX_SFF_TRANSCEIVER_ID_QSFP_PLUS 0x0d /* QSFP+ or later */
+#define EFX_SFF_TRANSCEIVER_ID_QSFP28 0x11 /* QSFP28 or later */
+
static __checkReturn efx_rc_t
efx_mcdi_get_phy_media_info(
__in efx_nic_t *enp,
@@ -2166,14 +2167,13 @@ efx_mcdi_get_phy_media_info(
__out_bcount(len) uint8_t *data)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN,
- MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(
- EFX_PHY_MEDIA_INFO_PAGE_SIZE))];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN,
+ MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(
+ EFX_PHY_MEDIA_INFO_PAGE_SIZE));
efx_rc_t rc;
EFSYS_ASSERT((uint32_t)offset + len <= EFX_PHY_MEDIA_INFO_PAGE_SIZE);
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PHY_MEDIA_INFO;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN;
@@ -2218,39 +2218,19 @@ fail1:
return (rc);
}
-/*
- * 2-wire device address of the base information in accordance with SFF-8472
- * Diagnostic Monitoring Interface for Optical Transceivers section
- * 4 Memory Organization.
- */
-#define EFX_PHY_MEDIA_INFO_DEV_ADDR_SFP_BASE 0xA0
-
-/*
- * 2-wire device address of the digital diagnostics monitoring interface
- * in accordance with SFF-8472 Diagnostic Monitoring Interface for Optical
- * Transceivers section 4 Memory Organization.
- */
-#define EFX_PHY_MEDIA_INFO_DEV_ADDR_SFP_DDM 0xA2
-
-/*
- * Hard wired 2-wire device address for QSFP+ in accordance with SFF-8436
- * QSFP+ 10 Gbs 4X PLUGGABLE TRANSCEIVER section 7.4 Device Addressing and
- * Operation.
- */
-#define EFX_PHY_MEDIA_INFO_DEV_ADDR_QSFP 0xA0
-
__checkReturn efx_rc_t
efx_mcdi_phy_module_get_info(
__in efx_nic_t *enp,
__in uint8_t dev_addr,
- __in uint8_t offset,
- __in uint8_t len,
+ __in size_t offset,
+ __in size_t len,
__out_bcount(len) uint8_t *data)
{
efx_port_t *epp = &(enp->en_port);
efx_rc_t rc;
uint32_t mcdi_lower_page;
uint32_t mcdi_upper_page;
+ uint8_t id;
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
@@ -2264,6 +2244,26 @@ efx_mcdi_phy_module_get_info(
*/
switch (epp->ep_fixed_port_type) {
case EFX_PHY_MEDIA_SFP_PLUS:
+ case EFX_PHY_MEDIA_QSFP_PLUS:
+ /* Port type supports modules */
+ break;
+ default:
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ /*
+ * For all supported port types, MCDI page 0 offset 0 holds the
+ * transceiver identifier. Probe to determine the data layout.
+ * Definitions from SFF-8024 Table 4-1.
+ */
+ rc = efx_mcdi_get_phy_media_info(enp,
+ 0, 0, sizeof(id), &id);
+ if (rc != 0)
+ goto fail2;
+
+ switch (id) {
+ case EFX_SFF_TRANSCEIVER_ID_SFP:
/*
* In accordance with SFF-8472 Diagnostic Monitoring
* Interface for Optical Transceivers section 4 Memory
@@ -2298,10 +2298,12 @@ efx_mcdi_phy_module_get_info(
break;
default:
rc = ENOTSUP;
- goto fail1;
+ goto fail3;
}
break;
- case EFX_PHY_MEDIA_QSFP_PLUS:
+ case EFX_SFF_TRANSCEIVER_ID_QSFP:
+ case EFX_SFF_TRANSCEIVER_ID_QSFP_PLUS:
+ case EFX_SFF_TRANSCEIVER_ID_QSFP28:
switch (dev_addr) {
case EFX_PHY_MEDIA_INFO_DEV_ADDR_QSFP:
/*
@@ -2317,22 +2319,24 @@ efx_mcdi_phy_module_get_info(
break;
default:
rc = ENOTSUP;
- goto fail1;
+ goto fail3;
}
break;
default:
rc = ENOTSUP;
- goto fail1;
+ goto fail3;
}
+ EFX_STATIC_ASSERT(EFX_PHY_MEDIA_INFO_PAGE_SIZE <= 0xFF);
+
if (offset < EFX_PHY_MEDIA_INFO_PAGE_SIZE) {
- uint8_t read_len =
+ size_t read_len =
MIN(len, EFX_PHY_MEDIA_INFO_PAGE_SIZE - offset);
rc = efx_mcdi_get_phy_media_info(enp,
- mcdi_lower_page, offset, read_len, data);
+ mcdi_lower_page, (uint8_t)offset, (uint8_t)read_len, data);
if (rc != 0)
- goto fail2;
+ goto fail4;
data += read_len;
len -= read_len;
@@ -2347,13 +2351,17 @@ efx_mcdi_phy_module_get_info(
EFSYS_ASSERT3U(offset, <, EFX_PHY_MEDIA_INFO_PAGE_SIZE);
rc = efx_mcdi_get_phy_media_info(enp,
- mcdi_upper_page, offset, len, data);
+ mcdi_upper_page, (uint8_t)offset, (uint8_t)len, data);
if (rc != 0)
- goto fail3;
+ goto fail5;
}
return (0);
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
fail3:
EFSYS_PROBE(fail3);
fail2:
diff --git a/drivers/net/sfc/base/efx_mcdi.h b/drivers/net/sfc/base/efx_mcdi.h
index 253a9e60..ddf91c11 100644
--- a/drivers/net/sfc/base/efx_mcdi.h
+++ b/drivers/net/sfc/base/efx_mcdi.h
@@ -10,6 +10,10 @@
#include "efx.h"
#include "efx_regs_mcdi.h"
+#if EFSYS_OPT_NAMES
+#include "mc_driver_pcol_strs.h"
+#endif /* EFSYS_OPT_NAMES */
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -215,8 +219,8 @@ extern __checkReturn efx_rc_t
efx_mcdi_phy_module_get_info(
__in efx_nic_t *enp,
__in uint8_t dev_addr,
- __in uint8_t offset,
- __in uint8_t len,
+ __in size_t offset,
+ __in size_t len,
__out_bcount(len) uint8_t *data);
#define MCDI_IN(_emr, _type, _ofst) \
@@ -380,6 +384,17 @@ efx_mcdi_phy_module_get_info(
(((mask) & (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv)) == \
(MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv))
+/*
+ * The buffer size must be a multiple of dword to ensure that MCDI works
+ * properly with Siena based boards (which use on-chip buffer). Also, it
+ * should be at minimum the size of two dwords to allow space for extended
+ * error responses if the request/response buffer sizes are smaller.
+ */
+#define EFX_MCDI_DECLARE_BUF(_name, _in_len, _out_len) \
+ uint8_t _name[P2ROUNDUP(MAX(MAX(_in_len, _out_len), \
+ (2 * sizeof (efx_dword_t))), \
+ sizeof (efx_dword_t))] = {0}
+
typedef enum efx_mcdi_feature_id_e {
EFX_MCDI_FEATURE_FW_UPDATE = 0,
EFX_MCDI_FEATURE_LINK_CONTROL,
diff --git a/drivers/net/sfc/base/efx_mon.c b/drivers/net/sfc/base/efx_mon.c
index 9fc268ec..f28775d0 100644
--- a/drivers/net/sfc/base/efx_mon.c
+++ b/drivers/net/sfc/base/efx_mon.c
@@ -38,7 +38,8 @@ efx_mon_name(
#if EFSYS_OPT_MON_MCDI
static const efx_mon_ops_t __efx_mon_mcdi_ops = {
#if EFSYS_OPT_MON_STATS
- mcdi_mon_stats_update /* emo_stats_update */
+ mcdi_mon_stats_update, /* emo_stats_update */
+ mcdi_mon_limits_update, /* emo_limits_update */
#endif /* EFSYS_OPT_MON_STATS */
};
#endif
@@ -99,77 +100,74 @@ fail1:
#if EFSYS_OPT_NAMES
-/* START MKCONFIG GENERATED MonitorStatNamesBlock 8150a068198c0f96 */
+/* START MKCONFIG GENERATED MonitorStatNamesBlock 277c17eda1a6d1a4 */
static const char * const __mon_stat_name[] = {
- "value_2_5v",
- "value_vccp1",
- "value_vcc",
- "value_5v",
- "value_12v",
- "value_vccp2",
- "value_ext_temp",
- "value_int_temp",
- "value_ain1",
- "value_ain2",
+ "controller_temp",
+ "phy_common_temp",
"controller_cooling",
- "ext_cooling",
- "1v",
- "1_2v",
- "1_8v",
- "3_3v",
- "1_2va",
- "vref",
- "vaoe",
- "aoe_temperature",
- "psu_aoe_temperature",
- "psu_temperature",
- "fan0",
- "fan1",
- "fan2",
- "fan3",
- "fan4",
- "vaoe_in",
- "iaoe",
- "iaoe_in",
+ "phy0_temp",
+ "phy0_cooling",
+ "phy1_temp",
+ "phy1_cooling",
+ "in_1v0",
+ "in_1v2",
+ "in_1v8",
+ "in_2v5",
+ "in_3v3",
+ "in_12v0",
+ "in_1v2a",
+ "in_vref",
+ "out_vaoe",
+ "aoe_temp",
+ "psu_aoe_temp",
+ "psu_temp",
+ "fan_0",
+ "fan_1",
+ "fan_2",
+ "fan_3",
+ "fan_4",
+ "in_vaoe",
+ "out_iaoe",
+ "in_iaoe",
"nic_power",
- "0_9v",
- "i0_9v",
- "i1_2v",
- "0_9v_adc",
- "controller_temperature2",
- "vreg_temperature",
- "vreg_0_9v_temperature",
- "vreg_1_2v_temperature",
- "int_vptat",
- "controller_internal_adc_temperature",
- "ext_vptat",
- "controller_external_adc_temperature",
- "ambient_temperature",
+ "in_0v9",
+ "in_i0v9",
+ "in_i1v2",
+ "in_0v9_adc",
+ "controller_2_temp",
+ "vreg_internal_temp",
+ "vreg_0v9_temp",
+ "vreg_1v2_temp",
+ "controller_vptat",
+ "controller_internal_temp",
+ "controller_vptat_extadc",
+ "controller_internal_temp_extadc",
+ "ambient_temp",
"airflow",
"vdd08d_vss08d_csr",
"vdd08d_vss08d_csr_extadc",
- "hotpoint_temperature",
- "phy_power_switch_port0",
- "phy_power_switch_port1",
+ "hotpoint_temp",
+ "phy_power_port0",
+ "phy_power_port1",
"mum_vcc",
- "0v9_a",
- "i0v9_a",
- "0v9_a_temp",
- "0v9_b",
- "i0v9_b",
- "0v9_b_temp",
+ "in_0v9_a",
+ "in_i0v9_a",
+ "vreg_0v9_a_temp",
+ "in_0v9_b",
+ "in_i0v9_b",
+ "vreg_0v9_b_temp",
"ccom_avreg_1v2_supply",
- "ccom_avreg_1v2_supply_ext_adc",
+ "ccom_avreg_1v2_supply_extadc",
"ccom_avreg_1v8_supply",
- "ccom_avreg_1v8_supply_ext_adc",
+ "ccom_avreg_1v8_supply_extadc",
"controller_master_vptat",
"controller_master_internal_temp",
- "controller_master_vptat_ext_adc",
- "controller_master_internal_temp_ext_adc",
+ "controller_master_vptat_extadc",
+ "controller_master_internal_temp_extadc",
"controller_slave_vptat",
"controller_slave_internal_temp",
- "controller_slave_vptat_ext_adc",
- "controller_slave_internal_temp_ext_adc",
+ "controller_slave_vptat_extadc",
+ "controller_slave_internal_temp_extadc",
"sodimm_vout",
"sodimm_0_temp",
"sodimm_1_temp",
@@ -178,17 +176,17 @@ static const char * const __mon_stat_name[] = {
"controller_tdiode_temp",
"board_front_temp",
"board_back_temp",
- "i1v8",
- "i2v5",
- "i3v3",
- "i12v0",
- "1v3",
- "i1v3",
+ "in_i1v8",
+ "in_i2v5",
+ "in_i3v3",
+ "in_i12v0",
+ "in_1v3",
+ "in_i1v3",
};
/* END MKCONFIG GENERATED MonitorStatNamesBlock */
-extern const char *
+ const char *
efx_mon_stat_name(
__in efx_nic_t *enp,
__in efx_mon_stat_t id)
@@ -200,8 +198,609 @@ efx_mon_stat_name(
return (__mon_stat_name[id]);
}
+typedef struct _stat_description_t {
+ efx_mon_stat_t stat;
+ const char *desc;
+} stat_description_t;
+
+/* START MKCONFIG GENERATED MonitorStatDescriptionsBlock f072138f16d2e1f8 */
+static const char *__mon_stat_description[] = {
+ MC_CMD_SENSOR_CONTROLLER_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_PHY_COMMON_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_COOLING_ENUM_STR,
+ MC_CMD_SENSOR_PHY0_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_PHY0_COOLING_ENUM_STR,
+ MC_CMD_SENSOR_PHY1_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_PHY1_COOLING_ENUM_STR,
+ MC_CMD_SENSOR_IN_1V0_ENUM_STR,
+ MC_CMD_SENSOR_IN_1V2_ENUM_STR,
+ MC_CMD_SENSOR_IN_1V8_ENUM_STR,
+ MC_CMD_SENSOR_IN_2V5_ENUM_STR,
+ MC_CMD_SENSOR_IN_3V3_ENUM_STR,
+ MC_CMD_SENSOR_IN_12V0_ENUM_STR,
+ MC_CMD_SENSOR_IN_1V2A_ENUM_STR,
+ MC_CMD_SENSOR_IN_VREF_ENUM_STR,
+ MC_CMD_SENSOR_OUT_VAOE_ENUM_STR,
+ MC_CMD_SENSOR_AOE_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_PSU_AOE_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_PSU_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_FAN_0_ENUM_STR,
+ MC_CMD_SENSOR_FAN_1_ENUM_STR,
+ MC_CMD_SENSOR_FAN_2_ENUM_STR,
+ MC_CMD_SENSOR_FAN_3_ENUM_STR,
+ MC_CMD_SENSOR_FAN_4_ENUM_STR,
+ MC_CMD_SENSOR_IN_VAOE_ENUM_STR,
+ MC_CMD_SENSOR_OUT_IAOE_ENUM_STR,
+ MC_CMD_SENSOR_IN_IAOE_ENUM_STR,
+ MC_CMD_SENSOR_NIC_POWER_ENUM_STR,
+ MC_CMD_SENSOR_IN_0V9_ENUM_STR,
+ MC_CMD_SENSOR_IN_I0V9_ENUM_STR,
+ MC_CMD_SENSOR_IN_I1V2_ENUM_STR,
+ MC_CMD_SENSOR_IN_0V9_ADC_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_2_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_VREG_INTERNAL_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_VREG_0V9_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_VREG_1V2_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_VPTAT_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_VPTAT_EXTADC_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_EXTADC_ENUM_STR,
+ MC_CMD_SENSOR_AMBIENT_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_AIRFLOW_ENUM_STR,
+ MC_CMD_SENSOR_VDD08D_VSS08D_CSR_ENUM_STR,
+ MC_CMD_SENSOR_VDD08D_VSS08D_CSR_EXTADC_ENUM_STR,
+ MC_CMD_SENSOR_HOTPOINT_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_PHY_POWER_PORT0_ENUM_STR,
+ MC_CMD_SENSOR_PHY_POWER_PORT1_ENUM_STR,
+ MC_CMD_SENSOR_MUM_VCC_ENUM_STR,
+ MC_CMD_SENSOR_IN_0V9_A_ENUM_STR,
+ MC_CMD_SENSOR_IN_I0V9_A_ENUM_STR,
+ MC_CMD_SENSOR_VREG_0V9_A_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_IN_0V9_B_ENUM_STR,
+ MC_CMD_SENSOR_IN_I0V9_B_ENUM_STR,
+ MC_CMD_SENSOR_VREG_0V9_B_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_ENUM_STR,
+ MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_EXTADC_ENUM_STR,
+ MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_ENUM_STR,
+ MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_EXTADC_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_EXTADC_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_EXTADC_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC_ENUM_STR,
+ MC_CMD_SENSOR_SODIMM_VOUT_ENUM_STR,
+ MC_CMD_SENSOR_SODIMM_0_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_SODIMM_1_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_PHY0_VCC_ENUM_STR,
+ MC_CMD_SENSOR_PHY1_VCC_ENUM_STR,
+ MC_CMD_SENSOR_CONTROLLER_TDIODE_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_BOARD_FRONT_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_BOARD_BACK_TEMP_ENUM_STR,
+ MC_CMD_SENSOR_IN_I1V8_ENUM_STR,
+ MC_CMD_SENSOR_IN_I2V5_ENUM_STR,
+ MC_CMD_SENSOR_IN_I3V3_ENUM_STR,
+ MC_CMD_SENSOR_IN_I12V0_ENUM_STR,
+ MC_CMD_SENSOR_IN_1V3_ENUM_STR,
+ MC_CMD_SENSOR_IN_I1V3_ENUM_STR,
+};
+
+/* END MKCONFIG GENERATED MonitorStatDescriptionsBlock */
+
+ const char *
+efx_mon_stat_description(
+ __in efx_nic_t *enp,
+ __in efx_mon_stat_t id)
+{
+ _NOTE(ARGUNUSED(enp))
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+ EFSYS_ASSERT3U(id, <, EFX_MON_NSTATS);
+ return (__mon_stat_description[id]);
+}
+
#endif /* EFSYS_OPT_NAMES */
+/* START MKCONFIG GENERATED MonitorMcdiMappingBlock 173eee0a5599996a */
+ __checkReturn boolean_t
+efx_mon_mcdi_to_efx_stat(
+ __in int mcdi_index,
+ __out efx_mon_stat_t *statp)
+{
+
+ if ((mcdi_index % (MC_CMD_SENSOR_PAGE0_NEXT + 1)) ==
+ MC_CMD_SENSOR_PAGE0_NEXT) {
+ *statp = EFX_MON_NSTATS;
+ return (B_FALSE);
+ }
+
+ switch (mcdi_index) {
+ case MC_CMD_SENSOR_IN_I0V9:
+ *statp = EFX_MON_STAT_IN_I0V9;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_EXTADC:
+ *statp = EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXTADC;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT:
+ *statp = EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT;
+ break;
+ case MC_CMD_SENSOR_PSU_TEMP:
+ *statp = EFX_MON_STAT_PSU_TEMP;
+ break;
+ case MC_CMD_SENSOR_FAN_2:
+ *statp = EFX_MON_STAT_FAN_2;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_EXTADC:
+ *statp = EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP_EXTADC;
+ break;
+ case MC_CMD_SENSOR_BOARD_BACK_TEMP:
+ *statp = EFX_MON_STAT_BOARD_BACK_TEMP;
+ break;
+ case MC_CMD_SENSOR_IN_1V3:
+ *statp = EFX_MON_STAT_IN_1V3;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_TDIODE_TEMP:
+ *statp = EFX_MON_STAT_CONTROLLER_TDIODE_TEMP;
+ break;
+ case MC_CMD_SENSOR_IN_2V5:
+ *statp = EFX_MON_STAT_IN_2V5;
+ break;
+ case MC_CMD_SENSOR_PHY_COMMON_TEMP:
+ *statp = EFX_MON_STAT_PHY_COMMON_TEMP;
+ break;
+ case MC_CMD_SENSOR_PHY1_TEMP:
+ *statp = EFX_MON_STAT_PHY1_TEMP;
+ break;
+ case MC_CMD_SENSOR_VREG_INTERNAL_TEMP:
+ *statp = EFX_MON_STAT_VREG_INTERNAL_TEMP;
+ break;
+ case MC_CMD_SENSOR_IN_1V0:
+ *statp = EFX_MON_STAT_IN_1V0;
+ break;
+ case MC_CMD_SENSOR_FAN_1:
+ *statp = EFX_MON_STAT_FAN_1;
+ break;
+ case MC_CMD_SENSOR_IN_1V2:
+ *statp = EFX_MON_STAT_IN_1V2;
+ break;
+ case MC_CMD_SENSOR_FAN_3:
+ *statp = EFX_MON_STAT_FAN_3;
+ break;
+ case MC_CMD_SENSOR_IN_1V2A:
+ *statp = EFX_MON_STAT_IN_1V2A;
+ break;
+ case MC_CMD_SENSOR_SODIMM_0_TEMP:
+ *statp = EFX_MON_STAT_SODIMM_0_TEMP;
+ break;
+ case MC_CMD_SENSOR_IN_1V8:
+ *statp = EFX_MON_STAT_IN_1V8;
+ break;
+ case MC_CMD_SENSOR_IN_VREF:
+ *statp = EFX_MON_STAT_IN_VREF;
+ break;
+ case MC_CMD_SENSOR_SODIMM_VOUT:
+ *statp = EFX_MON_STAT_SODIMM_VOUT;
+ break;
+ case MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY:
+ *statp = EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY;
+ break;
+ case MC_CMD_SENSOR_IN_I1V2:
+ *statp = EFX_MON_STAT_IN_I1V2;
+ break;
+ case MC_CMD_SENSOR_IN_I1V3:
+ *statp = EFX_MON_STAT_IN_I1V3;
+ break;
+ case MC_CMD_SENSOR_AIRFLOW:
+ *statp = EFX_MON_STAT_AIRFLOW;
+ break;
+ case MC_CMD_SENSOR_HOTPOINT_TEMP:
+ *statp = EFX_MON_STAT_HOTPOINT_TEMP;
+ break;
+ case MC_CMD_SENSOR_VDD08D_VSS08D_CSR:
+ *statp = EFX_MON_STAT_VDD08D_VSS08D_CSR;
+ break;
+ case MC_CMD_SENSOR_AOE_TEMP:
+ *statp = EFX_MON_STAT_AOE_TEMP;
+ break;
+ case MC_CMD_SENSOR_IN_I1V8:
+ *statp = EFX_MON_STAT_IN_I1V8;
+ break;
+ case MC_CMD_SENSOR_IN_I2V5:
+ *statp = EFX_MON_STAT_IN_I2V5;
+ break;
+ case MC_CMD_SENSOR_PHY1_COOLING:
+ *statp = EFX_MON_STAT_PHY1_COOLING;
+ break;
+ case MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_EXTADC:
+ *statp = EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXTADC;
+ break;
+ case MC_CMD_SENSOR_IN_0V9_ADC:
+ *statp = EFX_MON_STAT_IN_0V9_ADC;
+ break;
+ case MC_CMD_SENSOR_VREG_0V9_A_TEMP:
+ *statp = EFX_MON_STAT_VREG_0V9_A_TEMP;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT:
+ *statp = EFX_MON_STAT_CONTROLLER_MASTER_VPTAT;
+ break;
+ case MC_CMD_SENSOR_PHY0_VCC:
+ *statp = EFX_MON_STAT_PHY0_VCC;
+ break;
+ case MC_CMD_SENSOR_PHY0_COOLING:
+ *statp = EFX_MON_STAT_PHY0_COOLING;
+ break;
+ case MC_CMD_SENSOR_PSU_AOE_TEMP:
+ *statp = EFX_MON_STAT_PSU_AOE_TEMP;
+ break;
+ case MC_CMD_SENSOR_VREG_0V9_TEMP:
+ *statp = EFX_MON_STAT_VREG_0V9_TEMP;
+ break;
+ case MC_CMD_SENSOR_IN_I0V9_A:
+ *statp = EFX_MON_STAT_IN_I0V9_A;
+ break;
+ case MC_CMD_SENSOR_IN_I3V3:
+ *statp = EFX_MON_STAT_IN_I3V3;
+ break;
+ case MC_CMD_SENSOR_BOARD_FRONT_TEMP:
+ *statp = EFX_MON_STAT_BOARD_FRONT_TEMP;
+ break;
+ case MC_CMD_SENSOR_OUT_VAOE:
+ *statp = EFX_MON_STAT_OUT_VAOE;
+ break;
+ case MC_CMD_SENSOR_VDD08D_VSS08D_CSR_EXTADC:
+ *statp = EFX_MON_STAT_VDD08D_VSS08D_CSR_EXTADC;
+ break;
+ case MC_CMD_SENSOR_IN_I12V0:
+ *statp = EFX_MON_STAT_IN_I12V0;
+ break;
+ case MC_CMD_SENSOR_PHY_POWER_PORT1:
+ *statp = EFX_MON_STAT_PHY_POWER_PORT1;
+ break;
+ case MC_CMD_SENSOR_PHY_POWER_PORT0:
+ *statp = EFX_MON_STAT_PHY_POWER_PORT0;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC:
+ *statp = EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP:
+ *statp = EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_TEMP:
+ *statp = EFX_MON_STAT_CONTROLLER_TEMP;
+ break;
+ case MC_CMD_SENSOR_IN_IAOE:
+ *statp = EFX_MON_STAT_IN_IAOE;
+ break;
+ case MC_CMD_SENSOR_IN_VAOE:
+ *statp = EFX_MON_STAT_IN_VAOE;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_EXTADC:
+ *statp = EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXTADC;
+ break;
+ case MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY:
+ *statp = EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY;
+ break;
+ case MC_CMD_SENSOR_PHY1_VCC:
+ *statp = EFX_MON_STAT_PHY1_VCC;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_COOLING:
+ *statp = EFX_MON_STAT_CONTROLLER_COOLING;
+ break;
+ case MC_CMD_SENSOR_AMBIENT_TEMP:
+ *statp = EFX_MON_STAT_AMBIENT_TEMP;
+ break;
+ case MC_CMD_SENSOR_IN_3V3:
+ *statp = EFX_MON_STAT_IN_3V3;
+ break;
+ case MC_CMD_SENSOR_PHY0_TEMP:
+ *statp = EFX_MON_STAT_PHY0_TEMP;
+ break;
+ case MC_CMD_SENSOR_SODIMM_1_TEMP:
+ *statp = EFX_MON_STAT_SODIMM_1_TEMP;
+ break;
+ case MC_CMD_SENSOR_MUM_VCC:
+ *statp = EFX_MON_STAT_MUM_VCC;
+ break;
+ case MC_CMD_SENSOR_VREG_0V9_B_TEMP:
+ *statp = EFX_MON_STAT_VREG_0V9_B_TEMP;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP:
+ *statp = EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP;
+ break;
+ case MC_CMD_SENSOR_FAN_4:
+ *statp = EFX_MON_STAT_FAN_4;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_2_TEMP:
+ *statp = EFX_MON_STAT_CONTROLLER_2_TEMP;
+ break;
+ case MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_EXTADC:
+ *statp = EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXTADC;
+ break;
+ case MC_CMD_SENSOR_IN_0V9_A:
+ *statp = EFX_MON_STAT_IN_0V9_A;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_VPTAT_EXTADC:
+ *statp = EFX_MON_STAT_CONTROLLER_VPTAT_EXTADC;
+ break;
+ case MC_CMD_SENSOR_IN_0V9:
+ *statp = EFX_MON_STAT_IN_0V9;
+ break;
+ case MC_CMD_SENSOR_IN_I0V9_B:
+ *statp = EFX_MON_STAT_IN_I0V9_B;
+ break;
+ case MC_CMD_SENSOR_NIC_POWER:
+ *statp = EFX_MON_STAT_NIC_POWER;
+ break;
+ case MC_CMD_SENSOR_IN_12V0:
+ *statp = EFX_MON_STAT_IN_12V0;
+ break;
+ case MC_CMD_SENSOR_OUT_IAOE:
+ *statp = EFX_MON_STAT_OUT_IAOE;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_VPTAT:
+ *statp = EFX_MON_STAT_CONTROLLER_VPTAT;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC:
+ *statp = EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC;
+ break;
+ case MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP:
+ *statp = EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP;
+ break;
+ case MC_CMD_SENSOR_FAN_0:
+ *statp = EFX_MON_STAT_FAN_0;
+ break;
+ case MC_CMD_SENSOR_VREG_1V2_TEMP:
+ *statp = EFX_MON_STAT_VREG_1V2_TEMP;
+ break;
+ case MC_CMD_SENSOR_IN_0V9_B:
+ *statp = EFX_MON_STAT_IN_0V9_B;
+ break;
+ default:
+ *statp = EFX_MON_NSTATS;
+ break;
+ };
+
+ if (*statp == EFX_MON_NSTATS)
+ goto fail1;
+
+ return (B_TRUE);
+
+fail1:
+ EFSYS_PROBE1(fail1, boolean_t, B_TRUE);
+ return (B_FALSE);
+};
+
+/* END MKCONFIG GENERATED MonitorMcdiMappingBlock */
+
+/* START MKCONFIG GENERATED MonitorStatisticUnitsBlock 2d447c656cc2d01d */
+ __checkReturn boolean_t
+efx_mon_get_stat_unit(
+ __in efx_mon_stat_t stat,
+ __out efx_mon_stat_unit_t *unitp)
+{
+ switch (stat) {
+ case EFX_MON_STAT_IN_1V0:
+ case EFX_MON_STAT_IN_1V2:
+ case EFX_MON_STAT_IN_1V8:
+ case EFX_MON_STAT_IN_2V5:
+ case EFX_MON_STAT_IN_3V3:
+ case EFX_MON_STAT_IN_12V0:
+ case EFX_MON_STAT_IN_1V2A:
+ case EFX_MON_STAT_IN_VREF:
+ case EFX_MON_STAT_OUT_VAOE:
+ case EFX_MON_STAT_IN_VAOE:
+ case EFX_MON_STAT_IN_0V9:
+ case EFX_MON_STAT_IN_0V9_ADC:
+ case EFX_MON_STAT_CONTROLLER_VPTAT_EXTADC:
+ case EFX_MON_STAT_VDD08D_VSS08D_CSR:
+ case EFX_MON_STAT_VDD08D_VSS08D_CSR_EXTADC:
+ case EFX_MON_STAT_MUM_VCC:
+ case EFX_MON_STAT_IN_0V9_A:
+ case EFX_MON_STAT_IN_0V9_B:
+ case EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY:
+ case EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXTADC:
+ case EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY:
+ case EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXTADC:
+ case EFX_MON_STAT_CONTROLLER_MASTER_VPTAT:
+ case EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXTADC:
+ case EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT:
+ case EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXTADC:
+ case EFX_MON_STAT_SODIMM_VOUT:
+ case EFX_MON_STAT_PHY0_VCC:
+ case EFX_MON_STAT_PHY1_VCC:
+ case EFX_MON_STAT_IN_1V3:
+ *unitp = EFX_MON_STAT_UNIT_VOLTAGE_MV;
+ break;
+ case EFX_MON_STAT_CONTROLLER_TEMP:
+ case EFX_MON_STAT_PHY_COMMON_TEMP:
+ case EFX_MON_STAT_PHY0_TEMP:
+ case EFX_MON_STAT_PHY1_TEMP:
+ case EFX_MON_STAT_AOE_TEMP:
+ case EFX_MON_STAT_PSU_AOE_TEMP:
+ case EFX_MON_STAT_PSU_TEMP:
+ case EFX_MON_STAT_CONTROLLER_2_TEMP:
+ case EFX_MON_STAT_VREG_INTERNAL_TEMP:
+ case EFX_MON_STAT_VREG_0V9_TEMP:
+ case EFX_MON_STAT_VREG_1V2_TEMP:
+ case EFX_MON_STAT_CONTROLLER_VPTAT:
+ case EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP:
+ case EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP_EXTADC:
+ case EFX_MON_STAT_AMBIENT_TEMP:
+ case EFX_MON_STAT_HOTPOINT_TEMP:
+ case EFX_MON_STAT_VREG_0V9_A_TEMP:
+ case EFX_MON_STAT_VREG_0V9_B_TEMP:
+ case EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP:
+ case EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC:
+ case EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP:
+ case EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC:
+ case EFX_MON_STAT_SODIMM_0_TEMP:
+ case EFX_MON_STAT_SODIMM_1_TEMP:
+ case EFX_MON_STAT_CONTROLLER_TDIODE_TEMP:
+ case EFX_MON_STAT_BOARD_FRONT_TEMP:
+ case EFX_MON_STAT_BOARD_BACK_TEMP:
+ *unitp = EFX_MON_STAT_UNIT_TEMP_C;
+ break;
+ case EFX_MON_STAT_CONTROLLER_COOLING:
+ case EFX_MON_STAT_PHY0_COOLING:
+ case EFX_MON_STAT_PHY1_COOLING:
+ case EFX_MON_STAT_AIRFLOW:
+ case EFX_MON_STAT_PHY_POWER_PORT0:
+ case EFX_MON_STAT_PHY_POWER_PORT1:
+ *unitp = EFX_MON_STAT_UNIT_BOOL;
+ break;
+ case EFX_MON_STAT_NIC_POWER:
+ *unitp = EFX_MON_STAT_UNIT_POWER_W;
+ break;
+ case EFX_MON_STAT_OUT_IAOE:
+ case EFX_MON_STAT_IN_IAOE:
+ case EFX_MON_STAT_IN_I0V9:
+ case EFX_MON_STAT_IN_I1V2:
+ case EFX_MON_STAT_IN_I0V9_A:
+ case EFX_MON_STAT_IN_I0V9_B:
+ case EFX_MON_STAT_IN_I1V8:
+ case EFX_MON_STAT_IN_I2V5:
+ case EFX_MON_STAT_IN_I3V3:
+ case EFX_MON_STAT_IN_I12V0:
+ case EFX_MON_STAT_IN_I1V3:
+ *unitp = EFX_MON_STAT_UNIT_CURRENT_MA;
+ break;
+ case EFX_MON_STAT_FAN_0:
+ case EFX_MON_STAT_FAN_1:
+ case EFX_MON_STAT_FAN_2:
+ case EFX_MON_STAT_FAN_3:
+ case EFX_MON_STAT_FAN_4:
+ *unitp = EFX_MON_STAT_UNIT_RPM;
+ break;
+ default:
+ *unitp = EFX_MON_STAT_UNIT_UNKNOWN;
+ break;
+ };
+
+ if (*unitp == EFX_MON_STAT_UNIT_UNKNOWN)
+ goto fail1;
+
+ return (B_TRUE);
+
+fail1:
+ EFSYS_PROBE1(fail1, boolean_t, B_TRUE);
+ return (B_FALSE);
+};
+
+/* END MKCONFIG GENERATED MonitorStatisticUnitsBlock */
+
+/* START MKCONFIG GENERATED MonitorStatisticPortsBlock 1719b751d842534f */
+ __checkReturn boolean_t
+efx_mon_get_stat_portmap(
+ __in efx_mon_stat_t stat,
+ __out efx_mon_stat_portmask_t *maskp)
+{
+
+ switch (stat) {
+ case EFX_MON_STAT_PHY1_TEMP:
+ case EFX_MON_STAT_PHY1_COOLING:
+ case EFX_MON_STAT_PHY_POWER_PORT1:
+ *maskp = EFX_MON_STAT_PORTMAP_PORT1;
+ break;
+ case EFX_MON_STAT_CONTROLLER_TEMP:
+ case EFX_MON_STAT_PHY_COMMON_TEMP:
+ case EFX_MON_STAT_CONTROLLER_COOLING:
+ case EFX_MON_STAT_IN_1V0:
+ case EFX_MON_STAT_IN_1V2:
+ case EFX_MON_STAT_IN_1V8:
+ case EFX_MON_STAT_IN_2V5:
+ case EFX_MON_STAT_IN_3V3:
+ case EFX_MON_STAT_IN_12V0:
+ case EFX_MON_STAT_IN_1V2A:
+ case EFX_MON_STAT_IN_VREF:
+ case EFX_MON_STAT_OUT_VAOE:
+ case EFX_MON_STAT_AOE_TEMP:
+ case EFX_MON_STAT_PSU_AOE_TEMP:
+ case EFX_MON_STAT_PSU_TEMP:
+ case EFX_MON_STAT_FAN_0:
+ case EFX_MON_STAT_FAN_1:
+ case EFX_MON_STAT_FAN_2:
+ case EFX_MON_STAT_FAN_3:
+ case EFX_MON_STAT_FAN_4:
+ case EFX_MON_STAT_IN_VAOE:
+ case EFX_MON_STAT_OUT_IAOE:
+ case EFX_MON_STAT_IN_IAOE:
+ case EFX_MON_STAT_NIC_POWER:
+ case EFX_MON_STAT_IN_0V9:
+ case EFX_MON_STAT_IN_I0V9:
+ case EFX_MON_STAT_IN_I1V2:
+ case EFX_MON_STAT_IN_0V9_ADC:
+ case EFX_MON_STAT_CONTROLLER_2_TEMP:
+ case EFX_MON_STAT_VREG_INTERNAL_TEMP:
+ case EFX_MON_STAT_VREG_0V9_TEMP:
+ case EFX_MON_STAT_VREG_1V2_TEMP:
+ case EFX_MON_STAT_CONTROLLER_VPTAT:
+ case EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP:
+ case EFX_MON_STAT_CONTROLLER_VPTAT_EXTADC:
+ case EFX_MON_STAT_CONTROLLER_INTERNAL_TEMP_EXTADC:
+ case EFX_MON_STAT_AMBIENT_TEMP:
+ case EFX_MON_STAT_AIRFLOW:
+ case EFX_MON_STAT_VDD08D_VSS08D_CSR:
+ case EFX_MON_STAT_VDD08D_VSS08D_CSR_EXTADC:
+ case EFX_MON_STAT_HOTPOINT_TEMP:
+ case EFX_MON_STAT_MUM_VCC:
+ case EFX_MON_STAT_IN_0V9_A:
+ case EFX_MON_STAT_IN_I0V9_A:
+ case EFX_MON_STAT_VREG_0V9_A_TEMP:
+ case EFX_MON_STAT_IN_0V9_B:
+ case EFX_MON_STAT_IN_I0V9_B:
+ case EFX_MON_STAT_VREG_0V9_B_TEMP:
+ case EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY:
+ case EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXTADC:
+ case EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY:
+ case EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXTADC:
+ case EFX_MON_STAT_CONTROLLER_MASTER_VPTAT:
+ case EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP:
+ case EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXTADC:
+ case EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC:
+ case EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT:
+ case EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP:
+ case EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXTADC:
+ case EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC:
+ case EFX_MON_STAT_SODIMM_VOUT:
+ case EFX_MON_STAT_SODIMM_0_TEMP:
+ case EFX_MON_STAT_SODIMM_1_TEMP:
+ case EFX_MON_STAT_PHY0_VCC:
+ case EFX_MON_STAT_PHY1_VCC:
+ case EFX_MON_STAT_CONTROLLER_TDIODE_TEMP:
+ case EFX_MON_STAT_BOARD_FRONT_TEMP:
+ case EFX_MON_STAT_BOARD_BACK_TEMP:
+ case EFX_MON_STAT_IN_I1V8:
+ case EFX_MON_STAT_IN_I2V5:
+ case EFX_MON_STAT_IN_I3V3:
+ case EFX_MON_STAT_IN_I12V0:
+ case EFX_MON_STAT_IN_1V3:
+ case EFX_MON_STAT_IN_I1V3:
+ *maskp = EFX_MON_STAT_PORTMAP_ALL;
+ break;
+ case EFX_MON_STAT_PHY0_TEMP:
+ case EFX_MON_STAT_PHY0_COOLING:
+ case EFX_MON_STAT_PHY_POWER_PORT0:
+ *maskp = EFX_MON_STAT_PORTMAP_PORT0;
+ break;
+ default:
+ *maskp = EFX_MON_STAT_PORTMAP_UNKNOWN;
+ break;
+ };
+
+ if (*maskp == EFX_MON_STAT_PORTMAP_UNKNOWN)
+ goto fail1;
+
+ return (B_TRUE);
+
+fail1:
+ EFSYS_PROBE1(fail1, boolean_t, B_TRUE);
+ return (B_FALSE);
+};
+
+/* END MKCONFIG GENERATED MonitorStatisticPortsBlock */
+
__checkReturn efx_rc_t
efx_mon_stats_update(
__in efx_nic_t *enp,
@@ -217,6 +816,20 @@ efx_mon_stats_update(
return (emop->emo_stats_update(enp, esmp, values));
}
+ __checkReturn efx_rc_t
+efx_mon_limits_update(
+ __in efx_nic_t *enp,
+ __inout_ecount(EFX_MON_NSTATS) efx_mon_stat_limits_t *values)
+{
+ efx_mon_t *emp = &(enp->en_mon);
+ const efx_mon_ops_t *emop = emp->em_emop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MON);
+
+ return (emop->emo_limits_update(enp, values));
+}
+
#endif /* EFSYS_OPT_MON_STATS */
void
diff --git a/drivers/net/sfc/base/efx_nic.c b/drivers/net/sfc/base/efx_nic.c
index 6c162e03..cea32b79 100644
--- a/drivers/net/sfc/base/efx_nic.c
+++ b/drivers/net/sfc/base/efx_nic.c
@@ -100,6 +100,8 @@ static const efx_nic_ops_t __efx_nic_siena_ops = {
siena_nic_init, /* eno_init */
NULL, /* eno_get_vi_pool */
NULL, /* eno_get_bar_region */
+ NULL, /* eno_hw_unavailable */
+ NULL, /* eno_set_hw_unavailable */
#if EFSYS_OPT_DIAG
siena_nic_register_test, /* eno_register_test */
#endif /* EFSYS_OPT_DIAG */
@@ -119,6 +121,8 @@ static const efx_nic_ops_t __efx_nic_hunt_ops = {
ef10_nic_init, /* eno_init */
ef10_nic_get_vi_pool, /* eno_get_vi_pool */
ef10_nic_get_bar_region, /* eno_get_bar_region */
+ ef10_nic_hw_unavailable, /* eno_hw_unavailable */
+ ef10_nic_set_hw_unavailable, /* eno_set_hw_unavailable */
#if EFSYS_OPT_DIAG
ef10_nic_register_test, /* eno_register_test */
#endif /* EFSYS_OPT_DIAG */
@@ -138,6 +142,8 @@ static const efx_nic_ops_t __efx_nic_medford_ops = {
ef10_nic_init, /* eno_init */
ef10_nic_get_vi_pool, /* eno_get_vi_pool */
ef10_nic_get_bar_region, /* eno_get_bar_region */
+ ef10_nic_hw_unavailable, /* eno_hw_unavailable */
+ ef10_nic_set_hw_unavailable, /* eno_set_hw_unavailable */
#if EFSYS_OPT_DIAG
ef10_nic_register_test, /* eno_register_test */
#endif /* EFSYS_OPT_DIAG */
@@ -157,6 +163,8 @@ static const efx_nic_ops_t __efx_nic_medford2_ops = {
ef10_nic_init, /* eno_init */
ef10_nic_get_vi_pool, /* eno_get_vi_pool */
ef10_nic_get_bar_region, /* eno_get_bar_region */
+ ef10_nic_hw_unavailable, /* eno_hw_unavailable */
+ ef10_nic_set_hw_unavailable, /* eno_set_hw_unavailable */
#if EFSYS_OPT_DIAG
ef10_nic_register_test, /* eno_register_test */
#endif /* EFSYS_OPT_DIAG */
@@ -549,7 +557,7 @@ 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
+ * All modules except the MCDI, PROBE, NVRAM, VPD, MON, TUNNEL
* (which we do not reset here) must have been shut down or never
* initialized.
*
@@ -559,7 +567,10 @@ 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);
+#if EFSYS_OPT_TUNNEL
+ mod_flags &= ~EFX_MOD_TUNNEL;
+#endif /* EFSYS_OPT_TUNNEL */
EFSYS_ASSERT3U(mod_flags, ==, 0);
if (mod_flags != 0) {
rc = EINVAL;
@@ -584,6 +595,7 @@ efx_nic_cfg_get(
__in efx_nic_t *enp)
{
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
return (&(enp->en_nic_cfg));
}
@@ -649,6 +661,39 @@ fail1:
return (rc);
}
+ __checkReturn boolean_t
+efx_nic_hw_unavailable(
+ __in efx_nic_t *enp)
+{
+ const efx_nic_ops_t *enop = enp->en_enop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ /* NOTE: can be used by MCDI before NIC probe */
+
+ if (enop->eno_hw_unavailable != NULL) {
+ if ((enop->eno_hw_unavailable)(enp) != B_FALSE)
+ goto unavail;
+ }
+
+ return (B_FALSE);
+
+unavail:
+ return (B_TRUE);
+}
+
+ void
+efx_nic_set_hw_unavailable(
+ __in efx_nic_t *enp)
+{
+ const efx_nic_ops_t *enop = enp->en_enop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+ if (enop->eno_set_hw_unavailable != NULL)
+ enop->eno_set_hw_unavailable(enp);
+}
+
+
#if EFSYS_OPT_DIAG
__checkReturn efx_rc_t
@@ -786,13 +831,12 @@ efx_mcdi_get_loopback_modes(
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
- MC_CMD_GET_LOOPBACK_MODES_OUT_V2_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
+ MC_CMD_GET_LOOPBACK_MODES_OUT_V2_LEN);
efx_qword_t mask;
efx_qword_t modes;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
diff --git a/drivers/net/sfc/base/efx_nvram.c b/drivers/net/sfc/base/efx_nvram.c
index be409c3a..5296c59b 100644
--- a/drivers/net/sfc/base/efx_nvram.c
+++ b/drivers/net/sfc/base/efx_nvram.c
@@ -468,7 +468,7 @@ efx_nvram_validate(
goto fail1;
if (envop->envo_buffer_validate != NULL) {
- if ((rc = envop->envo_buffer_validate(enp, partn,
+ if ((rc = envop->envo_buffer_validate(partn,
partn_data, partn_size)) != 0)
goto fail2;
}
@@ -514,12 +514,11 @@ efx_mcdi_nvram_partitions(
__out unsigned int *npartnp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_PARTITIONS_IN_LEN,
- MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_PARTITIONS_IN_LEN,
+ MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX);
unsigned int npartn;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_NVRAM_PARTITIONS;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_NVRAM_PARTITIONS_IN_LEN;
@@ -577,11 +576,10 @@ efx_mcdi_nvram_metadata(
__in size_t size)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_METADATA_IN_LEN,
- MC_CMD_NVRAM_METADATA_OUT_LENMAX)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_METADATA_IN_LEN,
+ MC_CMD_NVRAM_METADATA_OUT_LENMAX);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_NVRAM_METADATA;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_NVRAM_METADATA_IN_LEN;
@@ -667,12 +665,11 @@ efx_mcdi_nvram_info(
__out_opt uint32_t *erase_sizep,
__out_opt uint32_t *write_sizep)
{
- uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN,
- MC_CMD_NVRAM_INFO_V2_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_INFO_IN_LEN,
+ MC_CMD_NVRAM_INFO_V2_OUT_LEN);
efx_mcdi_req_t req;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_NVRAM_INFO;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
@@ -728,12 +725,11 @@ efx_mcdi_nvram_update_start(
__in efx_nic_t *enp,
__in uint32_t partn)
{
- uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN,
- MC_CMD_NVRAM_UPDATE_START_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN,
+ MC_CMD_NVRAM_UPDATE_START_OUT_LEN);
efx_mcdi_req_t req;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN;
@@ -770,8 +766,8 @@ efx_mcdi_nvram_read(
__in uint32_t mode)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_V2_LEN,
- MC_CMD_NVRAM_READ_OUT_LENMAX)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_READ_IN_V2_LEN,
+ MC_CMD_NVRAM_READ_OUT_LENMAX);
efx_rc_t rc;
if (size > MC_CMD_NVRAM_READ_OUT_LENMAX) {
@@ -779,7 +775,6 @@ efx_mcdi_nvram_read(
goto fail1;
}
- (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_V2_LEN;
@@ -825,11 +820,10 @@ efx_mcdi_nvram_erase(
__in size_t size)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_ERASE_IN_LEN,
- MC_CMD_NVRAM_ERASE_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_ERASE_IN_LEN,
+ MC_CMD_NVRAM_ERASE_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_NVRAM_ERASE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
@@ -865,27 +859,31 @@ efx_mcdi_nvram_write(
__in efx_nic_t *enp,
__in uint32_t partn,
__in uint32_t offset,
- __out_bcount(size) caddr_t data,
+ __in_bcount(size) caddr_t data,
__in size_t size)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MCDI_CTL_SDU_LEN_MAX_V1,
- MCDI_CTL_SDU_LEN_MAX_V2)];
+ uint8_t *payload;
efx_rc_t rc;
size_t max_data_size;
+ size_t payload_len = enp->en_nic_cfg.enc_mcdi_max_payload_length;
- max_data_size = enp->en_nic_cfg.enc_mcdi_max_payload_length
- - MC_CMD_NVRAM_WRITE_IN_LEN(0);
- EFSYS_ASSERT3U(enp->en_nic_cfg.enc_mcdi_max_payload_length, >, 0);
- EFSYS_ASSERT3U(max_data_size, <,
- enp->en_nic_cfg.enc_mcdi_max_payload_length);
+ max_data_size = payload_len - MC_CMD_NVRAM_WRITE_IN_LEN(0);
+ EFSYS_ASSERT3U(payload_len, >, 0);
+ EFSYS_ASSERT3U(max_data_size, <, payload_len);
if (size > max_data_size) {
rc = EINVAL;
goto fail1;
}
- (void) memset(payload, 0, sizeof (payload));
+ EFSYS_KMEM_ALLOC(enp->en_esip, payload_len, payload);
+ if (payload == NULL) {
+ rc = ENOMEM;
+ goto fail2;
+ }
+
+ (void) memset(payload, 0, payload_len);
req.emr_cmd = MC_CMD_NVRAM_WRITE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size);
@@ -903,11 +901,16 @@ efx_mcdi_nvram_write(
if (req.emr_rc != 0) {
rc = req.emr_rc;
- goto fail2;
+ goto fail3;
}
+ EFSYS_KMEM_FREE(enp->en_esip, payload_len, payload);
+
return (0);
+fail3:
+ EFSYS_PROBE(fail3);
+ EFSYS_KMEM_FREE(enp->en_esip, payload_len, payload);
fail2:
EFSYS_PROBE(fail2);
fail1:
@@ -930,12 +933,11 @@ efx_mcdi_nvram_update_finish(
{
const efx_nic_cfg_t *encp = &enp->en_nic_cfg;
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN,
- MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN,
+ MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN);
uint32_t verify_result = MC_CMD_NVRAM_VERIFY_RC_UNKNOWN;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN;
@@ -1001,12 +1003,11 @@ efx_mcdi_nvram_test(
__in uint32_t partn)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN,
- MC_CMD_NVRAM_TEST_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TEST_IN_LEN,
+ MC_CMD_NVRAM_TEST_OUT_LEN);
int result;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_NVRAM_TEST;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
diff --git a/drivers/net/sfc/base/efx_phy.c b/drivers/net/sfc/base/efx_phy.c
index ba2f51c1..36a7bbd3 100644
--- a/drivers/net/sfc/base/efx_phy.c
+++ b/drivers/net/sfc/base/efx_phy.c
@@ -15,6 +15,7 @@ static const efx_phy_ops_t __efx_phy_siena_ops = {
siena_phy_reconfigure, /* epo_reconfigure */
siena_phy_verify, /* epo_verify */
siena_phy_oui_get, /* epo_oui_get */
+ NULL, /* epo_link_state_get */
#if EFSYS_OPT_PHY_STATS
siena_phy_stats_update, /* epo_stats_update */
#endif /* EFSYS_OPT_PHY_STATS */
@@ -34,6 +35,7 @@ static const efx_phy_ops_t __efx_phy_ef10_ops = {
ef10_phy_reconfigure, /* epo_reconfigure */
ef10_phy_verify, /* epo_verify */
ef10_phy_oui_get, /* epo_oui_get */
+ ef10_phy_link_state_get, /* epo_link_state_get */
#if EFSYS_OPT_PHY_STATS
ef10_phy_stats_update, /* epo_stats_update */
#endif /* EFSYS_OPT_PHY_STATS */
@@ -286,8 +288,8 @@ efx_phy_media_type_get(
efx_phy_module_get_info(
__in efx_nic_t *enp,
__in uint8_t dev_addr,
- __in uint8_t offset,
- __in uint8_t len,
+ __in size_t offset,
+ __in size_t len,
__out_bcount(len) uint8_t *data)
{
efx_rc_t rc;
@@ -295,7 +297,8 @@ efx_phy_module_get_info(
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT(data != NULL);
- if ((uint32_t)offset + len > 0xff) {
+ if ((offset > EFX_PHY_MEDIA_INFO_MAX_OFFSET) ||
+ ((offset + len) > EFX_PHY_MEDIA_INFO_MAX_OFFSET)) {
rc = EINVAL;
goto fail1;
}
@@ -314,6 +317,57 @@ fail1:
return (rc);
}
+ __checkReturn efx_rc_t
+efx_phy_fec_type_get(
+ __in efx_nic_t *enp,
+ __out efx_phy_fec_type_t *typep)
+{
+ efx_rc_t rc;
+ efx_phy_link_state_t epls;
+
+ if ((rc = efx_phy_link_state_get(enp, &epls)) != 0)
+ goto fail1;
+
+ *typep = epls.epls_fec;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+efx_phy_link_state_get(
+ __in efx_nic_t *enp,
+ __out efx_phy_link_state_t *eplsp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ const efx_phy_ops_t *epop = epp->ep_epop;
+ efx_rc_t rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+
+ if (epop->epo_link_state_get == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = epop->epo_link_state_get(enp, eplsp)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
#if EFSYS_OPT_PHY_STATS
#if EFSYS_OPT_NAMES
diff --git a/drivers/net/sfc/base/efx_port.c b/drivers/net/sfc/base/efx_port.c
index 33a1a084..5fff932b 100644
--- a/drivers/net/sfc/base/efx_port.c
+++ b/drivers/net/sfc/base/efx_port.c
@@ -37,7 +37,7 @@ efx_port_init(
epp->ep_emop->emo_reconfigure(enp);
/* Pick up current phy capababilities */
- efx_port_poll(enp, NULL);
+ (void) efx_port_poll(enp, NULL);
/*
* Turn on the PHY if available, otherwise reset it, and
diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c
index 4fd73bab..04bc7aed 100644
--- a/drivers/net/sfc/base/efx_rx.c
+++ b/drivers/net/sfc/base/efx_rx.c
@@ -298,84 +298,104 @@ fail1:
efx_rx_scale_hash_flags_get(
__in efx_nic_t *enp,
__in efx_rx_hash_alg_t hash_alg,
- __inout_ecount(EFX_RX_HASH_NFLAGS) unsigned int *flags,
+ __out_ecount_part(max_nflags, *nflagsp) unsigned int *flagsp,
+ __in unsigned int max_nflags,
__out unsigned int *nflagsp)
{
efx_nic_cfg_t *encp = &enp->en_nic_cfg;
- boolean_t l4;
- boolean_t additional_modes;
- unsigned int *entryp = flags;
+ unsigned int nflags = 0;
efx_rc_t rc;
- if (flags == NULL || nflagsp == NULL) {
+ if (flagsp == NULL || nflagsp == NULL) {
rc = EINVAL;
goto fail1;
}
- l4 = encp->enc_rx_scale_l4_hash_supported;
- additional_modes = encp->enc_rx_scale_additional_modes_supported;
+ if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0) {
+ nflags = 0;
+ goto done;
+ }
-#define LIST_FLAGS(_entryp, _class, _l4_hashing, _additional_modes) \
- do { \
- if (_l4_hashing) { \
- *(_entryp++) = EFX_RX_HASH(_class, 4TUPLE); \
- \
- if (_additional_modes) { \
- *(_entryp++) = \
- EFX_RX_HASH(_class, 2TUPLE_DST); \
- *(_entryp++) = \
- EFX_RX_HASH(_class, 2TUPLE_SRC); \
- } \
- } \
- \
- *(_entryp++) = EFX_RX_HASH(_class, 2TUPLE); \
- \
- if (_additional_modes) { \
- *(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_DST); \
- *(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_SRC); \
- } \
- \
- *(_entryp++) = EFX_RX_HASH(_class, DISABLE); \
- \
- _NOTE(CONSTANTCONDITION) \
+ /* Helper to add flags word to flags array without buffer overflow */
+#define INSERT_FLAGS(_flags) \
+ do { \
+ if (nflags >= max_nflags) { \
+ rc = E2BIG; \
+ goto fail2; \
+ } \
+ *(flagsp + nflags) = (_flags); \
+ nflags++; \
+ \
+ _NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
- switch (hash_alg) {
- case EFX_RX_HASHALG_PACKED_STREAM:
- if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0)
- break;
- /* FALLTHRU */
- case EFX_RX_HASHALG_TOEPLITZ:
- if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0)
- break;
+ if (encp->enc_rx_scale_l4_hash_supported != B_FALSE) {
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 4TUPLE));
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 4TUPLE));
+ }
- LIST_FLAGS(entryp, IPV4_TCP, l4, additional_modes);
- LIST_FLAGS(entryp, IPV6_TCP, l4, additional_modes);
+ if ((encp->enc_rx_scale_l4_hash_supported != B_FALSE) &&
+ (encp->enc_rx_scale_additional_modes_supported != B_FALSE)) {
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 2TUPLE_DST));
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 2TUPLE_SRC));
- if (additional_modes) {
- LIST_FLAGS(entryp, IPV4_UDP, l4, additional_modes);
- LIST_FLAGS(entryp, IPV6_UDP, l4, additional_modes);
- }
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 2TUPLE_DST));
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 2TUPLE_SRC));
- LIST_FLAGS(entryp, IPV4, B_FALSE, additional_modes);
- LIST_FLAGS(entryp, IPV6, B_FALSE, additional_modes);
- break;
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 4TUPLE));
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 2TUPLE_DST));
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 2TUPLE_SRC));
- default:
- rc = EINVAL;
- goto fail2;
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 4TUPLE));
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 2TUPLE_DST));
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 2TUPLE_SRC));
+ }
+
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 2TUPLE));
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 2TUPLE));
+
+ INSERT_FLAGS(EFX_RX_HASH(IPV4, 2TUPLE));
+ INSERT_FLAGS(EFX_RX_HASH(IPV6, 2TUPLE));
+
+ if (encp->enc_rx_scale_additional_modes_supported != B_FALSE) {
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 1TUPLE_DST));
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 1TUPLE_SRC));
+
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 1TUPLE_DST));
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 1TUPLE_SRC));
+
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 2TUPLE));
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 1TUPLE_DST));
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 1TUPLE_SRC));
+
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 2TUPLE));
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 1TUPLE_DST));
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 1TUPLE_SRC));
+
+ INSERT_FLAGS(EFX_RX_HASH(IPV4, 1TUPLE_DST));
+ INSERT_FLAGS(EFX_RX_HASH(IPV4, 1TUPLE_SRC));
+
+ INSERT_FLAGS(EFX_RX_HASH(IPV6, 1TUPLE_DST));
+ INSERT_FLAGS(EFX_RX_HASH(IPV6, 1TUPLE_SRC));
}
-#undef LIST_FLAGS
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, DISABLE));
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, DISABLE));
+
+ INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, DISABLE));
+ INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, DISABLE));
- *nflagsp = (unsigned int)(entryp - flags);
- EFSYS_ASSERT3U(*nflagsp, <=, EFX_RX_HASH_NFLAGS);
+ INSERT_FLAGS(EFX_RX_HASH(IPV4, DISABLE));
+ INSERT_FLAGS(EFX_RX_HASH(IPV6, DISABLE));
+#undef INSERT_FLAGS
+
+done:
+ *nflagsp = nflags;
return (0);
fail2:
EFSYS_PROBE(fail2);
-
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
@@ -512,9 +532,8 @@ efx_rx_scale_mode_set(
__in efx_rx_hash_type_t type,
__in boolean_t insert)
{
+ efx_nic_cfg_t *encp = &enp->en_nic_cfg;
const efx_rx_ops_t *erxop = enp->en_erxop;
- unsigned int type_flags[EFX_RX_HASH_NFLAGS];
- unsigned int type_nflags;
efx_rx_hash_type_t type_check;
unsigned int i;
efx_rc_t rc;
@@ -533,46 +552,60 @@ efx_rx_scale_mode_set(
}
/*
- * Translate legacy flags to the new representation
- * so that chip-specific handlers will consider the
- * new flags only.
+ * If RSS hash type is represented by additional bits
+ * in the value, the latter need to be verified since
+ * not all bit combinations are valid RSS modes. Also,
+ * depending on the firmware, some valid combinations
+ * may be unsupported. Discern additional bits in the
+ * type value and try to recognise valid combinations.
+ * If some bits remain unrecognised, report the error.
*/
- if (type & EFX_RX_HASH_IPV4) {
- type |= EFX_RX_HASH(IPV4, 2TUPLE);
- type |= EFX_RX_HASH(IPV4_TCP, 2TUPLE);
- type |= EFX_RX_HASH(IPV4_UDP, 2TUPLE);
- }
-
- if (type & EFX_RX_HASH_TCPIPV4)
- type |= EFX_RX_HASH(IPV4_TCP, 4TUPLE);
+ type_check = type & ~EFX_RX_HASH_LEGACY_MASK;
+ if (type_check != 0) {
+ unsigned int type_flags[EFX_RX_HASH_NFLAGS];
+ unsigned int type_nflags;
- if (type & EFX_RX_HASH_IPV6) {
- type |= EFX_RX_HASH(IPV6, 2TUPLE);
- type |= EFX_RX_HASH(IPV6_TCP, 2TUPLE);
- type |= EFX_RX_HASH(IPV6_UDP, 2TUPLE);
- }
+ rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags,
+ EFX_ARRAY_SIZE(type_flags), &type_nflags);
+ if (rc != 0)
+ goto fail2;
- if (type & EFX_RX_HASH_TCPIPV6)
- type |= EFX_RX_HASH(IPV6_TCP, 4TUPLE);
+ for (i = 0; i < type_nflags; ++i) {
+ if ((type_check & type_flags[i]) == type_flags[i])
+ type_check &= ~(type_flags[i]);
+ }
- type &= ~EFX_RX_HASH_LEGACY_MASK;
- type_check = type;
+ if (type_check != 0) {
+ rc = EINVAL;
+ goto fail3;
+ }
+ }
/*
- * Get the list of supported hash flags and sanitise the input.
+ * Translate EFX_RX_HASH() flags to their legacy counterparts
+ * provided that the FW claims no support for additional modes.
*/
- rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags, &type_nflags);
- if (rc != 0)
- goto fail2;
-
- for (i = 0; i < type_nflags; ++i) {
- if ((type_check & type_flags[i]) == type_flags[i])
- type_check &= ~(type_flags[i]);
- }
+ if (encp->enc_rx_scale_additional_modes_supported == B_FALSE) {
+ efx_rx_hash_type_t t_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE) |
+ EFX_RX_HASH(IPV4_TCP, 2TUPLE);
+ efx_rx_hash_type_t t_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE) |
+ EFX_RX_HASH(IPV6_TCP, 2TUPLE);
+ efx_rx_hash_type_t t_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE);
+ efx_rx_hash_type_t t_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE);
+
+ if ((type & t_ipv4) == t_ipv4)
+ type |= EFX_RX_HASH_IPV4;
+ if ((type & t_ipv6) == t_ipv6)
+ type |= EFX_RX_HASH_IPV6;
+
+ if (encp->enc_rx_scale_l4_hash_supported == B_TRUE) {
+ if ((type & t_ipv4_tcp) == t_ipv4_tcp)
+ type |= EFX_RX_HASH_TCPIPV4;
+ if ((type & t_ipv6_tcp) == t_ipv6_tcp)
+ type |= EFX_RX_HASH_TCPIPV6;
+ }
- if (type_check != 0) {
- rc = EINVAL;
- goto fail3;
+ type &= EFX_RX_HASH_LEGACY_MASK;
}
if (erxop->erxo_scale_mode_set != NULL) {
@@ -831,7 +864,7 @@ efx_rx_qcreate_packed_stream(
{
efx_rxq_type_data_t type_data;
- memset(&type_data, 0, sizeof(type_data));
+ memset(&type_data, 0, sizeof (type_data));
type_data.ertd_packed_stream.eps_buf_size = ps_buf_size;
@@ -867,7 +900,7 @@ efx_rx_qcreate_es_super_buffer(
goto fail1;
}
- memset(&type_data, 0, sizeof(type_data));
+ memset(&type_data, 0, sizeof (type_data));
type_data.ertd_es_super_buffer.eessb_bufs_per_desc = n_bufs_per_desc;
type_data.ertd_es_super_buffer.eessb_max_dma_len = max_dma_len;
@@ -1090,10 +1123,6 @@ siena_rx_scale_mode_set(
__in efx_rx_hash_type_t type,
__in boolean_t insert)
{
- efx_rx_hash_type_t type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE);
- efx_rx_hash_type_t type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE);
- efx_rx_hash_type_t type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE);
- efx_rx_hash_type_t type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE);
efx_rc_t rc;
if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
@@ -1108,12 +1137,12 @@ siena_rx_scale_mode_set(
case EFX_RX_HASHALG_TOEPLITZ:
EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert,
- (type & type_ipv4) == type_ipv4,
- (type & type_ipv4_tcp) == type_ipv4_tcp);
+ (type & EFX_RX_HASH_IPV4) ? B_TRUE : B_FALSE,
+ (type & EFX_RX_HASH_TCPIPV4) ? B_TRUE : B_FALSE);
EFX_RX_TOEPLITZ_IPV6_HASH(enp,
- (type & type_ipv6) == type_ipv6,
- (type & type_ipv6_tcp) == type_ipv6_tcp,
+ (type & EFX_RX_HASH_IPV6) ? B_TRUE : B_FALSE,
+ (type & EFX_RX_HASH_TCPIPV6) ? B_TRUE : B_FALSE,
rc);
if (rc != 0)
goto fail2;
diff --git a/drivers/net/sfc/base/efx_tunnel.c b/drivers/net/sfc/base/efx_tunnel.c
index 399fd540..edb6be02 100644
--- a/drivers/net/sfc/base/efx_tunnel.c
+++ b/drivers/net/sfc/base/efx_tunnel.c
@@ -40,8 +40,9 @@ efx_mcdi_set_tunnel_encap_udp_ports(
__out boolean_t *resetting)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMAX,
- MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload,
+ MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMAX,
+ MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_LEN);
efx_word_t flags;
efx_rc_t rc;
unsigned int i;
@@ -52,7 +53,6 @@ efx_mcdi_set_tunnel_encap_udp_ports(
else
entries_num = etcp->etc_udp_entries_num;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS;
req.emr_in_buf = payload;
req.emr_in_length =
diff --git a/drivers/net/sfc/base/efx_tx.c b/drivers/net/sfc/base/efx_tx.c
index da37580a..bf1180a1 100644
--- a/drivers/net/sfc/base/efx_tx.c
+++ b/drivers/net/sfc/base/efx_tx.c
@@ -572,19 +572,10 @@ efx_tx_qdesc_post(
{
efx_nic_t *enp = etp->et_enp;
const efx_tx_ops_t *etxop = enp->en_etxop;
- efx_rc_t rc;
EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
- if ((rc = etxop->etxo_qdesc_post(etp, ed,
- ndescs, completed, addedp)) != 0)
- goto fail1;
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
- return (rc);
+ return (etxop->etxo_qdesc_post(etp, ed, ndescs, completed, addedp));
}
void
@@ -763,10 +754,9 @@ siena_tx_qpost(
{
unsigned int added = *addedp;
unsigned int i;
- int rc = ENOSPC;
if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1))
- goto fail1;
+ return (ENOSPC);
for (i = 0; i < ndescs; i++) {
efx_buffer_t *ebp = &eb[i];
@@ -788,11 +778,6 @@ siena_tx_qpost(
*addedp = added;
return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
}
static void
diff --git a/drivers/net/sfc/base/hunt_nic.c b/drivers/net/sfc/base/hunt_nic.c
index 16ea81d2..ca30e90f 100644
--- a/drivers/net/sfc/base/hunt_nic.c
+++ b/drivers/net/sfc/base/hunt_nic.c
@@ -20,7 +20,6 @@ hunt_nic_get_required_pcie_bandwidth(
__out uint32_t *bandwidth_mbpsp)
{
uint32_t port_modes;
- uint32_t max_port_mode;
uint32_t bandwidth;
efx_rc_t rc;
@@ -30,7 +29,8 @@ hunt_nic_get_required_pcie_bandwidth(
* capable mode is in use.
*/
- if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, NULL)) != 0) {
+ if ((rc = efx_mcdi_get_port_modes(enp, &port_modes,
+ NULL, NULL)) != 0) {
/* No port mode info available */
bandwidth = 0;
goto out;
@@ -46,17 +46,13 @@ hunt_nic_get_required_pcie_bandwidth(
goto fail1;
} else {
if (port_modes & (1U << TLV_PORT_MODE_40G)) {
- max_port_mode = TLV_PORT_MODE_40G;
+ bandwidth = 40000;
} else if (port_modes & (1U << TLV_PORT_MODE_10G_10G_10G_10G)) {
- max_port_mode = TLV_PORT_MODE_10G_10G_10G_10G;
+ bandwidth = 4 * 10000;
} else {
/* Assume two 10G ports */
- max_port_mode = TLV_PORT_MODE_10G_10G;
+ bandwidth = 2 * 10000;
}
-
- if ((rc = ef10_nic_get_port_mode_bandwidth(max_port_mode,
- &bandwidth)) != 0)
- goto fail2;
}
out:
@@ -64,8 +60,6 @@ out:
return (0);
-fail2:
- EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
@@ -189,6 +183,9 @@ hunt_board_cfg(
encp->enc_bug61265_workaround = B_FALSE; /* Medford only */
+ /* Checksums for TSO sends can be incorrect on Huntington. */
+ encp->enc_bug61297_workaround = B_TRUE;
+
/* Alignment for receive packet DMA buffers */
encp->enc_rx_buf_align_start = 1;
encp->enc_rx_buf_align_end = 64; /* RX DMA end padding */
diff --git a/drivers/net/sfc/base/mc_driver_pcol_strs.h b/drivers/net/sfc/base/mc_driver_pcol_strs.h
new file mode 100644
index 00000000..73d633cb
--- /dev/null
+++ b/drivers/net/sfc/base/mc_driver_pcol_strs.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright 2008-2018 Solarflare Communications Inc.
+ * All rights reserved.
+ */
+
+/*
+ * This file is automatically generated. DO NOT EDIT IT.
+ * To make changes, edit the .yml files under firmwaresrc doc/mcdi/ and
+ * rebuild this file with "make -C doc mcdiheaders".
+ *
+ * The version of this file has MCDI strings really used in the libefx.
+ */
+
+#ifndef _MC_DRIVER_PCOL_STRS_H
+#define _MC_DRIVER_PCOL_STRS_H
+
+#define MC_CMD_SENSOR_CONTROLLER_TEMP_ENUM_STR "Controller temperature: degC"
+#define MC_CMD_SENSOR_PHY_COMMON_TEMP_ENUM_STR "Phy common temperature: degC"
+#define MC_CMD_SENSOR_CONTROLLER_COOLING_ENUM_STR "Controller cooling: bool"
+#define MC_CMD_SENSOR_PHY0_TEMP_ENUM_STR "Phy 0 temperature: degC"
+#define MC_CMD_SENSOR_PHY0_COOLING_ENUM_STR "Phy 0 cooling: bool"
+#define MC_CMD_SENSOR_PHY1_TEMP_ENUM_STR "Phy 1 temperature: degC"
+#define MC_CMD_SENSOR_PHY1_COOLING_ENUM_STR "Phy 1 cooling: bool"
+#define MC_CMD_SENSOR_IN_1V0_ENUM_STR "1.0v power: mV"
+#define MC_CMD_SENSOR_IN_1V2_ENUM_STR "1.2v power: mV"
+#define MC_CMD_SENSOR_IN_1V8_ENUM_STR "1.8v power: mV"
+#define MC_CMD_SENSOR_IN_2V5_ENUM_STR "2.5v power: mV"
+#define MC_CMD_SENSOR_IN_3V3_ENUM_STR "3.3v power: mV"
+#define MC_CMD_SENSOR_IN_12V0_ENUM_STR "12v power: mV"
+#define MC_CMD_SENSOR_IN_1V2A_ENUM_STR "1.2v analogue power: mV"
+#define MC_CMD_SENSOR_IN_VREF_ENUM_STR "reference voltage: mV"
+#define MC_CMD_SENSOR_OUT_VAOE_ENUM_STR "AOE FPGA power: mV"
+#define MC_CMD_SENSOR_AOE_TEMP_ENUM_STR "AOE FPGA temperature: degC"
+#define MC_CMD_SENSOR_PSU_AOE_TEMP_ENUM_STR "AOE FPGA PSU temperature: degC"
+#define MC_CMD_SENSOR_PSU_TEMP_ENUM_STR "AOE PSU temperature: degC"
+#define MC_CMD_SENSOR_FAN_0_ENUM_STR "Fan 0 speed: RPM"
+#define MC_CMD_SENSOR_FAN_1_ENUM_STR "Fan 1 speed: RPM"
+#define MC_CMD_SENSOR_FAN_2_ENUM_STR "Fan 2 speed: RPM"
+#define MC_CMD_SENSOR_FAN_3_ENUM_STR "Fan 3 speed: RPM"
+#define MC_CMD_SENSOR_FAN_4_ENUM_STR "Fan 4 speed: RPM"
+#define MC_CMD_SENSOR_IN_VAOE_ENUM_STR "AOE FPGA input power: mV"
+#define MC_CMD_SENSOR_OUT_IAOE_ENUM_STR "AOE FPGA current: mA"
+#define MC_CMD_SENSOR_IN_IAOE_ENUM_STR "AOE FPGA input current: mA"
+#define MC_CMD_SENSOR_NIC_POWER_ENUM_STR "NIC power consumption: W"
+#define MC_CMD_SENSOR_IN_0V9_ENUM_STR "0.9v power voltage: mV"
+#define MC_CMD_SENSOR_IN_I0V9_ENUM_STR "0.9v power current: mA"
+#define MC_CMD_SENSOR_IN_I1V2_ENUM_STR "1.2v power current: mA"
+#define MC_CMD_SENSOR_PAGE0_NEXT_ENUM_STR "Not a sensor: reserved for the next page flag"
+#define MC_CMD_SENSOR_IN_0V9_ADC_ENUM_STR "0.9v power voltage (at ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_2_TEMP_ENUM_STR "Controller temperature 2: degC"
+#define MC_CMD_SENSOR_VREG_INTERNAL_TEMP_ENUM_STR "Voltage regulator internal temperature: degC"
+#define MC_CMD_SENSOR_VREG_0V9_TEMP_ENUM_STR "0.9V voltage regulator temperature: degC"
+#define MC_CMD_SENSOR_VREG_1V2_TEMP_ENUM_STR "1.2V voltage regulator temperature: degC"
+#define MC_CMD_SENSOR_CONTROLLER_VPTAT_ENUM_STR "controller internal temperature sensor voltage (internal ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_ENUM_STR "controller internal temperature (internal ADC): degC"
+#define MC_CMD_SENSOR_CONTROLLER_VPTAT_EXTADC_ENUM_STR "controller internal temperature sensor voltage (external ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_EXTADC_ENUM_STR "controller internal temperature (external ADC): degC"
+#define MC_CMD_SENSOR_AMBIENT_TEMP_ENUM_STR "ambient temperature: degC"
+#define MC_CMD_SENSOR_AIRFLOW_ENUM_STR "air flow: bool"
+#define MC_CMD_SENSOR_VDD08D_VSS08D_CSR_ENUM_STR "voltage between VSS08D and VSS08D at CSR: mV"
+#define MC_CMD_SENSOR_VDD08D_VSS08D_CSR_EXTADC_ENUM_STR "voltage between VSS08D and VSS08D at CSR (external ADC): mV"
+#define MC_CMD_SENSOR_HOTPOINT_TEMP_ENUM_STR "Hotpoint temperature: degC"
+#define MC_CMD_SENSOR_PHY_POWER_PORT0_ENUM_STR "Port 0 PHY power switch over-current: bool"
+#define MC_CMD_SENSOR_PHY_POWER_PORT1_ENUM_STR "Port 1 PHY power switch over-current: bool"
+#define MC_CMD_SENSOR_MUM_VCC_ENUM_STR "Mop-up microcontroller reference voltage: mV"
+#define MC_CMD_SENSOR_IN_0V9_A_ENUM_STR "0.9v power phase A voltage: mV"
+#define MC_CMD_SENSOR_IN_I0V9_A_ENUM_STR "0.9v power phase A current: mA"
+#define MC_CMD_SENSOR_VREG_0V9_A_TEMP_ENUM_STR "0.9V voltage regulator phase A temperature: degC"
+#define MC_CMD_SENSOR_IN_0V9_B_ENUM_STR "0.9v power phase B voltage: mV"
+#define MC_CMD_SENSOR_IN_I0V9_B_ENUM_STR "0.9v power phase B current: mA"
+#define MC_CMD_SENSOR_VREG_0V9_B_TEMP_ENUM_STR "0.9V voltage regulator phase B temperature: degC"
+#define MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_ENUM_STR "CCOM AVREG 1v2 supply (interval ADC): mV"
+#define MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_EXTADC_ENUM_STR "CCOM AVREG 1v2 supply (external ADC): mV"
+#define MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_ENUM_STR "CCOM AVREG 1v8 supply (interval ADC): mV"
+#define MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_EXTADC_ENUM_STR "CCOM AVREG 1v8 supply (external ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_RTS_ENUM_STR "CCOM RTS temperature: degC"
+#define MC_CMD_SENSOR_PAGE1_NEXT_ENUM_STR "Not a sensor: reserved for the next page flag"
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_ENUM_STR "controller internal temperature sensor voltage on master core (internal ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_ENUM_STR "controller internal temperature on master core (internal ADC): degC"
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_EXTADC_ENUM_STR "controller internal temperature sensor voltage on master core (external ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC_ENUM_STR "controller internal temperature on master core (external ADC): degC"
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_ENUM_STR "controller internal temperature on slave core sensor voltage (internal ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_ENUM_STR "controller internal temperature on slave core (internal ADC): degC"
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_EXTADC_ENUM_STR "controller internal temperature on slave core sensor voltage (external ADC): mV"
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC_ENUM_STR "controller internal temperature on slave core (external ADC): degC"
+#define MC_CMD_SENSOR_SODIMM_VOUT_ENUM_STR "Voltage supplied to the SODIMMs from their power supply: mV"
+#define MC_CMD_SENSOR_SODIMM_0_TEMP_ENUM_STR "Temperature of SODIMM 0 (if installed): degC"
+#define MC_CMD_SENSOR_SODIMM_1_TEMP_ENUM_STR "Temperature of SODIMM 1 (if installed): degC"
+#define MC_CMD_SENSOR_PHY0_VCC_ENUM_STR "Voltage supplied to the QSFP #0 from their power supply: mV"
+#define MC_CMD_SENSOR_PHY1_VCC_ENUM_STR "Voltage supplied to the QSFP #1 from their power supply: mV"
+#define MC_CMD_SENSOR_CONTROLLER_TDIODE_TEMP_ENUM_STR "Controller die temperature (TDIODE): degC"
+#define MC_CMD_SENSOR_BOARD_FRONT_TEMP_ENUM_STR "Board temperature (front): degC"
+#define MC_CMD_SENSOR_BOARD_BACK_TEMP_ENUM_STR "Board temperature (back): degC"
+#define MC_CMD_SENSOR_IN_I1V8_ENUM_STR "1.8v power current: mA"
+#define MC_CMD_SENSOR_IN_I2V5_ENUM_STR "2.5v power current: mA"
+#define MC_CMD_SENSOR_IN_I3V3_ENUM_STR "3.3v power current: mA"
+#define MC_CMD_SENSOR_IN_I12V0_ENUM_STR "12v power current: mA"
+#define MC_CMD_SENSOR_IN_1V3_ENUM_STR "1.3v power: mV"
+#define MC_CMD_SENSOR_IN_I1V3_ENUM_STR "1.3v power current: mA"
+
+#endif /* _MC_DRIVER_PCOL_STRS_H */
diff --git a/drivers/net/sfc/base/mcdi_mon.c b/drivers/net/sfc/base/mcdi_mon.c
index 940bd026..b53de0d6 100644
--- a/drivers/net/sfc/base/mcdi_mon.c
+++ b/drivers/net/sfc/base/mcdi_mon.c
@@ -6,141 +6,15 @@
#include "efx.h"
#include "efx_impl.h"
+#include "mcdi_mon.h"
#if EFSYS_OPT_MON_MCDI
#if EFSYS_OPT_MON_STATS
-#define MCDI_MON_NEXT_PAGE ((uint16_t)0xfffe)
-#define MCDI_MON_INVALID_SENSOR ((uint16_t)0xfffd)
-#define MCDI_MON_PAGE_SIZE 0x20
-
-/* Bitmasks of valid port(s) for each sensor */
-#define MCDI_MON_PORT_NONE (0x00)
-#define MCDI_MON_PORT_P1 (0x01)
-#define MCDI_MON_PORT_P2 (0x02)
-#define MCDI_MON_PORT_P3 (0x04)
-#define MCDI_MON_PORT_P4 (0x08)
-#define MCDI_MON_PORT_Px (0xFFFF)
-
/* Get port mask from one-based MCDI port number */
#define MCDI_MON_PORT_MASK(_emip) (1U << ((_emip)->emi_port - 1))
-/* Entry for MCDI sensor in sensor map */
-#define STAT(portmask, stat) \
- { (MCDI_MON_PORT_##portmask), (EFX_MON_STAT_##stat) }
-
-/* Entry for sensor next page flag in sensor map */
-#define STAT_NEXT_PAGE() \
- { MCDI_MON_PORT_NONE, MCDI_MON_NEXT_PAGE }
-
-/* Placeholder for gaps in the array */
-#define STAT_NO_SENSOR() \
- { MCDI_MON_PORT_NONE, MCDI_MON_INVALID_SENSOR }
-
-/* Map from MC sensors to monitor statistics */
-static const struct mcdi_sensor_map_s {
- uint16_t msm_port_mask;
- uint16_t msm_stat;
-} mcdi_sensor_map[] = {
- /* Sensor page 0 MC_CMD_SENSOR_xxx */
- STAT(Px, INT_TEMP), /* 0x00 CONTROLLER_TEMP */
- STAT(Px, EXT_TEMP), /* 0x01 PHY_COMMON_TEMP */
- STAT(Px, INT_COOLING), /* 0x02 CONTROLLER_COOLING */
- STAT(P1, EXT_TEMP), /* 0x03 PHY0_TEMP */
- STAT(P1, EXT_COOLING), /* 0x04 PHY0_COOLING */
- STAT(P2, EXT_TEMP), /* 0x05 PHY1_TEMP */
- STAT(P2, EXT_COOLING), /* 0x06 PHY1_COOLING */
- STAT(Px, 1V), /* 0x07 IN_1V0 */
- STAT(Px, 1_2V), /* 0x08 IN_1V2 */
- STAT(Px, 1_8V), /* 0x09 IN_1V8 */
- STAT(Px, 2_5V), /* 0x0a IN_2V5 */
- STAT(Px, 3_3V), /* 0x0b IN_3V3 */
- STAT(Px, 12V), /* 0x0c IN_12V0 */
- STAT(Px, 1_2VA), /* 0x0d IN_1V2A */
- STAT(Px, VREF), /* 0x0e IN_VREF */
- STAT(Px, VAOE), /* 0x0f OUT_VAOE */
- STAT(Px, AOE_TEMP), /* 0x10 AOE_TEMP */
- STAT(Px, PSU_AOE_TEMP), /* 0x11 PSU_AOE_TEMP */
- STAT(Px, PSU_TEMP), /* 0x12 PSU_TEMP */
- STAT(Px, FAN0), /* 0x13 FAN_0 */
- STAT(Px, FAN1), /* 0x14 FAN_1 */
- STAT(Px, FAN2), /* 0x15 FAN_2 */
- STAT(Px, FAN3), /* 0x16 FAN_3 */
- STAT(Px, FAN4), /* 0x17 FAN_4 */
- STAT(Px, VAOE_IN), /* 0x18 IN_VAOE */
- STAT(Px, IAOE), /* 0x19 OUT_IAOE */
- STAT(Px, IAOE_IN), /* 0x1a IN_IAOE */
- STAT(Px, NIC_POWER), /* 0x1b NIC_POWER */
- STAT(Px, 0_9V), /* 0x1c IN_0V9 */
- STAT(Px, I0_9V), /* 0x1d IN_I0V9 */
- STAT(Px, I1_2V), /* 0x1e IN_I1V2 */
- STAT_NEXT_PAGE(), /* 0x1f Next page flag (not a sensor) */
-
- /* Sensor page 1 MC_CMD_SENSOR_xxx */
- STAT(Px, 0_9V_ADC), /* 0x20 IN_0V9_ADC */
- STAT(Px, INT_TEMP2), /* 0x21 CONTROLLER_2_TEMP */
- STAT(Px, VREG_TEMP), /* 0x22 VREG_INTERNAL_TEMP */
- STAT(Px, VREG_0_9V_TEMP), /* 0x23 VREG_0V9_TEMP */
- STAT(Px, VREG_1_2V_TEMP), /* 0x24 VREG_1V2_TEMP */
- STAT(Px, INT_VPTAT), /* 0x25 CTRLR. VPTAT */
- STAT(Px, INT_ADC_TEMP), /* 0x26 CTRLR. INTERNAL_TEMP */
- STAT(Px, EXT_VPTAT), /* 0x27 CTRLR. VPTAT_EXTADC */
- STAT(Px, EXT_ADC_TEMP), /* 0x28 CTRLR. INTERNAL_TEMP_EXTADC */
- STAT(Px, AMBIENT_TEMP), /* 0x29 AMBIENT_TEMP */
- STAT(Px, AIRFLOW), /* 0x2a AIRFLOW */
- STAT(Px, VDD08D_VSS08D_CSR), /* 0x2b VDD08D_VSS08D_CSR */
- STAT(Px, VDD08D_VSS08D_CSR_EXTADC), /* 0x2c VDD08D_VSS08D_CSR_EXTADC */
- STAT(Px, HOTPOINT_TEMP), /* 0x2d HOTPOINT_TEMP */
- STAT(P1, PHY_POWER_SWITCH_PORT0), /* 0x2e PHY_POWER_SWITCH_PORT0 */
- STAT(P2, PHY_POWER_SWITCH_PORT1), /* 0x2f PHY_POWER_SWITCH_PORT1 */
- STAT(Px, MUM_VCC), /* 0x30 MUM_VCC */
- STAT(Px, 0V9_A), /* 0x31 0V9_A */
- STAT(Px, I0V9_A), /* 0x32 I0V9_A */
- STAT(Px, 0V9_A_TEMP), /* 0x33 0V9_A_TEMP */
- STAT(Px, 0V9_B), /* 0x34 0V9_B */
- STAT(Px, I0V9_B), /* 0x35 I0V9_B */
- STAT(Px, 0V9_B_TEMP), /* 0x36 0V9_B_TEMP */
- STAT(Px, CCOM_AVREG_1V2_SUPPLY), /* 0x37 CCOM_AVREG_1V2_SUPPLY */
- STAT(Px, CCOM_AVREG_1V2_SUPPLY_EXT_ADC),
- /* 0x38 CCOM_AVREG_1V2_SUPPLY_EXT_ADC */
- STAT(Px, CCOM_AVREG_1V8_SUPPLY), /* 0x39 CCOM_AVREG_1V8_SUPPLY */
- STAT(Px, CCOM_AVREG_1V8_SUPPLY_EXT_ADC),
- /* 0x3a CCOM_AVREG_1V8_SUPPLY_EXT_ADC */
- STAT_NO_SENSOR(), /* 0x3b (no sensor) */
- STAT_NO_SENSOR(), /* 0x3c (no sensor) */
- STAT_NO_SENSOR(), /* 0x3d (no sensor) */
- STAT_NO_SENSOR(), /* 0x3e (no sensor) */
- STAT_NEXT_PAGE(), /* 0x3f Next page flag (not a sensor) */
-
- /* Sensor page 2 MC_CMD_SENSOR_xxx */
- STAT(Px, CONTROLLER_MASTER_VPTAT), /* 0x40 MASTER_VPTAT */
- STAT(Px, CONTROLLER_MASTER_INTERNAL_TEMP), /* 0x41 MASTER_INT_TEMP */
- STAT(Px, CONTROLLER_MASTER_VPTAT_EXT_ADC), /* 0x42 MAST_VPTAT_EXT_ADC */
- STAT(Px, CONTROLLER_MASTER_INTERNAL_TEMP_EXT_ADC),
- /* 0x43 MASTER_INTERNAL_TEMP_EXT_ADC */
- STAT(Px, CONTROLLER_SLAVE_VPTAT), /* 0x44 SLAVE_VPTAT */
- STAT(Px, CONTROLLER_SLAVE_INTERNAL_TEMP), /* 0x45 SLAVE_INTERNAL_TEMP */
- STAT(Px, CONTROLLER_SLAVE_VPTAT_EXT_ADC), /* 0x46 SLAVE_VPTAT_EXT_ADC */
- STAT(Px, CONTROLLER_SLAVE_INTERNAL_TEMP_EXT_ADC),
- /* 0x47 SLAVE_INTERNAL_TEMP_EXT_ADC */
- STAT_NO_SENSOR(), /* 0x48 (no sensor) */
- STAT(Px, SODIMM_VOUT), /* 0x49 SODIMM_VOUT */
- STAT(Px, SODIMM_0_TEMP), /* 0x4a SODIMM_0_TEMP */
- STAT(Px, SODIMM_1_TEMP), /* 0x4b SODIMM_1_TEMP */
- STAT(Px, PHY0_VCC), /* 0x4c PHY0_VCC */
- STAT(Px, PHY1_VCC), /* 0x4d PHY1_VCC */
- STAT(Px, CONTROLLER_TDIODE_TEMP), /* 0x4e CONTROLLER_TDIODE_TEMP */
- STAT(Px, BOARD_FRONT_TEMP), /* 0x4f BOARD_FRONT_TEMP */
- STAT(Px, BOARD_BACK_TEMP), /* 0x50 BOARD_BACK_TEMP */
- STAT(Px, I1V8), /* 0x51 IN_I1V8 */
- STAT(Px, I2V5), /* 0x52 IN_I2V5 */
- STAT(Px, I3V3), /* 0x53 IN_I3V3 */
- STAT(Px, I12V0), /* 0x54 IN_I12V0 */
- STAT(Px, 1_3V), /* 0x55 IN_1V3 */
- STAT(Px, I1V3), /* 0x56 IN_I1V3 */
-};
-
#define MCDI_STATIC_SENSOR_ASSERT(_field) \
EFX_STATIC_ASSERT(MC_CMD_SENSOR_STATE_ ## _field \
== EFX_MON_STAT_STATE_ ## _field)
@@ -155,10 +29,10 @@ mcdi_mon_decode_stats(
__inout_ecount_opt(EFX_MON_NSTATS) efx_mon_stat_value_t *stat)
{
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
- uint16_t port_mask;
+ efx_mon_stat_portmask_t port_mask;
uint16_t sensor;
size_t sensor_max;
- uint32_t stat_mask[(EFX_ARRAY_SIZE(mcdi_sensor_map) + 31) / 32];
+ uint32_t stat_mask[(EFX_MON_NSTATS + 31) / 32];
uint32_t idx = 0;
uint32_t page = 0;
@@ -169,13 +43,10 @@ mcdi_mon_decode_stats(
MCDI_STATIC_SENSOR_ASSERT(BROKEN);
MCDI_STATIC_SENSOR_ASSERT(NO_READING);
- EFX_STATIC_ASSERT(sizeof (stat_mask[0]) * 8 ==
- EFX_MON_MASK_ELEMENT_SIZE);
- sensor_max =
- MIN((8 * sensor_mask_size), EFX_ARRAY_SIZE(mcdi_sensor_map));
+ sensor_max = 8 * sensor_mask_size;
EFSYS_ASSERT(emip->emi_port > 0); /* MCDI port number is one-based */
- port_mask = MCDI_MON_PORT_MASK(emip);
+ port_mask = (efx_mon_stat_portmask_t)MCDI_MON_PORT_MASK(emip);
memset(stat_mask, 0, sizeof (stat_mask));
@@ -190,19 +61,36 @@ mcdi_mon_decode_stats(
* does not understand.
*/
for (sensor = 0; sensor < sensor_max; ++sensor) {
- efx_mon_stat_t id = mcdi_sensor_map[sensor].msm_stat;
+ efx_mon_stat_t id;
+ efx_mon_stat_portmask_t stat_portmask = 0;
+ boolean_t decode_ok;
+ efx_mon_stat_unit_t stat_unit;
- if ((sensor % MCDI_MON_PAGE_SIZE) == MC_CMD_SENSOR_PAGE0_NEXT) {
- EFSYS_ASSERT3U(id, ==, MCDI_MON_NEXT_PAGE);
+ if ((sensor % (MC_CMD_SENSOR_PAGE0_NEXT + 1)) ==
+ MC_CMD_SENSOR_PAGE0_NEXT) {
page++;
continue;
+ /* This sensor is one of the page boundary bits. */
}
+
if (~(sensor_mask[page]) & (1U << sensor))
continue;
+ /* This sensor not in DMA buffer */
+
idx++;
+ /*
+ * Valid stat in DMA buffer that we need to increment over, even
+ * if we couldn't look up the id
+ */
+
+ decode_ok = efx_mon_mcdi_to_efx_stat(sensor, &id);
+ decode_ok =
+ decode_ok && efx_mon_get_stat_portmap(id, &stat_portmask);
- if ((port_mask & mcdi_sensor_map[sensor].msm_port_mask) == 0)
+ if (!(decode_ok && (stat_portmask & port_mask)))
continue;
+ /* Either bad decode, or don't know what port stat is on */
+
EFSYS_ASSERT(id < EFX_MON_NSTATS);
/*
@@ -228,6 +116,10 @@ mcdi_mon_decode_stats(
stat[id].emsv_state = (uint16_t)EFX_DWORD_FIELD(dword,
MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE);
+
+ stat[id].emsv_unit =
+ efx_mon_get_stat_unit(id, &stat_unit) ?
+ stat_unit : EFX_MON_STAT_UNIT_UNKNOWN;
}
}
@@ -244,7 +136,7 @@ mcdi_mon_ev(
__out efx_mon_stat_value_t *valuep)
{
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
- uint16_t port_mask;
+ efx_mon_stat_portmask_t port_mask, sensor_port_mask;
uint16_t sensor;
uint16_t state;
uint16_t value;
@@ -261,20 +153,22 @@ mcdi_mon_ev(
/* Hardware must support this MCDI sensor */
EFSYS_ASSERT3U(sensor, <,
(8 * enp->en_nic_cfg.enc_mcdi_sensor_mask_size));
- EFSYS_ASSERT((sensor % MCDI_MON_PAGE_SIZE) != MC_CMD_SENSOR_PAGE0_NEXT);
+ EFSYS_ASSERT((sensor % (MC_CMD_SENSOR_PAGE0_NEXT + 1)) !=
+ MC_CMD_SENSOR_PAGE0_NEXT);
EFSYS_ASSERT(enp->en_nic_cfg.enc_mcdi_sensor_maskp != NULL);
- EFSYS_ASSERT(
- (enp->en_nic_cfg.enc_mcdi_sensor_maskp[sensor/MCDI_MON_PAGE_SIZE] &
- (1U << (sensor % MCDI_MON_PAGE_SIZE))) != 0);
+ EFSYS_ASSERT((enp->en_nic_cfg.enc_mcdi_sensor_maskp[
+ sensor / (MC_CMD_SENSOR_PAGE0_NEXT + 1)] &
+ (1U << (sensor % (MC_CMD_SENSOR_PAGE0_NEXT + 1)))) != 0);
- /* But we don't have to understand it */
- if (sensor >= EFX_ARRAY_SIZE(mcdi_sensor_map)) {
+ /* And we need to understand it, to get port-map */
+ if (!efx_mon_mcdi_to_efx_stat(sensor, &id)) {
rc = ENOTSUP;
goto fail1;
}
- id = mcdi_sensor_map[sensor].msm_stat;
- if ((port_mask & mcdi_sensor_map[sensor].msm_port_mask) == 0)
+ if (!(efx_mon_get_stat_portmap(id, &sensor_port_mask) &&
+ (port_mask && sensor_port_mask))) {
return (ENODEV);
+ }
EFSYS_ASSERT(id < EFX_MON_NSTATS);
*idp = id;
@@ -297,9 +191,15 @@ efx_mcdi_read_sensors(
__in uint32_t size)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_READ_SENSORS_EXT_IN_LEN,
- MC_CMD_READ_SENSORS_EXT_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_READ_SENSORS_EXT_IN_LEN,
+ MC_CMD_READ_SENSORS_EXT_OUT_LEN);
uint32_t addr_lo, addr_hi;
+ efx_rc_t rc;
+
+ if (EFSYS_MEM_SIZE(esmp) < size) {
+ rc = EINVAL;
+ goto fail1;
+ }
req.emr_cmd = MC_CMD_READ_SENSORS;
req.emr_in_buf = payload;
@@ -317,6 +217,11 @@ efx_mcdi_read_sensors(
efx_mcdi_execute(enp, &req);
return (req.emr_rc);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
}
static __checkReturn efx_rc_t
@@ -325,8 +230,8 @@ efx_mcdi_sensor_info_npages(
__out uint32_t *npagesp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN,
- MC_CMD_SENSOR_INFO_OUT_LENMAX)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SENSOR_INFO_EXT_IN_LEN,
+ MC_CMD_SENSOR_INFO_OUT_LENMAX);
int page;
efx_rc_t rc;
@@ -369,8 +274,8 @@ efx_mcdi_sensor_info(
__in size_t npages)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN,
- MC_CMD_SENSOR_INFO_OUT_LENMAX)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SENSOR_INFO_EXT_IN_LEN,
+ MC_CMD_SENSOR_INFO_OUT_LENMAX);
uint32_t page;
efx_rc_t rc;
@@ -429,6 +334,86 @@ fail1:
return (rc);
}
+static __checkReturn efx_rc_t
+efx_mcdi_sensor_info_page(
+ __in efx_nic_t *enp,
+ __in uint32_t page,
+ __out uint32_t *mask_part,
+ __out_ecount((sizeof (*mask_part) * 8) - 1)
+ efx_mon_stat_limits_t *limits)
+{
+ efx_mcdi_req_t req;
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SENSOR_INFO_EXT_IN_LEN,
+ MC_CMD_SENSOR_INFO_OUT_LENMAX);
+ efx_rc_t rc;
+ uint32_t mask_copy;
+ efx_dword_t *maskp;
+ efx_qword_t *limit_info;
+
+ EFSYS_ASSERT(mask_part != NULL);
+ EFSYS_ASSERT(limits != NULL);
+
+ memset(limits, 0,
+ ((sizeof (*mask_part) * 8) - 1) * sizeof (efx_mon_stat_limits_t));
+
+ req.emr_cmd = MC_CMD_SENSOR_INFO;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_SENSOR_INFO_EXT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SENSOR_INFO_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, SENSOR_INFO_EXT_IN_PAGE, page);
+
+ efx_mcdi_execute(enp, &req);
+
+ rc = req.emr_rc;
+
+ if (rc != 0)
+ goto fail1;
+
+ EFSYS_ASSERT(sizeof (*limit_info) ==
+ MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_LEN);
+ maskp = MCDI_OUT2(req, efx_dword_t, SENSOR_INFO_OUT_MASK);
+ limit_info = (efx_qword_t *)(maskp + 1);
+
+ *mask_part = maskp->ed_u32[0];
+ mask_copy = *mask_part;
+
+ /* Copy an entry for all but the highest bit set. */
+ while (mask_copy) {
+
+ if (mask_copy == (1U << MC_CMD_SENSOR_PAGE0_NEXT)) {
+ /* Only next page bit set. */
+ mask_copy = 0;
+ } else {
+ /* Clear lowest bit */
+ mask_copy = mask_copy & ~(mask_copy ^ (mask_copy - 1));
+ /* And copy out limit entry into buffer */
+ limits->emlv_warning_min = EFX_QWORD_FIELD(*limit_info,
+ MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1);
+
+ limits->emlv_warning_max = EFX_QWORD_FIELD(*limit_info,
+ MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1);
+
+ limits->emlv_fatal_min = EFX_QWORD_FIELD(*limit_info,
+ MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2);
+
+ limits->emlv_fatal_max = EFX_QWORD_FIELD(*limit_info,
+ MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2);
+
+ limits++;
+ limit_info++;
+ }
+ }
+
+ return (rc);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
__checkReturn efx_rc_t
mcdi_mon_stats_update(
__in efx_nic_t *enp,
@@ -457,6 +442,96 @@ fail1:
return (rc);
}
+static void
+lowest_set_bit(
+ __in uint32_t input_mask,
+ __out uint32_t *lowest_bit_mask,
+ __out uint32_t *lowest_bit_num
+)
+{
+ uint32_t x;
+ uint32_t set_bit, bit_index;
+
+ x = (input_mask ^ (input_mask - 1));
+ set_bit = (x + 1) >> 1;
+ if (!set_bit)
+ set_bit = (1U << 31U);
+
+ bit_index = 0;
+ if (set_bit & 0xFFFF0000)
+ bit_index += 16;
+ if (set_bit & 0xFF00FF00)
+ bit_index += 8;
+ if (set_bit & 0xF0F0F0F0)
+ bit_index += 4;
+ if (set_bit & 0xCCCCCCCC)
+ bit_index += 2;
+ if (set_bit & 0xAAAAAAAA)
+ bit_index += 1;
+
+ *lowest_bit_mask = set_bit;
+ *lowest_bit_num = bit_index;
+}
+
+ __checkReturn efx_rc_t
+mcdi_mon_limits_update(
+ __in efx_nic_t *enp,
+ __inout_ecount(EFX_MON_NSTATS) efx_mon_stat_limits_t *values)
+{
+ efx_rc_t rc;
+ uint32_t page;
+ uint32_t page_mask;
+ uint32_t limit_index;
+ efx_mon_stat_limits_t limits[sizeof (page_mask) * 8];
+ efx_mon_stat_t stat;
+
+ page = 0;
+ page--;
+ do {
+ page++;
+
+ rc = efx_mcdi_sensor_info_page(enp, page, &page_mask, limits);
+ if (rc != 0)
+ goto fail1;
+
+ limit_index = 0;
+ while (page_mask) {
+ uint32_t set_bit;
+ uint32_t page_index;
+ uint32_t mcdi_index;
+
+ if (page_mask == (1U << MC_CMD_SENSOR_PAGE0_NEXT))
+ break;
+
+ lowest_set_bit(page_mask, &set_bit, &page_index);
+ page_mask = page_mask & ~set_bit;
+
+ mcdi_index =
+ page_index + (sizeof (page_mask) * 8 * page);
+
+ /*
+ * This can fail if MCDI reports newer stats than the
+ * drivers understand, or the bit is the next page bit.
+ *
+ * Driver needs to be tolerant of this.
+ */
+ if (!efx_mon_mcdi_to_efx_stat(mcdi_index, &stat))
+ continue;
+
+ values[stat] = limits[limit_index];
+ limit_index++;
+ }
+
+ } while (page_mask & (1U << MC_CMD_SENSOR_PAGE0_NEXT));
+
+ return (rc);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
__checkReturn efx_rc_t
mcdi_mon_cfg_build(
__in efx_nic_t *enp)
diff --git a/drivers/net/sfc/base/mcdi_mon.h b/drivers/net/sfc/base/mcdi_mon.h
index 5aa6a6a2..5eba0901 100644
--- a/drivers/net/sfc/base/mcdi_mon.h
+++ b/drivers/net/sfc/base/mcdi_mon.h
@@ -39,6 +39,11 @@ mcdi_mon_stats_update(
__in efsys_mem_t *esmp,
__inout_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values);
+extern __checkReturn efx_rc_t
+mcdi_mon_limits_update(
+ __in efx_nic_t *enp,
+ __inout_ecount(EFX_MON_NSTATS) efx_mon_stat_limits_t *values);
+
#endif /* EFSYS_OPT_MON_STATS */
#endif /* EFSYS_OPT_MON_MCDI */
diff --git a/drivers/net/sfc/base/medford2_nic.c b/drivers/net/sfc/base/medford2_nic.c
index 7f5ad175..6bc1e87c 100644
--- a/drivers/net/sfc/base/medford2_nic.c
+++ b/drivers/net/sfc/base/medford2_nic.c
@@ -15,25 +15,15 @@ medford2_nic_get_required_pcie_bandwidth(
__in efx_nic_t *enp,
__out uint32_t *bandwidth_mbpsp)
{
- uint32_t port_modes;
- uint32_t current_mode;
uint32_t bandwidth;
efx_rc_t rc;
/* FIXME: support new Medford2 dynamic port modes */
- if ((rc = efx_mcdi_get_port_modes(enp, &port_modes,
- &current_mode)) != 0) {
- /* No port mode info available. */
- bandwidth = 0;
- goto out;
- }
-
- if ((rc = ef10_nic_get_port_mode_bandwidth(current_mode,
+ if ((rc = ef10_nic_get_port_mode_bandwidth(enp,
&bandwidth)) != 0)
goto fail1;
-out:
*bandwidth_mbpsp = bandwidth;
return (0);
@@ -96,6 +86,9 @@ medford2_board_cfg(
else
goto fail1;
+ /* Checksums for TSO sends should always be correct on Medford2. */
+ encp->enc_bug61297_workaround = B_FALSE;
+
/* Get clock frequencies (in MHz). */
if ((rc = efx_mcdi_get_clock(enp, &sysclk, &dpcpu_clk)) != 0)
goto fail2;
diff --git a/drivers/net/sfc/base/medford_nic.c b/drivers/net/sfc/base/medford_nic.c
index 6dc895f5..bfe01ca9 100644
--- a/drivers/net/sfc/base/medford_nic.c
+++ b/drivers/net/sfc/base/medford_nic.c
@@ -15,23 +15,13 @@ medford_nic_get_required_pcie_bandwidth(
__in efx_nic_t *enp,
__out uint32_t *bandwidth_mbpsp)
{
- uint32_t port_modes;
- uint32_t current_mode;
uint32_t bandwidth;
efx_rc_t rc;
- if ((rc = efx_mcdi_get_port_modes(enp, &port_modes,
- &current_mode)) != 0) {
- /* No port mode info available. */
- bandwidth = 0;
- goto out;
- }
-
- if ((rc = ef10_nic_get_port_mode_bandwidth(current_mode,
+ if ((rc = ef10_nic_get_port_mode_bandwidth(enp,
&bandwidth)) != 0)
goto fail1;
-out:
*bandwidth_mbpsp = bandwidth;
return (0);
@@ -94,6 +84,9 @@ medford_board_cfg(
else
goto fail1;
+ /* Checksums for TSO sends can be incorrect on Medford. */
+ encp->enc_bug61297_workaround = B_TRUE;
+
/* Get clock frequencies (in MHz). */
if ((rc = efx_mcdi_get_clock(enp, &sysclk, &dpcpu_clk)) != 0)
goto fail2;
diff --git a/drivers/net/sfc/base/meson.build b/drivers/net/sfc/base/meson.build
index da2bf44d..ab66f32f 100644
--- a/drivers/net/sfc/base/meson.build
+++ b/drivers/net/sfc/base/meson.build
@@ -58,6 +58,9 @@ extra_flags = [
]
c_args = cflags
+if allow_experimental_apis
+ c_args += '-DALLOW_EXPERIMENTAL_API'
+endif
foreach flag: extra_flags
if cc.has_argument(flag)
c_args += flag
diff --git a/drivers/net/sfc/base/siena_mac.c b/drivers/net/sfc/base/siena_mac.c
index f8857cdd..928dfc34 100644
--- a/drivers/net/sfc/base/siena_mac.c
+++ b/drivers/net/sfc/base/siena_mac.c
@@ -68,14 +68,13 @@ siena_mac_reconfigure(
efx_port_t *epp = &(enp->en_port);
efx_oword_t multicast_hash[2];
efx_mcdi_req_t req;
- uint8_t payload[MAX(MAX(MC_CMD_SET_MAC_IN_LEN,
- MC_CMD_SET_MAC_OUT_LEN),
- MAX(MC_CMD_SET_MCAST_HASH_IN_LEN,
- MC_CMD_SET_MCAST_HASH_OUT_LEN))];
+ EFX_MCDI_DECLARE_BUF(payload,
+ MAX(MC_CMD_SET_MAC_IN_LEN, MC_CMD_SET_MCAST_HASH_IN_LEN),
+ MAX(MC_CMD_SET_MAC_OUT_LEN, MC_CMD_SET_MCAST_HASH_OUT_LEN));
+
unsigned int fcntl;
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_IN_LEN;
diff --git a/drivers/net/sfc/base/siena_nic.c b/drivers/net/sfc/base/siena_nic.c
index 31eef80b..fca17171 100644
--- a/drivers/net/sfc/base/siena_nic.c
+++ b/drivers/net/sfc/base/siena_nic.c
@@ -18,11 +18,10 @@ siena_nic_get_partn_mask(
__out unsigned int *maskp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN,
- MC_CMD_NVRAM_TYPES_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TYPES_IN_LEN,
+ MC_CMD_NVRAM_TYPES_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_NVRAM_TYPES;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
@@ -115,6 +114,7 @@ siena_board_cfg(
/* Alignment for WPTR updates */
encp->enc_rx_push_align = 1;
+#if EFSYS_OPT_RX_SCALE
/* There is one RSS context per function */
encp->enc_rx_scale_max_exclusive_contexts = 1;
@@ -129,6 +129,7 @@ siena_board_cfg(
/* There is no support for additional RSS modes */
encp->enc_rx_scale_additional_modes_supported = B_FALSE;
+#endif /* EFSYS_OPT_RX_SCALE */
encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT);
/* Fragments must not span 4k boundaries. */
diff --git a/drivers/net/sfc/base/siena_nvram.c b/drivers/net/sfc/base/siena_nvram.c
index 8cdd2df7..b8ea8a75 100644
--- a/drivers/net/sfc/base/siena_nvram.c
+++ b/drivers/net/sfc/base/siena_nvram.c
@@ -418,12 +418,11 @@ siena_nvram_get_subtype(
__out uint32_t *subtypep)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_BOARD_CFG_IN_LEN,
- MC_CMD_GET_BOARD_CFG_OUT_LENMAX)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_BOARD_CFG_IN_LEN,
+ MC_CMD_GET_BOARD_CFG_OUT_LENMAX);
efx_word_t *fw_list;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_BOARD_CFG;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_BOARD_CFG_IN_LEN;
diff --git a/drivers/net/sfc/base/siena_phy.c b/drivers/net/sfc/base/siena_phy.c
index 4b2190d3..7eec9c74 100644
--- a/drivers/net/sfc/base/siena_phy.c
+++ b/drivers/net/sfc/base/siena_phy.c
@@ -169,11 +169,10 @@ siena_phy_get_link(
__out siena_link_state_t *slsp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_LINK_IN_LEN,
- MC_CMD_GET_LINK_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LINK_IN_LEN,
+ MC_CMD_GET_LINK_OUT_LEN);
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_LINK;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_LINK_IN_LEN;
@@ -244,10 +243,9 @@ siena_phy_reconfigure(
{
efx_port_t *epp = &(enp->en_port);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MAX(MC_CMD_SET_ID_LED_IN_LEN,
- MC_CMD_SET_ID_LED_OUT_LEN),
- MAX(MC_CMD_SET_LINK_IN_LEN,
- MC_CMD_SET_LINK_OUT_LEN))];
+ EFX_MCDI_DECLARE_BUF(payload,
+ MAX(MC_CMD_SET_ID_LED_IN_LEN, MC_CMD_SET_LINK_IN_LEN),
+ MAX(MC_CMD_SET_ID_LED_OUT_LEN, MC_CMD_SET_LINK_OUT_LEN));
uint32_t cap_mask;
#if EFSYS_OPT_PHY_LED_CONTROL
unsigned int led_mode;
@@ -255,7 +253,6 @@ siena_phy_reconfigure(
unsigned int speed;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_LINK;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_SET_LINK_IN_LEN;
@@ -361,12 +358,11 @@ siena_phy_verify(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_PHY_STATE_IN_LEN,
- MC_CMD_GET_PHY_STATE_OUT_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_PHY_STATE_IN_LEN,
+ MC_CMD_GET_PHY_STATE_OUT_LEN);
uint32_t state;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PHY_STATE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_PHY_STATE_IN_LEN;
@@ -530,8 +526,8 @@ siena_phy_stats_update(
uint32_t vmask = encp->enc_mcdi_phy_stat_mask;
uint64_t smask;
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_PHY_STATS_IN_LEN,
- MC_CMD_PHY_STATS_OUT_DMA_LEN)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_PHY_STATS_IN_LEN,
+ MC_CMD_PHY_STATS_OUT_DMA_LEN);
efx_rc_t rc;
if ((esmp == NULL) || (EFSYS_MEM_SIZE(esmp) < EFX_PHY_STATS_SIZE)) {
@@ -539,7 +535,6 @@ siena_phy_stats_update(
goto fail1;
}
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_PHY_STATS;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_PHY_STATS_IN_LEN;
@@ -626,14 +621,13 @@ siena_phy_bist_poll(
__in size_t count)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN,
- MCDI_CTL_SDU_LEN_MAX)];
+ EFX_MCDI_DECLARE_BUF(payload, MC_CMD_POLL_BIST_IN_LEN,
+ MCDI_CTL_SDU_LEN_MAX);
uint32_t value_mask = 0;
efx_mcdi_req_t req;
uint32_t result;
efx_rc_t rc;
- (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_POLL_BIST;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN;
diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h
index b9d2df58..0b4795da 100644
--- a/drivers/net/sfc/efsys.h
+++ b/drivers/net/sfc/efsys.h
@@ -48,10 +48,6 @@ extern "C" {
#include "efx_types.h"
-#ifndef _NOTE
-#define _NOTE(s)
-#endif
-
typedef bool boolean_t;
#ifndef B_FALSE
@@ -106,40 +102,6 @@ prefetch_read_once(const volatile void *addr)
rte_prefetch_non_temporal(addr);
}
-/* Modifiers used for Windows builds */
-#define __in
-#define __in_opt
-#define __in_ecount(_n)
-#define __in_ecount_opt(_n)
-#define __in_bcount(_n)
-#define __in_bcount_opt(_n)
-
-#define __out
-#define __out_opt
-#define __out_ecount(_n)
-#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
-
-#define __inout
-#define __inout_opt
-#define __inout_ecount(_n)
-#define __inout_ecount_opt(_n)
-#define __inout_bcount(_n)
-#define __inout_bcount_opt(_n)
-#define __inout_bcount_full_opt(_n)
-
-#define __deref_out_bcount_opt(n)
-
-#define __checkReturn
-#define __success(_x)
-
-#define __drv_when(_p, _c)
-
/* Code inclusion options */
diff --git a/drivers/net/sfc/sfc_dp_tx.h b/drivers/net/sfc/sfc_dp_tx.h
index eda9676c..c246871c 100644
--- a/drivers/net/sfc/sfc_dp_tx.h
+++ b/drivers/net/sfc/sfc_dp_tx.h
@@ -57,6 +57,11 @@ struct sfc_dp_tx_qcreate_info {
volatile void *mem_bar;
/** VI window size shift */
unsigned int vi_window_shift;
+ /**
+ * Maximum number of bytes into the packet the TCP header can start for
+ * the hardware to apply TSO packet edits.
+ */
+ uint16_t tso_tcp_header_offset_limit;
};
/**
diff --git a/drivers/net/sfc/sfc_ef10_essb_rx.c b/drivers/net/sfc/sfc_ef10_essb_rx.c
index 81c8f7fb..a24f54e7 100644
--- a/drivers/net/sfc/sfc_ef10_essb_rx.c
+++ b/drivers/net/sfc/sfc_ef10_essb_rx.c
@@ -123,14 +123,22 @@ static struct rte_mbuf *
sfc_ef10_essb_next_mbuf(const struct sfc_ef10_essb_rxq *rxq,
struct rte_mbuf *mbuf)
{
- return (struct rte_mbuf *)((uintptr_t)mbuf + rxq->buf_stride);
+ struct rte_mbuf *m;
+
+ m = (struct rte_mbuf *)((uintptr_t)mbuf + rxq->buf_stride);
+ MBUF_RAW_ALLOC_CHECK(m);
+ return m;
}
static struct rte_mbuf *
sfc_ef10_essb_mbuf_by_index(const struct sfc_ef10_essb_rxq *rxq,
struct rte_mbuf *mbuf, unsigned int idx)
{
- return (struct rte_mbuf *)((uintptr_t)mbuf + idx * rxq->buf_stride);
+ struct rte_mbuf *m;
+
+ m = (struct rte_mbuf *)((uintptr_t)mbuf + idx * rxq->buf_stride);
+ MBUF_RAW_ALLOC_CHECK(m);
+ return m;
}
static struct rte_mbuf *
@@ -324,7 +332,7 @@ sfc_ef10_essb_rx_get_pending(struct sfc_ef10_essb_rxq *rxq,
/* Buffers to be discarded have 0 in packet type */
if (unlikely(m->packet_type == 0)) {
- rte_mempool_put(rxq->refill_mb_pool, m);
+ rte_mbuf_raw_free(m);
goto next_buf;
}
@@ -687,7 +695,7 @@ sfc_ef10_essb_rx_qpurge(struct sfc_dp_rxq *dp_rxq)
m = sfc_ef10_essb_mbuf_by_index(rxq, rxd->first_mbuf,
rxq->block_size - rxq->left_in_completed);
while (rxq->left_in_completed > 0) {
- rte_mempool_put(rxq->refill_mb_pool, m);
+ rte_mbuf_raw_free(m);
m = sfc_ef10_essb_next_mbuf(rxq, m);
rxq->left_in_completed--;
}
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index 6a5052b9..77ca580b 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -57,12 +57,13 @@ struct sfc_ef10_rxq {
#define SFC_EF10_RXQ_EXCEPTION 0x4
#define SFC_EF10_RXQ_RSS_HASH 0x8
unsigned int ptr_mask;
- unsigned int prepared;
+ unsigned int pending;
unsigned int completed;
unsigned int evq_read_ptr;
efx_qword_t *evq_hw_ring;
struct sfc_ef10_rx_sw_desc *sw_ring;
uint64_t rearm_data;
+ struct rte_mbuf *scatter_pkt;
uint16_t prefix_size;
/* Used on refill */
@@ -133,6 +134,8 @@ sfc_ef10_rx_qrefill(struct sfc_ef10_rxq *rxq)
struct sfc_ef10_rx_sw_desc *rxd;
rte_iova_t phys_addr;
+ MBUF_RAW_ALLOC_CHECK(m);
+
SFC_ASSERT((id & ~ptr_mask) == 0);
rxd = &rxq->sw_ring[id];
rxd->mbuf = m;
@@ -184,21 +187,26 @@ sfc_ef10_rx_prefetch_next(struct sfc_ef10_rxq *rxq, unsigned int next_id)
}
}
-static uint16_t
-sfc_ef10_rx_prepared(struct sfc_ef10_rxq *rxq, struct rte_mbuf **rx_pkts,
- uint16_t nb_pkts)
+static struct rte_mbuf **
+sfc_ef10_rx_pending(struct sfc_ef10_rxq *rxq, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts)
{
- uint16_t n_rx_pkts = RTE_MIN(nb_pkts, rxq->prepared);
- unsigned int completed = rxq->completed;
- unsigned int i;
+ uint16_t n_rx_pkts = RTE_MIN(nb_pkts, rxq->pending - rxq->completed);
- rxq->prepared -= n_rx_pkts;
- rxq->completed = completed + n_rx_pkts;
+ SFC_ASSERT(rxq->pending == rxq->completed || rxq->scatter_pkt == NULL);
- for (i = 0; i < n_rx_pkts; ++i, ++completed)
- rx_pkts[i] = rxq->sw_ring[completed & rxq->ptr_mask].mbuf;
+ if (n_rx_pkts != 0) {
+ unsigned int completed = rxq->completed;
+
+ rxq->completed = completed + n_rx_pkts;
+
+ do {
+ *rx_pkts++ =
+ rxq->sw_ring[completed++ & rxq->ptr_mask].mbuf;
+ } while (completed != rxq->completed);
+ }
- return n_rx_pkts;
+ return rx_pkts;
}
static uint16_t
@@ -213,47 +221,80 @@ sfc_ef10_rx_pseudo_hdr_get_hash(const uint8_t *pseudo_hdr)
return rte_le_to_cpu_32(*(const uint32_t *)pseudo_hdr);
}
-static uint16_t
+static struct rte_mbuf **
sfc_ef10_rx_process_event(struct sfc_ef10_rxq *rxq, efx_qword_t rx_ev,
- struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
+ struct rte_mbuf **rx_pkts,
+ struct rte_mbuf ** const rx_pkts_end)
{
const unsigned int ptr_mask = rxq->ptr_mask;
- unsigned int completed = rxq->completed;
+ unsigned int pending = rxq->pending;
unsigned int ready;
struct sfc_ef10_rx_sw_desc *rxd;
struct rte_mbuf *m;
struct rte_mbuf *m0;
- uint16_t n_rx_pkts;
const uint8_t *pseudo_hdr;
- uint16_t pkt_len;
+ uint16_t seg_len;
- ready = (EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_DSC_PTR_LBITS) - completed) &
+ ready = (EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_DSC_PTR_LBITS) - pending) &
EFX_MASK32(ESF_DZ_RX_DSC_PTR_LBITS);
- SFC_ASSERT(ready > 0);
+
+ if (ready == 0) {
+ /* Rx abort - it was no enough descriptors for Rx packet */
+ rte_pktmbuf_free(rxq->scatter_pkt);
+ rxq->scatter_pkt = NULL;
+ return rx_pkts;
+ }
+
+ rxq->pending = pending + ready;
if (rx_ev.eq_u64[0] &
rte_cpu_to_le_64((1ull << ESF_DZ_RX_ECC_ERR_LBN) |
(1ull << ESF_DZ_RX_ECRC_ERR_LBN))) {
- SFC_ASSERT(rxq->prepared == 0);
- rxq->completed += ready;
- while (ready-- > 0) {
- rxd = &rxq->sw_ring[completed++ & ptr_mask];
- rte_mempool_put(rxq->refill_mb_pool, rxd->mbuf);
- }
- return 0;
+ SFC_ASSERT(rxq->completed == pending);
+ do {
+ rxd = &rxq->sw_ring[pending++ & ptr_mask];
+ rte_mbuf_raw_free(rxd->mbuf);
+ } while (pending != rxq->pending);
+ rxq->completed = pending;
+ return rx_pkts;
}
- n_rx_pkts = RTE_MIN(ready, nb_pkts);
- rxq->prepared = ready - n_rx_pkts;
- rxq->completed += n_rx_pkts;
+ /* If scattered packet is in progress */
+ if (rxq->scatter_pkt != NULL) {
+ /* Events for scattered packet frags are not merged */
+ SFC_ASSERT(ready == 1);
+ SFC_ASSERT(rxq->completed == pending);
- rxd = &rxq->sw_ring[completed++ & ptr_mask];
+ /* There is no pseudo-header in scatter segments. */
+ seg_len = EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_BYTES);
- sfc_ef10_rx_prefetch_next(rxq, completed & ptr_mask);
+ rxd = &rxq->sw_ring[pending++ & ptr_mask];
+ m = rxd->mbuf;
- m = rxd->mbuf;
+ MBUF_RAW_ALLOC_CHECK(m);
+
+ m->data_off = RTE_PKTMBUF_HEADROOM;
+ rte_pktmbuf_data_len(m) = seg_len;
+ rte_pktmbuf_pkt_len(m) = seg_len;
- *rx_pkts++ = m;
+ rxq->scatter_pkt->nb_segs++;
+ rte_pktmbuf_pkt_len(rxq->scatter_pkt) += seg_len;
+ rte_pktmbuf_lastseg(rxq->scatter_pkt)->next = m;
+
+ if (~rx_ev.eq_u64[0] &
+ rte_cpu_to_le_64(1ull << ESF_DZ_RX_CONT_LBN)) {
+ *rx_pkts++ = rxq->scatter_pkt;
+ rxq->scatter_pkt = NULL;
+ }
+ rxq->completed = pending;
+ return rx_pkts;
+ }
+
+ rxd = &rxq->sw_ring[pending++ & ptr_mask];
+
+ sfc_ef10_rx_prefetch_next(rxq, pending & ptr_mask);
+
+ m = rxd->mbuf;
RTE_BUILD_BUG_ON(sizeof(m->rearm_data[0]) != sizeof(rxq->rearm_data));
m->rearm_data[0] = rxq->rearm_data;
@@ -275,27 +316,40 @@ sfc_ef10_rx_process_event(struct sfc_ef10_rxq *rxq, efx_qword_t rx_ev,
m->hash.rss = sfc_ef10_rx_pseudo_hdr_get_hash(pseudo_hdr);
if (ready == 1)
- pkt_len = EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_BYTES) -
+ seg_len = EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_BYTES) -
rxq->prefix_size;
else
- pkt_len = sfc_ef10_rx_pseudo_hdr_get_len(pseudo_hdr);
- SFC_ASSERT(pkt_len > 0);
- rte_pktmbuf_data_len(m) = pkt_len;
- rte_pktmbuf_pkt_len(m) = pkt_len;
+ seg_len = sfc_ef10_rx_pseudo_hdr_get_len(pseudo_hdr);
+ SFC_ASSERT(seg_len > 0);
+ rte_pktmbuf_data_len(m) = seg_len;
+ rte_pktmbuf_pkt_len(m) = seg_len;
SFC_ASSERT(m->next == NULL);
+ if (~rx_ev.eq_u64[0] & rte_cpu_to_le_64(1ull << ESF_DZ_RX_CONT_LBN)) {
+ *rx_pkts++ = m;
+ rxq->completed = pending;
+ } else {
+ /* Events with CONT bit are not merged */
+ SFC_ASSERT(ready == 1);
+ rxq->scatter_pkt = m;
+ rxq->completed = pending;
+ return rx_pkts;
+ }
+
/* Remember mbuf to copy offload flags and packet type from */
m0 = m;
- for (--ready; ready > 0; --ready) {
- rxd = &rxq->sw_ring[completed++ & ptr_mask];
+ while (pending != rxq->pending) {
+ rxd = &rxq->sw_ring[pending++ & ptr_mask];
- sfc_ef10_rx_prefetch_next(rxq, completed & ptr_mask);
+ sfc_ef10_rx_prefetch_next(rxq, pending & ptr_mask);
m = rxd->mbuf;
- if (ready > rxq->prepared)
+ if (rx_pkts != rx_pkts_end) {
*rx_pkts++ = m;
+ rxq->completed = pending;
+ }
RTE_BUILD_BUG_ON(sizeof(m->rearm_data[0]) !=
sizeof(rxq->rearm_data));
@@ -315,15 +369,15 @@ sfc_ef10_rx_process_event(struct sfc_ef10_rxq *rxq, efx_qword_t rx_ev,
*/
m->hash.rss = sfc_ef10_rx_pseudo_hdr_get_hash(pseudo_hdr);
- pkt_len = sfc_ef10_rx_pseudo_hdr_get_len(pseudo_hdr);
- SFC_ASSERT(pkt_len > 0);
- rte_pktmbuf_data_len(m) = pkt_len;
- rte_pktmbuf_pkt_len(m) = pkt_len;
+ seg_len = sfc_ef10_rx_pseudo_hdr_get_len(pseudo_hdr);
+ SFC_ASSERT(seg_len > 0);
+ rte_pktmbuf_data_len(m) = seg_len;
+ rte_pktmbuf_pkt_len(m) = seg_len;
SFC_ASSERT(m->next == NULL);
}
- return n_rx_pkts;
+ return rx_pkts;
}
static bool
@@ -355,26 +409,25 @@ static uint16_t
sfc_ef10_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
{
struct sfc_ef10_rxq *rxq = sfc_ef10_rxq_by_dp_rxq(rx_queue);
+ struct rte_mbuf ** const rx_pkts_end = &rx_pkts[nb_pkts];
unsigned int evq_old_read_ptr;
- uint16_t n_rx_pkts;
efx_qword_t rx_ev;
+ rx_pkts = sfc_ef10_rx_pending(rxq, rx_pkts, nb_pkts);
+
if (unlikely(rxq->flags &
(SFC_EF10_RXQ_NOT_RUNNING | SFC_EF10_RXQ_EXCEPTION)))
- return 0;
-
- n_rx_pkts = sfc_ef10_rx_prepared(rxq, rx_pkts, nb_pkts);
+ goto done;
evq_old_read_ptr = rxq->evq_read_ptr;
- while (n_rx_pkts != nb_pkts && sfc_ef10_rx_get_event(rxq, &rx_ev)) {
+ while (rx_pkts != rx_pkts_end && sfc_ef10_rx_get_event(rxq, &rx_ev)) {
/*
* DROP_EVENT is an internal to the NIC, software should
* never see it and, therefore, may ignore it.
*/
- n_rx_pkts += sfc_ef10_rx_process_event(rxq, rx_ev,
- rx_pkts + n_rx_pkts,
- nb_pkts - n_rx_pkts);
+ rx_pkts = sfc_ef10_rx_process_event(rxq, rx_ev,
+ rx_pkts, rx_pkts_end);
}
sfc_ef10_ev_qclear(rxq->evq_hw_ring, rxq->ptr_mask, evq_old_read_ptr,
@@ -383,7 +436,8 @@ sfc_ef10_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
/* It is not a problem if we refill in the case of exception */
sfc_ef10_rx_qrefill(rxq);
- return n_rx_pkts;
+done:
+ return nb_pkts - (rx_pkts_end - rx_pkts);
}
const uint32_t *
@@ -446,21 +500,53 @@ sfc_ef10_supported_ptypes_get(uint32_t tunnel_encaps)
static sfc_dp_rx_qdesc_npending_t sfc_ef10_rx_qdesc_npending;
static unsigned int
-sfc_ef10_rx_qdesc_npending(__rte_unused struct sfc_dp_rxq *dp_rxq)
+sfc_ef10_rx_qdesc_npending(struct sfc_dp_rxq *dp_rxq)
{
+ struct sfc_ef10_rxq *rxq = sfc_ef10_rxq_by_dp_rxq(dp_rxq);
+ efx_qword_t rx_ev;
+ const unsigned int evq_old_read_ptr = rxq->evq_read_ptr;
+ unsigned int pending = rxq->pending;
+ unsigned int ready;
+
+ if (unlikely(rxq->flags &
+ (SFC_EF10_RXQ_NOT_RUNNING | SFC_EF10_RXQ_EXCEPTION)))
+ goto done;
+
+ while (sfc_ef10_rx_get_event(rxq, &rx_ev)) {
+ ready = (EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_DSC_PTR_LBITS) -
+ pending) &
+ EFX_MASK32(ESF_DZ_RX_DSC_PTR_LBITS);
+ pending += ready;
+ }
+
/*
- * Correct implementation requires EvQ polling and events
- * processing (keeping all ready mbufs in prepared).
+ * The function does not process events, so return event queue read
+ * pointer to the original position to allow the events that were
+ * read to be processed later
*/
- return -ENOTSUP;
+ rxq->evq_read_ptr = evq_old_read_ptr;
+
+done:
+ return pending - rxq->completed;
}
static sfc_dp_rx_qdesc_status_t sfc_ef10_rx_qdesc_status;
static int
-sfc_ef10_rx_qdesc_status(__rte_unused struct sfc_dp_rxq *dp_rxq,
- __rte_unused uint16_t offset)
+sfc_ef10_rx_qdesc_status(struct sfc_dp_rxq *dp_rxq, uint16_t offset)
{
- return -ENOTSUP;
+ struct sfc_ef10_rxq *rxq = sfc_ef10_rxq_by_dp_rxq(dp_rxq);
+ unsigned int npending = sfc_ef10_rx_qdesc_npending(dp_rxq);
+
+ if (unlikely(offset > rxq->ptr_mask))
+ return -EINVAL;
+
+ if (offset < npending)
+ return RTE_ETH_RX_DESC_DONE;
+
+ if (offset < (rxq->added - rxq->completed))
+ return RTE_ETH_RX_DESC_AVAIL;
+
+ return RTE_ETH_RX_DESC_UNAVAIL;
}
@@ -594,8 +680,9 @@ sfc_ef10_rx_qstart(struct sfc_dp_rxq *dp_rxq, unsigned int evq_read_ptr)
{
struct sfc_ef10_rxq *rxq = sfc_ef10_rxq_by_dp_rxq(dp_rxq);
- rxq->prepared = 0;
- rxq->completed = rxq->added = 0;
+ SFC_ASSERT(rxq->completed == 0);
+ SFC_ASSERT(rxq->pending == 0);
+ SFC_ASSERT(rxq->added == 0);
sfc_ef10_rx_qrefill(rxq);
@@ -642,12 +729,17 @@ sfc_ef10_rx_qpurge(struct sfc_dp_rxq *dp_rxq)
unsigned int i;
struct sfc_ef10_rx_sw_desc *rxd;
+ rte_pktmbuf_free(rxq->scatter_pkt);
+ rxq->scatter_pkt = NULL;
+
for (i = rxq->completed; i != rxq->added; ++i) {
rxd = &rxq->sw_ring[i & rxq->ptr_mask];
- rte_mempool_put(rxq->refill_mb_pool, rxd->mbuf);
+ rte_mbuf_raw_free(rxd->mbuf);
rxd->mbuf = NULL;
}
+ rxq->completed = rxq->pending = rxq->added = 0;
+
rxq->flags &= ~SFC_EF10_RXQ_STARTED;
}
@@ -657,7 +749,8 @@ struct sfc_dp_rx sfc_ef10_rx = {
.type = SFC_DP_RX,
.hw_fw_caps = SFC_DP_HW_FW_CAP_EF10,
},
- .features = SFC_DP_RX_FEAT_MULTI_PROCESS |
+ .features = SFC_DP_RX_FEAT_SCATTER |
+ SFC_DP_RX_FEAT_MULTI_PROCESS |
SFC_DP_RX_FEAT_TUNNELS |
SFC_DP_RX_FEAT_CHECKSUM,
.get_dev_info = sfc_ef10_rx_get_dev_info,
diff --git a/drivers/net/sfc/sfc_ef10_tx.c b/drivers/net/sfc/sfc_ef10_tx.c
index d0daa3b3..bcd3153f 100644
--- a/drivers/net/sfc/sfc_ef10_tx.c
+++ b/drivers/net/sfc/sfc_ef10_tx.c
@@ -11,6 +11,8 @@
#include <rte_mbuf.h>
#include <rte_io.h>
+#include <rte_ip.h>
+#include <rte_tcp.h>
#include "efx.h"
#include "efx_types.h"
@@ -21,6 +23,7 @@
#include "sfc_tweak.h"
#include "sfc_kvargs.h"
#include "sfc_ef10.h"
+#include "sfc_tso.h"
#define sfc_ef10_tx_err(dpq, ...) \
SFC_DP_LOG(SFC_KVARG_DATAPATH_EF10, ERR, dpq, __VA_ARGS__)
@@ -62,6 +65,9 @@ struct sfc_ef10_txq {
efx_qword_t *txq_hw_ring;
volatile void *doorbell;
efx_qword_t *evq_hw_ring;
+ uint8_t *tsoh;
+ rte_iova_t tsoh_iova;
+ uint16_t tso_tcp_header_offset_limit;
/* Datapath transmit queue anchor */
struct sfc_dp_txq dp;
@@ -184,6 +190,30 @@ sfc_ef10_tx_qdesc_dma_create(rte_iova_t addr, uint16_t size, bool eop,
ESF_DZ_TX_KER_BUF_ADDR, addr);
}
+static void
+sfc_ef10_tx_qdesc_tso2_create(struct sfc_ef10_txq * const txq,
+ unsigned int added, uint16_t ipv4_id,
+ uint16_t outer_ipv4_id, uint32_t tcp_seq,
+ uint16_t tcp_mss)
+{
+ EFX_POPULATE_QWORD_5(txq->txq_hw_ring[added & txq->ptr_mask],
+ 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_5(txq->txq_hw_ring[(added + 1) & txq->ptr_mask],
+ 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,
+ ESF_DZ_TX_TSO_OUTER_IPID, outer_ipv4_id);
+}
+
static inline void
sfc_ef10_tx_qpush(struct sfc_ef10_txq *txq, unsigned int added,
unsigned int pushed)
@@ -263,6 +293,252 @@ sfc_ef10_tx_pkt_descs_max(const struct rte_mbuf *m)
extra_descs_per_pkt);
}
+static bool
+sfc_ef10_try_reap(struct sfc_ef10_txq * const txq, unsigned int added,
+ unsigned int needed_desc, unsigned int *dma_desc_space,
+ bool *reap_done)
+{
+ if (*reap_done)
+ return false;
+
+ if (added != txq->added) {
+ sfc_ef10_tx_qpush(txq, added, txq->added);
+ txq->added = added;
+ }
+
+ sfc_ef10_tx_reap(txq);
+ *reap_done = true;
+
+ /*
+ * Recalculate DMA descriptor space since Tx reap may change
+ * the number of completed descriptors
+ */
+ *dma_desc_space = txq->max_fill_level -
+ (added - txq->completed);
+
+ return (needed_desc <= *dma_desc_space);
+}
+
+static int
+sfc_ef10_xmit_tso_pkt(struct sfc_ef10_txq * const txq, struct rte_mbuf *m_seg,
+ unsigned int *added, unsigned int *dma_desc_space,
+ bool *reap_done)
+{
+ size_t iph_off = m_seg->l2_len;
+ size_t tcph_off = m_seg->l2_len + m_seg->l3_len;
+ size_t header_len = m_seg->l2_len + m_seg->l3_len + m_seg->l4_len;
+ /* Offset of the payload in the last segment that contains the header */
+ size_t in_off = 0;
+ const struct tcp_hdr *th;
+ uint16_t packet_id;
+ uint32_t sent_seq;
+ uint8_t *hdr_addr;
+ rte_iova_t hdr_iova;
+ struct rte_mbuf *first_m_seg = m_seg;
+ unsigned int pkt_start = *added;
+ unsigned int needed_desc;
+ struct rte_mbuf *m_seg_to_free_up_to = first_m_seg;
+ bool eop;
+
+ /* Both checks may be done, so use bit OR to have only one branching */
+ if (unlikely((header_len > SFC_TSOH_STD_LEN) |
+ (tcph_off > txq->tso_tcp_header_offset_limit)))
+ return EMSGSIZE;
+
+ /*
+ * Preliminary estimation of required DMA descriptors, including extra
+ * descriptor for TSO header that is needed when the header is
+ * separated from payload in one segment. It does not include
+ * extra descriptors that may appear when a big segment is split across
+ * several descriptors.
+ */
+ needed_desc = m_seg->nb_segs +
+ (unsigned int)SFC_TSO_OPT_DESCS_NUM +
+ (unsigned int)SFC_TSO_HDR_DESCS_NUM;
+
+ if (needed_desc > *dma_desc_space &&
+ !sfc_ef10_try_reap(txq, pkt_start, needed_desc,
+ dma_desc_space, reap_done)) {
+ /*
+ * If a future Tx reap may increase available DMA descriptor
+ * space, do not try to send the packet.
+ */
+ if (txq->completed != pkt_start)
+ return ENOSPC;
+ /*
+ * Do not allow to send packet if the maximum DMA
+ * descriptor space is not sufficient to hold TSO
+ * descriptors, header descriptor and at least 1
+ * segment descriptor.
+ */
+ if (*dma_desc_space < SFC_TSO_OPT_DESCS_NUM +
+ SFC_TSO_HDR_DESCS_NUM + 1)
+ return EMSGSIZE;
+ }
+
+ /* Check if the header is not fragmented */
+ if (rte_pktmbuf_data_len(m_seg) >= header_len) {
+ hdr_addr = rte_pktmbuf_mtod(m_seg, uint8_t *);
+ hdr_iova = rte_mbuf_data_iova(m_seg);
+ if (rte_pktmbuf_data_len(m_seg) == header_len) {
+ /*
+ * Associate header mbuf with header descriptor
+ * which is located after TSO descriptors.
+ */
+ txq->sw_ring[(pkt_start + SFC_TSO_OPT_DESCS_NUM) &
+ txq->ptr_mask].mbuf = m_seg;
+ m_seg = m_seg->next;
+ in_off = 0;
+
+ /*
+ * If there is no payload offset (payload starts at the
+ * beginning of a segment) then an extra descriptor for
+ * separated header is not needed.
+ */
+ needed_desc--;
+ } else {
+ in_off = header_len;
+ }
+ } else {
+ unsigned int copied_segs;
+ unsigned int hdr_addr_off = (*added & txq->ptr_mask) *
+ SFC_TSOH_STD_LEN;
+
+ hdr_addr = txq->tsoh + hdr_addr_off;
+ hdr_iova = txq->tsoh_iova + hdr_addr_off;
+ copied_segs = sfc_tso_prepare_header(hdr_addr, header_len,
+ &m_seg, &in_off);
+
+ m_seg_to_free_up_to = m_seg;
+ /*
+ * Reduce the number of needed descriptors by the number of
+ * segments that entirely consist of header data.
+ */
+ needed_desc -= copied_segs;
+
+ /* Extra descriptor for separated header is not needed */
+ if (in_off == 0)
+ needed_desc--;
+ }
+
+ switch (first_m_seg->ol_flags & (PKT_TX_IPV4 | PKT_TX_IPV6)) {
+ case PKT_TX_IPV4: {
+ const struct ipv4_hdr *iphe4;
+
+ iphe4 = (const struct ipv4_hdr *)(hdr_addr + iph_off);
+ rte_memcpy(&packet_id, &iphe4->packet_id, sizeof(uint16_t));
+ packet_id = rte_be_to_cpu_16(packet_id);
+ break;
+ }
+ case PKT_TX_IPV6:
+ packet_id = 0;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ th = (const struct tcp_hdr *)(hdr_addr + tcph_off);
+ rte_memcpy(&sent_seq, &th->sent_seq, sizeof(uint32_t));
+ sent_seq = rte_be_to_cpu_32(sent_seq);
+
+ sfc_ef10_tx_qdesc_tso2_create(txq, *added, packet_id, 0, sent_seq,
+ first_m_seg->tso_segsz);
+ (*added) += SFC_TSO_OPT_DESCS_NUM;
+
+ sfc_ef10_tx_qdesc_dma_create(hdr_iova, header_len, false,
+ &txq->txq_hw_ring[(*added) & txq->ptr_mask]);
+ (*added)++;
+
+ do {
+ rte_iova_t next_frag = rte_mbuf_data_iova(m_seg);
+ unsigned int seg_len = rte_pktmbuf_data_len(m_seg);
+ unsigned int id;
+
+ next_frag += in_off;
+ seg_len -= in_off;
+ in_off = 0;
+
+ do {
+ rte_iova_t frag_addr = next_frag;
+ size_t frag_len;
+
+ frag_len = RTE_MIN(seg_len,
+ SFC_EF10_TX_DMA_DESC_LEN_MAX);
+
+ next_frag += frag_len;
+ seg_len -= frag_len;
+
+ eop = (seg_len == 0 && m_seg->next == NULL);
+
+ id = (*added) & txq->ptr_mask;
+ (*added)++;
+
+ /*
+ * Initially we assume that one DMA descriptor is needed
+ * for every segment. When the segment is split across
+ * several DMA descriptors, increase the estimation.
+ */
+ needed_desc += (seg_len != 0);
+
+ /*
+ * When no more descriptors can be added, but not all
+ * segments are processed.
+ */
+ if (*added - pkt_start == *dma_desc_space &&
+ !eop &&
+ !sfc_ef10_try_reap(txq, pkt_start, needed_desc,
+ dma_desc_space, reap_done)) {
+ struct rte_mbuf *m;
+ struct rte_mbuf *m_next;
+
+ if (txq->completed != pkt_start) {
+ unsigned int i;
+
+ /*
+ * Reset mbuf associations with added
+ * descriptors.
+ */
+ for (i = pkt_start; i != *added; i++) {
+ id = i & txq->ptr_mask;
+ txq->sw_ring[id].mbuf = NULL;
+ }
+ return ENOSPC;
+ }
+
+ /* Free the segments that cannot be sent */
+ for (m = m_seg->next; m != NULL; m = m_next) {
+ m_next = m->next;
+ rte_pktmbuf_free_seg(m);
+ }
+ eop = true;
+ /* Ignore the rest of the segment */
+ seg_len = 0;
+ }
+
+ sfc_ef10_tx_qdesc_dma_create(frag_addr, frag_len,
+ eop, &txq->txq_hw_ring[id]);
+
+ } while (seg_len != 0);
+
+ txq->sw_ring[id].mbuf = m_seg;
+
+ m_seg = m_seg->next;
+ } while (!eop);
+
+ /*
+ * Free segments which content was entirely copied to the TSO header
+ * memory space of Tx queue
+ */
+ for (m_seg = first_m_seg; m_seg != m_seg_to_free_up_to;) {
+ struct rte_mbuf *seg_to_free = m_seg;
+
+ m_seg = m_seg->next;
+ rte_pktmbuf_free_seg(seg_to_free);
+ }
+
+ return 0;
+}
+
static uint16_t
sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
@@ -296,6 +572,30 @@ sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
if (likely(pktp + 1 != pktp_end))
rte_mbuf_prefetch_part1(pktp[1]);
+ if (m_seg->ol_flags & PKT_TX_TCP_SEG) {
+ int rc;
+
+ rc = sfc_ef10_xmit_tso_pkt(txq, m_seg, &added,
+ &dma_desc_space, &reap_done);
+ if (rc != 0) {
+ added = pkt_start;
+
+ /* Packet can be sent in following xmit calls */
+ if (likely(rc == ENOSPC))
+ break;
+
+ /*
+ * Packet cannot be sent, tell RTE that
+ * it is sent, but actually drop it and
+ * continue with another packet
+ */
+ rte_pktmbuf_free(*pktp);
+ continue;
+ }
+
+ goto dma_desc_space_update;
+ }
+
if (sfc_ef10_tx_pkt_descs_max(m_seg) > dma_desc_space) {
if (reap_done)
break;
@@ -349,6 +649,7 @@ sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
} while ((m_seg = m_seg->next) != 0);
+dma_desc_space_update:
dma_desc_space -= (added - pkt_start);
}
@@ -524,6 +825,18 @@ sfc_ef10_tx_qcreate(uint16_t port_id, uint16_t queue_id,
if (txq->sw_ring == NULL)
goto fail_sw_ring_alloc;
+ if (info->offloads & DEV_TX_OFFLOAD_TCP_TSO) {
+ txq->tsoh = rte_calloc_socket("sfc-ef10-txq-tsoh",
+ info->txq_entries,
+ SFC_TSOH_STD_LEN,
+ RTE_CACHE_LINE_SIZE,
+ socket_id);
+ if (txq->tsoh == NULL)
+ goto fail_tsoh_alloc;
+
+ txq->tsoh_iova = rte_malloc_virt2iova(txq->tsoh);
+ }
+
txq->flags = SFC_EF10_TXQ_NOT_RUNNING;
txq->ptr_mask = info->txq_entries - 1;
txq->max_fill_level = info->max_fill_level;
@@ -533,10 +846,14 @@ sfc_ef10_tx_qcreate(uint16_t port_id, uint16_t queue_id,
ER_DZ_TX_DESC_UPD_REG_OFST +
(info->hw_index << info->vi_window_shift);
txq->evq_hw_ring = info->evq_hw_ring;
+ txq->tso_tcp_header_offset_limit = info->tso_tcp_header_offset_limit;
*dp_txqp = &txq->dp;
return 0;
+fail_tsoh_alloc:
+ rte_free(txq->sw_ring);
+
fail_sw_ring_alloc:
rte_free(txq);
@@ -551,6 +868,7 @@ sfc_ef10_tx_qdestroy(struct sfc_dp_txq *dp_txq)
{
struct sfc_ef10_txq *txq = sfc_ef10_txq_by_dp_txq(dp_txq);
+ rte_free(txq->tsoh);
rte_free(txq->sw_ring);
rte_free(txq);
}
@@ -618,12 +936,49 @@ sfc_ef10_tx_qreap(struct sfc_dp_txq *dp_txq)
txq->flags &= ~SFC_EF10_TXQ_STARTED;
}
+static unsigned int
+sfc_ef10_tx_qdesc_npending(struct sfc_ef10_txq *txq)
+{
+ const unsigned int curr_done = txq->completed - 1;
+ unsigned int anew_done = curr_done;
+ efx_qword_t tx_ev;
+ const unsigned int evq_old_read_ptr = txq->evq_read_ptr;
+
+ if (unlikely(txq->flags &
+ (SFC_EF10_TXQ_NOT_RUNNING | SFC_EF10_TXQ_EXCEPTION)))
+ return 0;
+
+ while (sfc_ef10_tx_get_event(txq, &tx_ev))
+ anew_done = EFX_QWORD_FIELD(tx_ev, ESF_DZ_TX_DESCR_INDX);
+
+ /*
+ * The function does not process events, so return event queue read
+ * pointer to the original position to allow the events that were
+ * read to be processed later
+ */
+ txq->evq_read_ptr = evq_old_read_ptr;
+
+ return (anew_done - curr_done) & txq->ptr_mask;
+}
+
static sfc_dp_tx_qdesc_status_t sfc_ef10_tx_qdesc_status;
static int
-sfc_ef10_tx_qdesc_status(__rte_unused struct sfc_dp_txq *dp_txq,
- __rte_unused uint16_t offset)
+sfc_ef10_tx_qdesc_status(struct sfc_dp_txq *dp_txq,
+ uint16_t offset)
{
- return -ENOTSUP;
+ struct sfc_ef10_txq *txq = sfc_ef10_txq_by_dp_txq(dp_txq);
+ unsigned int npending = sfc_ef10_tx_qdesc_npending(txq);
+
+ if (unlikely(offset > txq->ptr_mask))
+ return -EINVAL;
+
+ if (unlikely(offset >= txq->max_fill_level))
+ return RTE_ETH_TX_DESC_UNAVAIL;
+
+ if (unlikely(offset < npending))
+ return RTE_ETH_TX_DESC_FULL;
+
+ return RTE_ETH_TX_DESC_DONE;
}
struct sfc_dp_tx sfc_ef10_tx = {
@@ -632,7 +987,8 @@ struct sfc_dp_tx sfc_ef10_tx = {
.type = SFC_DP_TX,
.hw_fw_caps = SFC_DP_HW_FW_CAP_EF10,
},
- .features = SFC_DP_TX_FEAT_MULTI_SEG |
+ .features = SFC_DP_TX_FEAT_TSO |
+ SFC_DP_TX_FEAT_MULTI_SEG |
SFC_DP_TX_FEAT_MULTI_POOL |
SFC_DP_TX_FEAT_REFCNT |
SFC_DP_TX_FEAT_MULTI_PROCESS,
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 9decbf5a..3886daf7 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -171,6 +171,9 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
sa->dp_rx->get_dev_info(dev_info);
if (sa->dp_tx->get_dev_info != NULL)
sa->dp_tx->get_dev_info(dev_info);
+
+ dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
+ RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP;
}
static const uint32_t *
@@ -441,8 +444,6 @@ sfc_rx_queue_release(void *queue)
sfc_log_init(sa, "RxQ=%u", sw_index);
- sa->eth_dev->data->rx_queues[sw_index] = NULL;
-
sfc_rx_qfini(sa, sw_index);
sfc_adapter_unlock(sa);
@@ -497,9 +498,6 @@ sfc_tx_queue_release(void *queue)
sfc_adapter_lock(sa);
- SFC_ASSERT(sw_index < sa->eth_dev->data->nb_tx_queues);
- sa->eth_dev->data->tx_queues[sw_index] = NULL;
-
sfc_tx_qfini(sa, sw_index);
sfc_adapter_unlock(sa);
@@ -1143,6 +1141,9 @@ sfc_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
if (sa->state != SFC_ADAPTER_STARTED)
goto fail_not_started;
+ if (sa->rxq_info[rx_queue_id].rxq == NULL)
+ goto fail_not_setup;
+
rc = sfc_rx_qstart(sa, rx_queue_id);
if (rc != 0)
goto fail_rx_qstart;
@@ -1154,6 +1155,7 @@ sfc_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
return 0;
fail_rx_qstart:
+fail_not_setup:
fail_not_started:
sfc_adapter_unlock(sa);
SFC_ASSERT(rc > 0);
@@ -1191,6 +1193,9 @@ sfc_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
if (sa->state != SFC_ADAPTER_STARTED)
goto fail_not_started;
+ if (sa->txq_info[tx_queue_id].txq == NULL)
+ goto fail_not_setup;
+
rc = sfc_tx_qstart(sa, tx_queue_id);
if (rc != 0)
goto fail_tx_qstart;
@@ -1202,6 +1207,7 @@ sfc_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
fail_tx_qstart:
+fail_not_setup:
fail_not_started:
sfc_adapter_unlock(sa);
SFC_ASSERT(rc > 0);
@@ -1348,14 +1354,10 @@ sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
{
struct sfc_adapter *sa = dev->data->dev_private;
struct sfc_rss *rss = &sa->rss;
- struct sfc_port *port = &sa->port;
- if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE || port->isolated)
+ if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE)
return -ENOTSUP;
- if (rss->channels == 0)
- return -EINVAL;
-
sfc_adapter_lock(sa);
/*
@@ -2033,9 +2035,6 @@ sfc_eth_dev_uninit(struct rte_eth_dev *dev)
sfc_detach(sa);
sfc_unprobe(sa);
- rte_free(dev->data->mac_addrs);
- dev->data->mac_addrs = NULL;
-
sfc_kvargs_cleanup(sa);
sfc_adapter_unlock(sa);
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index d8503e20..c792e0b2 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -96,13 +96,12 @@ sfc_efx_rx_qrefill(struct sfc_efx_rxq *rxq)
++i, id = (id + 1) & rxq->ptr_mask) {
m = objs[i];
+ MBUF_RAW_ALLOC_CHECK(m);
+
rxd = &rxq->sw_desc[id];
rxd->mbuf = m;
- SFC_ASSERT(rte_mbuf_refcnt_read(m) == 1);
m->data_off = RTE_PKTMBUF_HEADROOM;
- SFC_ASSERT(m->next == NULL);
- SFC_ASSERT(m->nb_segs == 1);
m->port = port_id;
addr[i] = rte_pktmbuf_iova(m);
@@ -296,7 +295,7 @@ sfc_efx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
discard:
discard_next = ((desc_flags & EFX_PKT_CONT) != 0);
- rte_mempool_put(rxq->refill_mb_pool, m);
+ rte_mbuf_raw_free(m);
rxd->mbuf = NULL;
}
@@ -498,7 +497,7 @@ sfc_efx_rx_qpurge(struct sfc_dp_rxq *dp_rxq)
for (i = rxq->completed; i != rxq->added; ++i) {
rxd = &rxq->sw_desc[i & rxq->ptr_mask];
- rte_mempool_put(rxq->refill_mb_pool, rxd->mbuf);
+ rte_mbuf_raw_free(rxd->mbuf);
rxd->mbuf = NULL;
/* Packed stream relies on 0 in inactive SW desc.
* Rx queue stop is not performance critical, so
@@ -673,6 +672,7 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
rxq_info = &sa->rxq_info[sw_index];
rxq = rxq_info->rxq;
+ SFC_ASSERT(rxq != NULL);
SFC_ASSERT(rxq->state == SFC_RXQ_INITIALIZED);
evq = rxq->evq;
@@ -763,7 +763,7 @@ sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
rxq_info = &sa->rxq_info[sw_index];
rxq = rxq_info->rxq;
- if (rxq->state == SFC_RXQ_INITIALIZED)
+ if (rxq == NULL || rxq->state == SFC_RXQ_INITIALIZED)
return;
SFC_ASSERT(rxq->state & SFC_RXQ_STARTED);
@@ -792,7 +792,6 @@ sfc_rx_get_dev_offload_caps(struct sfc_adapter *sa)
uint64_t caps = 0;
caps |= DEV_RX_OFFLOAD_JUMBO_FRAME;
- caps |= DEV_RX_OFFLOAD_CRC_STRIP;
if (sa->dp_rx->features & SFC_DP_RX_FEAT_CHECKSUM) {
caps |= DEV_RX_OFFLOAD_IPV4_CKSUM;
@@ -1103,6 +1102,7 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
struct sfc_rxq *rxq;
SFC_ASSERT(sw_index < sa->rxq_count);
+ sa->eth_dev->data->rx_queues[sw_index] = NULL;
rxq_info = &sa->rxq_info[sw_index];
@@ -1126,7 +1126,7 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
/*
* Mapping between RTE RSS hash functions and their EFX counterparts.
*/
-struct sfc_rss_hf_rte_to_efx sfc_rss_hf_map[] = {
+static const struct sfc_rss_hf_rte_to_efx sfc_rss_hf_map[] = {
{ ETH_RSS_NONFRAG_IPV4_TCP,
EFX_RX_HASH(IPV4_TCP, 4TUPLE) },
{ ETH_RSS_NONFRAG_IPV4_UDP,
@@ -1200,7 +1200,7 @@ sfc_rx_hash_init(struct sfc_adapter *sa)
return EINVAL;
rc = efx_rx_scale_hash_flags_get(sa->nic, alg, flags_supp,
- &nb_flags_supp);
+ RTE_DIM(flags_supp), &nb_flags_supp);
if (rc != 0)
return rc;
@@ -1363,7 +1363,8 @@ sfc_rx_start(struct sfc_adapter *sa)
goto fail_rss_config;
for (sw_index = 0; sw_index < sa->rxq_count; ++sw_index) {
- if ((!sa->rxq_info[sw_index].deferred_start ||
+ if (sa->rxq_info[sw_index].rxq != NULL &&
+ (!sa->rxq_info[sw_index].deferred_start ||
sa->rxq_info[sw_index].deferred_started)) {
rc = sfc_rx_qstart(sa, sw_index);
if (rc != 0)
@@ -1439,14 +1440,6 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode)
rc = EINVAL;
}
- /* KEEP_CRC offload flag is not supported by PMD
- * can remove the below block when DEV_RX_OFFLOAD_CRC_STRIP removed
- */
- if (rte_eth_dev_must_keep_crc(rxmode->offloads)) {
- sfc_warn(sa, "FCS stripping cannot be disabled - always on");
- rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
- }
-
/*
* Requested offloads are validated against supported by ethdev,
* so unsupported offloads cannot be added as the result of
@@ -1511,7 +1504,7 @@ sfc_rx_configure(struct sfc_adapter *sa)
goto fail_check_mode;
if (nb_rx_queues == sa->rxq_count)
- goto done;
+ goto configure_rss;
if (sa->rxq_info == NULL) {
rc = ENOMEM;
@@ -1548,6 +1541,7 @@ sfc_rx_configure(struct sfc_adapter *sa)
sa->rxq_count++;
}
+configure_rss:
rss->channels = (dev_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) ?
MIN(sa->rxq_count, EFX_MAXRSS) : 0;
@@ -1564,7 +1558,6 @@ sfc_rx_configure(struct sfc_adapter *sa)
goto fail_rx_process_adv_conf_rss;
}
-done:
return 0;
fail_rx_process_adv_conf_rss:
diff --git a/drivers/net/sfc/sfc_tso.c b/drivers/net/sfc/sfc_tso.c
index effe9853..076a25d4 100644
--- a/drivers/net/sfc/sfc_tso.c
+++ b/drivers/net/sfc/sfc_tso.c
@@ -14,12 +14,7 @@
#include "sfc_debug.h"
#include "sfc_tx.h"
#include "sfc_ev.h"
-
-/** Standard TSO header length */
-#define SFC_TSOH_STD_LEN 256
-
-/** The number of TSO option descriptors that precede the packet descriptors */
-#define SFC_TSO_OPDESCS_IDX_SHIFT 2
+#include "sfc_tso.h"
int
sfc_efx_tso_alloc_tsoh_objs(struct sfc_efx_tx_sw_desc *sw_ring,
@@ -57,13 +52,14 @@ sfc_efx_tso_free_tsoh_objs(struct sfc_efx_tx_sw_desc *sw_ring,
}
}
-static void
-sfc_efx_tso_prepare_header(struct sfc_efx_txq *txq, struct rte_mbuf **in_seg,
- size_t *in_off, unsigned int idx, size_t bytes_left)
+unsigned int
+sfc_tso_prepare_header(uint8_t *tsoh, size_t header_len,
+ struct rte_mbuf **in_seg, size_t *in_off)
{
struct rte_mbuf *m = *in_seg;
size_t bytes_to_copy = 0;
- uint8_t *tsoh = txq->sw_ring[idx & txq->ptr_mask].tsoh;
+ size_t bytes_left = header_len;
+ unsigned int segments_copied = 0;
do {
bytes_to_copy = MIN(bytes_left, m->data_len);
@@ -77,16 +73,20 @@ sfc_efx_tso_prepare_header(struct sfc_efx_txq *txq, struct rte_mbuf **in_seg,
if (bytes_left > 0) {
m = m->next;
SFC_ASSERT(m != NULL);
+ segments_copied++;
}
} while (bytes_left > 0);
if (bytes_to_copy == m->data_len) {
*in_seg = m->next;
*in_off = 0;
+ segments_copied++;
} else {
*in_seg = m;
*in_off = bytes_to_copy;
}
+
+ return segments_copied;
}
int
@@ -105,7 +105,7 @@ sfc_efx_tso_do(struct sfc_efx_txq *txq, unsigned int idx,
size_t header_len = m->l2_len + m->l3_len + m->l4_len;
const efx_nic_cfg_t *encp = efx_nic_cfg_get(txq->evq->sa->nic);
- idx += SFC_TSO_OPDESCS_IDX_SHIFT;
+ idx += SFC_TSO_OPT_DESCS_NUM;
/* Packets which have too big headers should be discarded */
if (unlikely(header_len > SFC_TSOH_STD_LEN))
@@ -129,9 +129,8 @@ sfc_efx_tso_do(struct sfc_efx_txq *txq, unsigned int idx,
* limitations on address boundaries crossing by DMA descriptor data.
*/
if (m->data_len < header_len) {
- sfc_efx_tso_prepare_header(txq, in_seg, in_off, idx,
- header_len);
tsoh = txq->sw_ring[idx & txq->ptr_mask].tsoh;
+ sfc_tso_prepare_header(tsoh, header_len, in_seg, in_off);
header_paddr = rte_malloc_virt2iova((void *)tsoh);
} else {
diff --git a/drivers/net/sfc/sfc_tso.h b/drivers/net/sfc/sfc_tso.h
new file mode 100644
index 00000000..3d2faf54
--- /dev/null
+++ b/drivers/net/sfc/sfc_tso.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2018 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ */
+
+/** Standard TSO header length */
+#define SFC_TSOH_STD_LEN 256
+
+/** The number of TSO option descriptors that precede the packet descriptors */
+#define SFC_TSO_OPT_DESCS_NUM 2
+
+/**
+ * The number of DMA descriptors for TSO header that may or may not precede the
+ * packet's payload descriptors
+ */
+#define SFC_TSO_HDR_DESCS_NUM 1
+
+unsigned int sfc_tso_prepare_header(uint8_t *tsoh, size_t header_len,
+ struct rte_mbuf **in_seg, size_t *in_off);
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 6d42a1a6..147f9336 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -190,6 +190,8 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
info.hw_index = txq->hw_index;
info.mem_bar = sa->mem_bar.esb_base;
info.vi_window_shift = encp->enc_vi_window_shift;
+ info.tso_tcp_header_offset_limit =
+ encp->enc_tx_tso_tcp_header_offset_limit;
rc = sa->dp_tx->qcreate(sa->eth_dev->data->port_id, sw_index,
&RTE_ETH_DEV_TO_PCI(sa->eth_dev)->addr,
@@ -233,6 +235,8 @@ sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
sfc_log_init(sa, "TxQ = %u", sw_index);
SFC_ASSERT(sw_index < sa->txq_count);
+ sa->eth_dev->data->tx_queues[sw_index] = NULL;
+
txq_info = &sa->txq_info[sw_index];
txq = txq_info->txq;
@@ -421,6 +425,7 @@ sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
txq = txq_info->txq;
+ SFC_ASSERT(txq != NULL);
SFC_ASSERT(txq->state == SFC_TXQ_INITIALIZED);
evq = txq->evq;
@@ -501,7 +506,7 @@ sfc_tx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
txq = txq_info->txq;
- if (txq->state == SFC_TXQ_INITIALIZED)
+ if (txq == NULL || txq->state == SFC_TXQ_INITIALIZED)
return;
SFC_ASSERT(txq->state & SFC_TXQ_STARTED);
@@ -578,8 +583,9 @@ sfc_tx_start(struct sfc_adapter *sa)
goto fail_efx_tx_init;
for (sw_index = 0; sw_index < sa->txq_count; ++sw_index) {
- if (!(sa->txq_info[sw_index].deferred_start) ||
- sa->txq_info[sw_index].deferred_started) {
+ if (sa->txq_info[sw_index].txq != NULL &&
+ (!(sa->txq_info[sw_index].deferred_start) ||
+ sa->txq_info[sw_index].deferred_started)) {
rc = sfc_tx_qstart(sa, sw_index);
if (rc != 0)
goto fail_tx_qstart;