req.emr_out_length = MC_CMD_DRV_ATTACH_EXT_OUT_LEN;
/*
- * Use DONT_CARE for the datapath firmware type to ensure that the
- * driver can attach to an unprivileged function. The datapath firmware
- * type to use is controlled by the 'sfboot' utility.
+ * Typically, client drivers use DONT_CARE for the datapath firmware
+ * type to ensure that the driver can attach to an unprivileged
+ * function. The datapath firmware type to use is controlled by the
+ * 'sfboot' utility.
+ * If a client driver wishes to attach with a specific datapath firmware
+ * type, that can be passed in second argument of efx_nic_probe API. One
+ * such example is the ESXi native driver that attempts attaching with
+ * FULL_FEATURED datapath firmware type first and fall backs to
+ * DONT_CARE datapath firmware type if MC_CMD_DRV_ATTACH fails.
*/
- MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_NEW_STATE, attach ? 1 : 0);
+ MCDI_IN_POPULATE_DWORD_2(req, DRV_ATTACH_IN_NEW_STATE,
+ DRV_ATTACH_IN_ATTACH, attach ? 1 : 0,
+ DRV_ATTACH_IN_SUBVARIANT_AWARE, EFSYS_OPT_FW_SUBVARIANT_AWARE);
MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_UPDATE, 1);
- MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_FIRMWARE_ID, MC_CMD_FW_DONT_CARE);
+ MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_FIRMWARE_ID, enp->efv);
efx_mcdi_execute(enp, &req);
{
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_MAC_STATS_IN_LEN,
- MC_CMD_MAC_STATS_OUT_DMA_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);
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_MAC_STATS_IN_LEN;
req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_MAC_STATS_OUT_DMA_LEN;
+ req.emr_out_length = MC_CMD_MAC_STATS_V2_OUT_DMA_LEN;
MCDI_IN_POPULATE_DWORD_6(req, MAC_STATS_IN_CMD,
MAC_STATS_IN_DMA, upload,
MAC_STATS_IN_PERIODIC_NOEVENT, !events,
MAC_STATS_IN_PERIOD_MS, (enable | events) ? period_ms : 0);
- if (esmp != NULL) {
- int bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t);
+ if (enable || events || upload) {
+ const efx_nic_cfg_t *encp = &enp->en_nic_cfg;
+ uint32_t bytes;
- EFX_STATIC_ASSERT(MC_CMD_MAC_NSTATS * sizeof (uint64_t) <=
- EFX_MAC_STATS_SIZE);
+ /* Periodic stats or stats upload require a DMA buffer */
+ if (esmp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ if (encp->enc_mac_stats_nstats < MC_CMD_MAC_NSTATS) {
+ /* MAC stats count too small for legacy MAC stats */
+ rc = ENOSPC;
+ goto fail2;
+ }
+
+ bytes = encp->enc_mac_stats_nstats * sizeof (efx_qword_t);
+
+ if (EFSYS_MEM_SIZE(esmp) < bytes) {
+ /* DMA buffer too small */
+ rc = ENOSPC;
+ goto fail3;
+ }
MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO,
EFSYS_MEM_ADDR(esmp) & 0xffffffff);
MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI,
EFSYS_MEM_ADDR(esmp) >> 32);
MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes);
- } else {
- EFSYS_ASSERT(!upload && !enable && !events);
}
/*
if ((req.emr_rc != ENOENT) ||
(enp->en_rx_qcount + enp->en_tx_qcount != 0)) {
rc = req.emr_rc;
- goto fail1;
+ goto fail4;
}
}
return (0);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);