From owner-svn-src-stable-10@freebsd.org Thu Jan 14 15:26:08 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6AAE0A82081; Thu, 14 Jan 2016 15:26:08 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 287D711C3; Thu, 14 Jan 2016 15:26:08 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u0EFQ79n043162; Thu, 14 Jan 2016 15:26:07 GMT (envelope-from arybchik@FreeBSD.org) Received: (from arybchik@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u0EFQ6AC043158; Thu, 14 Jan 2016 15:26:06 GMT (envelope-from arybchik@FreeBSD.org) Message-Id: <201601141526.u0EFQ6AC043158@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: arybchik set sender to arybchik@FreeBSD.org using -f From: Andrew Rybchenko Date: Thu, 14 Jan 2016 15:26:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r293961 - stable/10/sys/dev/sfxge/common X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jan 2016 15:26:08 -0000 Author: arybchik Date: Thu Jan 14 15:26:06 2016 New Revision: 293961 URL: https://svnweb.freebsd.org/changeset/base/293961 Log: MFC r292007 sfxge: [4/6] rework MCDI response polling Required for MCDI proxy authorization support. Submitted by: Andy Moreton Sponsored by: Solarflare Communications, Inc. Modified: stable/10/sys/dev/sfxge/common/efx_mcdi.c stable/10/sys/dev/sfxge/common/efx_mcdi.h stable/10/sys/dev/sfxge/common/hunt_mcdi.c stable/10/sys/dev/sfxge/common/siena_mcdi.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sfxge/common/efx_mcdi.c ============================================================================== --- stable/10/sys/dev/sfxge/common/efx_mcdi.c Thu Jan 14 15:25:17 2016 (r293960) +++ stable/10/sys/dev/sfxge/common/efx_mcdi.c Thu Jan 14 15:26:06 2016 (r293961) @@ -228,6 +228,114 @@ efx_mcdi_request_start( emcop->emco_request_copyin(enp, emrp, seq, ev_cpl, new_epoch); } + + void +efx_mcdi_read_response_header( + __in efx_nic_t *enp, + __inout efx_mcdi_req_t *emrp) +{ +#if EFSYS_OPT_MCDI_LOGGING + const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; +#endif /* EFSYS_OPT_MCDI_LOGGING */ + efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); + efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop; + efx_dword_t hdr[2]; + unsigned int hdr_len; + unsigned int data_len; + unsigned int seq; + unsigned int cmd; + unsigned int error; + efx_rc_t rc; + + EFSYS_ASSERT(emrp != NULL); + + emcop->emco_read_response(enp, &hdr[0], 0, sizeof (hdr[0])); + hdr_len = sizeof (hdr[0]); + + cmd = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE); + seq = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_SEQ); + error = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR); + + if (cmd != MC_CMD_V2_EXTN) { + data_len = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_DATALEN); + } else { + emcop->emco_read_response(enp, &hdr[1], hdr_len, + sizeof (hdr[1])); + hdr_len += sizeof (hdr[1]); + + cmd = EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_EXTENDED_CMD); + data_len = + EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN); + } + + if (error && (data_len == 0)) { + /* The MC has rebooted since the request was sent. */ + EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US); + emcop->emco_poll_reboot(enp); + rc = EIO; + goto fail1; + } + if ((cmd != emrp->emr_cmd) || + (seq != ((emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ)))) { + /* Response is for a different request */ + rc = EIO; + goto fail2; + } + if (error) { + efx_dword_t err[2]; + unsigned int err_len = MIN(data_len, sizeof (err)); + int err_code = MC_CMD_ERR_EPROTO; + int err_arg = 0; + + /* Read error code (and arg num for MCDI v2 commands) */ + emcop->emco_read_response(enp, &err, hdr_len, err_len); + + if (err_len >= (MC_CMD_ERR_CODE_OFST + sizeof (efx_dword_t))) + err_code = EFX_DWORD_FIELD(err[0], EFX_DWORD_0); +#ifdef WITH_MCDI_V2 + if (err_len >= (MC_CMD_ERR_ARG_OFST + sizeof (efx_dword_t))) + err_arg = EFX_DWORD_FIELD(err[1], EFX_DWORD_0); +#endif + emrp->emr_err_code = err_code; + emrp->emr_err_arg = err_arg; + +#if EFSYS_OPT_MCDI_LOGGING + if (emtp->emt_logger != NULL) { + emtp->emt_logger(emtp->emt_context, + EFX_LOG_MCDI_RESPONSE, + &hdr, hdr_len, + &err, err_len); + } +#endif /* EFSYS_OPT_MCDI_LOGGING */ + + if (!emrp->emr_quiet) { + EFSYS_PROBE3(mcdi_err_arg, int, emrp->emr_cmd, + int, err_code, int, err_arg); + } + + rc = efx_mcdi_request_errcode(err_code); + goto fail3; + } + + emrp->emr_rc = 0; + emrp->emr_out_length_used = data_len; + return; + +fail3: + if (!emrp->emr_quiet) + EFSYS_PROBE(fail3); +fail2: + if (!emrp->emr_quiet) + EFSYS_PROBE(fail2); +fail1: + if (!emrp->emr_quiet) + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + emrp->emr_rc = rc; + emrp->emr_out_length_used = 0; +} + + __checkReturn boolean_t efx_mcdi_request_poll( __in efx_nic_t *enp) Modified: stable/10/sys/dev/sfxge/common/efx_mcdi.h ============================================================================== --- stable/10/sys/dev/sfxge/common/efx_mcdi.h Thu Jan 14 15:25:17 2016 (r293960) +++ stable/10/sys/dev/sfxge/common/efx_mcdi.h Thu Jan 14 15:26:06 2016 (r293961) @@ -59,6 +59,9 @@ struct efx_mcdi_req_s { uint8_t *emr_out_buf; size_t emr_out_length; size_t emr_out_length_used; + /* Internals: low level transport details */ + unsigned int emr_err_code; + unsigned int emr_err_arg; }; typedef struct efx_mcdi_iface_s { @@ -82,6 +85,11 @@ efx_mcdi_execute_quiet( __in efx_nic_t *enp, __inout efx_mcdi_req_t *emrp); + extern void +efx_mcdi_read_response_header( + __in efx_nic_t *enp, + __inout efx_mcdi_req_t *emrp); + extern void efx_mcdi_ev_cpl( __in efx_nic_t *enp, Modified: stable/10/sys/dev/sfxge/common/hunt_mcdi.c ============================================================================== --- stable/10/sys/dev/sfxge/common/hunt_mcdi.c Thu Jan 14 15:25:17 2016 (r293960) +++ stable/10/sys/dev/sfxge/common/hunt_mcdi.c Thu Jan 14 15:26:06 2016 (r293961) @@ -308,11 +308,6 @@ hunt_mcdi_request_poll( #endif /* EFSYS_OPT_MCDI_LOGGING */ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); efx_mcdi_req_t *emrp; - efx_dword_t hdr[2]; - unsigned int hdr_len; - unsigned int data_len; - unsigned int seq; - unsigned int cmd; int state; efx_rc_t rc; @@ -332,101 +327,26 @@ hunt_mcdi_request_poll( } /* Read the response header */ - hdr_len = sizeof (hdr[0]); - hunt_mcdi_read_response(enp, &hdr[0], 0, hdr_len); - - if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) { - hunt_mcdi_read_response(enp, &hdr[1], hdr_len, sizeof (hdr[1])); - hdr_len += sizeof (hdr[1]); - - cmd = EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_EXTENDED_CMD); - data_len = - EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN); - } else { - cmd = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE); - data_len = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_DATALEN); - } + efx_mcdi_read_response_header(enp, emrp); /* Request complete */ emip->emi_pending_req = NULL; - seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ); - - /* Check for synchronous reboot */ - if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR) != 0 && data_len == 0) { - /* The MC has rebooted since the request was sent. */ - EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US); - hunt_mcdi_poll_reboot(enp); - - EFSYS_UNLOCK(enp->en_eslp, state); - rc = EIO; - goto fail1; - } /* Ensure stale MCDI requests fail after an MC reboot. */ emip->emi_new_epoch = B_FALSE; EFSYS_UNLOCK(enp->en_eslp, state); - /* Check that the returned data is consistent */ - if (cmd != emrp->emr_cmd || - EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_SEQ) != seq) { - /* Response is for a different request */ - rc = EIO; - goto fail2; - } - if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR)) { - efx_dword_t err[2]; - unsigned int err_len = MIN(data_len, sizeof (err)); - int err_code = MC_CMD_ERR_EPROTO; - int err_arg = 0; - - /* Read error code (and arg num for MCDI v2 commands) */ - hunt_mcdi_read_response(enp, &err[0], hdr_len, err_len); - - if (err_len >= MC_CMD_ERR_CODE_OFST + sizeof (efx_dword_t)) - err_code = EFX_DWORD_FIELD(err[0], EFX_DWORD_0); - - if (err_len >= MC_CMD_ERR_ARG_OFST + sizeof (efx_dword_t)) - err_arg = EFX_DWORD_FIELD(err[1], EFX_DWORD_0); - -#if EFSYS_OPT_MCDI_LOGGING - if (emtp->emt_logger != NULL) { - emtp->emt_logger(emtp->emt_context, - EFX_LOG_MCDI_RESPONSE, - &hdr, hdr_len, - &err, err_len); - } -#endif /* EFSYS_OPT_MCDI_LOGGING */ - - rc = efx_mcdi_request_errcode(err_code); - if (!emrp->emr_quiet) { - EFSYS_PROBE3(mcdi_err_arg, int, emrp->emr_cmd, - int, err_code, int, err_arg); - } - goto fail3; - - } else { - emrp->emr_out_length_used = data_len; - emrp->emr_rc = 0; - hunt_mcdi_request_copyout(enp, emrp); - } + if ((rc = emrp->emr_rc) != 0) + goto fail1; + hunt_mcdi_request_copyout(enp, emrp); goto out; -fail3: - if (!emrp->emr_quiet) - EFSYS_PROBE(fail3); -fail2: - if (!emrp->emr_quiet) - EFSYS_PROBE(fail2); fail1: if (!emrp->emr_quiet) EFSYS_PROBE1(fail1, efx_rc_t, rc); - /* Fill out error state */ - emrp->emr_rc = rc; - emrp->emr_out_length_used = 0; - /* Reboot/Assertion */ if (rc == EIO || rc == EINTR) efx_mcdi_raise_exception(enp, emrp, rc); Modified: stable/10/sys/dev/sfxge/common/siena_mcdi.c ============================================================================== --- stable/10/sys/dev/sfxge/common/siena_mcdi.c Thu Jan 14 15:25:17 2016 (r293960) +++ stable/10/sys/dev/sfxge/common/siena_mcdi.c Thu Jan 14 15:26:06 2016 (r293961) @@ -222,15 +222,8 @@ siena_mcdi_read_response( siena_mcdi_request_poll( __in efx_nic_t *enp) { -#if EFSYS_OPT_MCDI_LOGGING - const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; -#endif efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); efx_mcdi_req_t *emrp; - efx_dword_t hdr; - unsigned int hdr_len; - unsigned int data_len; - unsigned int seq; int state; efx_rc_t rc; @@ -260,76 +253,19 @@ siena_mcdi_request_poll( } /* Read the response header */ - hdr_len = sizeof (hdr); - siena_mcdi_read_response(enp, &hdr, 0, hdr_len); + efx_mcdi_read_response_header(enp, emrp); /* Request complete */ emip->emi_pending_req = NULL; - seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ); - - /* Check for synchronous reboot */ - if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_ERROR) != 0 && - EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN) == 0) { - /* Consume status word */ - EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US); - siena_mcdi_poll_reboot(enp); - EFSYS_UNLOCK(enp->en_eslp, state); - rc = EIO; - goto fail2; - } EFSYS_UNLOCK(enp->en_eslp, state); - /* Check that the returned data is consistent */ - if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_CODE) != emrp->emr_cmd || - EFX_DWORD_FIELD(hdr, MCDI_HEADER_SEQ) != seq) { - /* Response is for a different request */ - rc = EIO; - goto fail3; - } - - data_len = EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN); - if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_ERROR)) { - efx_dword_t err; - int err_code = MC_CMD_ERR_EPROTO; - unsigned int err_len = MIN(data_len, sizeof (err)); - - /* Read error code */ - siena_mcdi_read_response(enp, &err, hdr_len, err_len); - - if (err_len >= MC_CMD_ERR_CODE_OFST + sizeof (efx_dword_t)) - err_code = EFX_DWORD_FIELD(err, EFX_DWORD_0); - -#if EFSYS_OPT_MCDI_LOGGING - if (emtp->emt_logger != NULL) { - emtp->emt_logger(emtp->emt_context, - EFX_LOG_MCDI_RESPONSE, - &hdr, hdr_len, - &err, err_len); - } -#endif /* EFSYS_OPT_MCDI_LOGGING */ - - rc = efx_mcdi_request_errcode(err_code); - if (!emrp->emr_quiet) { - EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd, - int, err_code); - } - goto fail4; - - } else { - emrp->emr_out_length_used = data_len; - emrp->emr_rc = 0; - siena_mcdi_request_copyout(enp, emrp); - } + if ((rc = emrp->emr_rc) != 0) + goto fail2; + siena_mcdi_request_copyout(enp, emrp); goto out; -fail4: - if (!emrp->emr_quiet) - EFSYS_PROBE(fail4); -fail3: - if (!emrp->emr_quiet) - EFSYS_PROBE(fail3); fail2: if (!emrp->emr_quiet) EFSYS_PROBE(fail2); @@ -337,10 +273,6 @@ fail1: if (!emrp->emr_quiet) EFSYS_PROBE1(fail1, efx_rc_t, rc); - /* Fill out error state */ - emrp->emr_rc = rc; - emrp->emr_out_length_used = 0; - /* Reboot/Assertion */ if (rc == EIO || rc == EINTR) efx_mcdi_raise_exception(enp, emrp, rc);