From owner-svn-src-stable-10@freebsd.org Thu Jan 14 15:25:19 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 37283A81FE5; Thu, 14 Jan 2016 15:25:19 +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 04B6B1FFD; Thu, 14 Jan 2016 15:25:18 +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 u0EFPHfJ043078; Thu, 14 Jan 2016 15:25:17 GMT (envelope-from arybchik@FreeBSD.org) Received: (from arybchik@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u0EFPH9U043072; Thu, 14 Jan 2016 15:25:17 GMT (envelope-from arybchik@FreeBSD.org) Message-Id: <201601141525.u0EFPH9U043072@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:25:17 +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: r293960 - 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:25:19 -0000 Author: arybchik Date: Thu Jan 14 15:25:17 2016 New Revision: 293960 URL: https://svnweb.freebsd.org/changeset/base/293960 Log: MFC r291985 sfxge: [3/6] rework MCDI response handling Required for MCDI proxy authorization support. Submitted by: Andy Moreton Reviewed by: gnn Sponsored by: Solarflare Communications, Inc. Modified: stable/10/sys/dev/sfxge/common/efx_impl.h stable/10/sys/dev/sfxge/common/efx_mcdi.c stable/10/sys/dev/sfxge/common/hunt_impl.h stable/10/sys/dev/sfxge/common/hunt_mcdi.c stable/10/sys/dev/sfxge/common/siena_impl.h stable/10/sys/dev/sfxge/common/siena_mcdi.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sfxge/common/efx_impl.h ============================================================================== --- stable/10/sys/dev/sfxge/common/efx_impl.h Thu Jan 14 15:24:15 2016 (r293959) +++ stable/10/sys/dev/sfxge/common/efx_impl.h Thu Jan 14 15:25:17 2016 (r293960) @@ -463,6 +463,7 @@ typedef struct efx_mcdi_ops_s { efx_rc_t (*emco_fw_update_supported)(efx_nic_t *, boolean_t *); efx_rc_t (*emco_macaddr_change_supported)(efx_nic_t *, boolean_t *); efx_rc_t (*emco_link_control_supported)(efx_nic_t *, boolean_t *); + void (*emco_read_response)(efx_nic_t *, void *, size_t, size_t); } efx_mcdi_ops_t; typedef struct efx_mcdi_s { Modified: stable/10/sys/dev/sfxge/common/efx_mcdi.c ============================================================================== --- stable/10/sys/dev/sfxge/common/efx_mcdi.c Thu Jan 14 15:24:15 2016 (r293959) +++ stable/10/sys/dev/sfxge/common/efx_mcdi.c Thu Jan 14 15:25:17 2016 (r293960) @@ -55,6 +55,7 @@ static efx_mcdi_ops_t __efx_mcdi_siena_o /* emco_macaddr_change_supported */ siena_mcdi_link_control_supported, /* emco_link_control_supported */ + siena_mcdi_read_response, /* emco_read_response */ }; #endif /* EFSYS_OPT_SIENA */ @@ -73,6 +74,7 @@ static efx_mcdi_ops_t __efx_mcdi_hunt_op /* emco_macaddr_change_supported */ hunt_mcdi_link_control_supported, /* emco_link_control_supported */ + hunt_mcdi_read_response, /* emco_read_response */ }; #endif /* EFSYS_OPT_HUNTINGTON */ Modified: stable/10/sys/dev/sfxge/common/hunt_impl.h ============================================================================== --- stable/10/sys/dev/sfxge/common/hunt_impl.h Thu Jan 14 15:24:15 2016 (r293959) +++ stable/10/sys/dev/sfxge/common/hunt_impl.h Thu Jan 14 15:25:17 2016 (r293960) @@ -263,6 +263,13 @@ hunt_mcdi_request_copyin( __in boolean_t ev_cpl, __in boolean_t new_epoch); +extern void +hunt_mcdi_read_response( + __in efx_nic_t *enp, + __out void *bufferp, + __in size_t offset, + __in size_t length); + extern __checkReturn boolean_t hunt_mcdi_request_poll( __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:24:15 2016 (r293959) +++ stable/10/sys/dev/sfxge/common/hunt_mcdi.c Thu Jan 14 15:25:17 2016 (r293960) @@ -229,47 +229,41 @@ hunt_mcdi_request_copyout( __in efx_nic_t *enp, __in efx_mcdi_req_t *emrp) { +#if EFSYS_OPT_MCDI_LOGGING const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; - efsys_mem_t *esmp = emtp->emt_dma_mem; - unsigned int pos; - unsigned int offset; +#endif /* EFSYS_OPT_MCDI_LOGGING */ efx_dword_t hdr[2]; - efx_dword_t data; + unsigned int hdr_len; size_t bytes; if (emrp->emr_out_buf == NULL) return; /* Read the command header to detect MCDI response format */ - EFSYS_MEM_READD(esmp, 0, &hdr[0]); + 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) { - offset = 2 * sizeof (efx_dword_t); - /* * Read the actual payload length. The length given in the event * is only correct for responses with the V1 format. */ - EFSYS_MEM_READD(esmp, sizeof (efx_dword_t), &hdr[1]); + hunt_mcdi_read_response(enp, &hdr[1], hdr_len, sizeof (hdr[1])); + hdr_len += sizeof (hdr[1]); + emrp->emr_out_length_used = EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN); - } else { - offset = sizeof (efx_dword_t); } /* Copy payload out into caller supplied buffer */ bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length); - for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) { - EFSYS_MEM_READD(esmp, offset + pos, &data); - memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data, - MIN(sizeof (data), bytes - pos)); - } + hunt_mcdi_read_response(enp, emrp->emr_out_buf, hdr_len, bytes); #if EFSYS_OPT_MCDI_LOGGING if (emtp->emt_logger != NULL) { emtp->emt_logger(emtp->emt_context, EFX_LOG_MCDI_RESPONSE, - &hdr, offset, - emrp->emr_out_buf, emrp->emr_out_length_used); + &hdr, hdr_len, + emrp->emr_out_buf, bytes); } #endif /* EFSYS_OPT_MCDI_LOGGING */ } @@ -286,19 +280,39 @@ hunt_mcdi_poll_response( return (EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE) ? B_TRUE : B_FALSE); } + void +hunt_mcdi_read_response( + __in efx_nic_t *enp, + __out void *bufferp, + __in size_t offset, + __in size_t length) +{ + const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; + efsys_mem_t *esmp = emtp->emt_dma_mem; + unsigned int pos; + efx_dword_t data; + + for (pos = 0; pos < length; pos += sizeof (efx_dword_t)) { + EFSYS_MEM_READD(esmp, offset + pos, &data); + memcpy((uint8_t *)bufferp + pos, &data, + MIN(sizeof (data), length - pos)); + } +} + __checkReturn boolean_t hunt_mcdi_request_poll( __in efx_nic_t *enp) { - efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); +#if EFSYS_OPT_MCDI_LOGGING const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; - efsys_mem_t *esmp = emtp->emt_dma_mem; +#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; - unsigned int length; - size_t offset; int state; efx_rc_t rc; @@ -311,8 +325,6 @@ hunt_mcdi_request_poll( EFSYS_ASSERT(!emip->emi_ev_cpl); emrp = emip->emi_pending_req; - offset = 0; - /* Check if a response is available */ if (hunt_mcdi_poll_response(enp) == B_FALSE) { EFSYS_UNLOCK(enp->en_eslp, state); @@ -320,17 +332,19 @@ hunt_mcdi_request_poll( } /* Read the response header */ - EFSYS_MEM_READD(esmp, offset, &hdr[0]); - offset += sizeof (efx_dword_t); + 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) { - EFSYS_MEM_READD(esmp, offset, &hdr[1]); - offset += sizeof (efx_dword_t); + 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); - length = EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN); + data_len = + EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN); } else { cmd = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE); - length = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_DATALEN); + data_len = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_DATALEN); } /* Request complete */ @@ -338,7 +352,7 @@ hunt_mcdi_request_poll( seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ); /* Check for synchronous reboot */ - if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR) != 0 && length == 0) { + 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); @@ -362,34 +376,37 @@ hunt_mcdi_request_poll( } if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR)) { efx_dword_t err[2]; - int errcode; - int argnum; + 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) */ - EFSYS_MEM_READD(esmp, offset + MC_CMD_ERR_CODE_OFST, &err[0]); - errcode = EFX_DWORD_FIELD(err[0], EFX_DWORD_0); + 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); - EFSYS_MEM_READD(esmp, offset + MC_CMD_ERR_ARG_OFST, &err[1]); - argnum = EFX_DWORD_FIELD(err[1], 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, offset, - &err, sizeof (err)); + &hdr, hdr_len, + &err, err_len); } #endif /* EFSYS_OPT_MCDI_LOGGING */ - rc = efx_mcdi_request_errcode(errcode); + rc = efx_mcdi_request_errcode(err_code); if (!emrp->emr_quiet) { EFSYS_PROBE3(mcdi_err_arg, int, emrp->emr_cmd, - int, errcode, int, argnum); + int, err_code, int, err_arg); } goto fail3; } else { - emrp->emr_out_length_used = length; + emrp->emr_out_length_used = data_len; emrp->emr_rc = 0; hunt_mcdi_request_copyout(enp, emrp); } Modified: stable/10/sys/dev/sfxge/common/siena_impl.h ============================================================================== --- stable/10/sys/dev/sfxge/common/siena_impl.h Thu Jan 14 15:24:15 2016 (r293959) +++ stable/10/sys/dev/sfxge/common/siena_impl.h Thu Jan 14 15:25:17 2016 (r293960) @@ -121,6 +121,13 @@ siena_mcdi_request_copyin( __in boolean_t ev_cpl, __in boolean_t new_epoch); +extern void +siena_mcdi_read_response( + __in efx_nic_t *enp, + __out void *bufferp, + __in size_t offset, + __in size_t length); + extern __checkReturn boolean_t siena_mcdi_request_poll( __in efx_nic_t *enp); Modified: stable/10/sys/dev/sfxge/common/siena_mcdi.c ============================================================================== --- stable/10/sys/dev/sfxge/common/siena_mcdi.c Thu Jan 14 15:24:15 2016 (r293959) +++ stable/10/sys/dev/sfxge/common/siena_mcdi.c Thu Jan 14 15:25:17 2016 (r293960) @@ -123,33 +123,22 @@ siena_mcdi_request_copyout( const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; efx_dword_t hdr; #endif - efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); - unsigned int pos; - unsigned int pdur; - efx_dword_t data; - - pdur = SIENA_MCDI_PDU(emip); + size_t bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length); /* Copy payload out if caller supplied buffer */ if (emrp->emr_out_buf != NULL) { - size_t bytes = MIN(emrp->emr_out_length_used, - emrp->emr_out_length); - for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) { - EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, - pdur + 1 + (pos >> 2), &data, B_FALSE); - memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data, - MIN(sizeof (data), bytes - pos)); - } + siena_mcdi_read_response(enp, emrp->emr_out_buf, + sizeof (efx_dword_t), bytes); } #if EFSYS_OPT_MCDI_LOGGING if (emtp->emt_logger != NULL) { - EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &hdr, B_FALSE); + siena_mcdi_read_response(enp, &hdr, 0, sizeof (hdr)); emtp->emt_logger(emtp->emt_context, EFX_LOG_MCDI_RESPONSE, &hdr, sizeof (hdr), - emrp->emr_out_buf, emrp->emr_out_length_used); + emrp->emr_out_buf, bytes); } #endif /* EFSYS_OPT_MCDI_LOGGING */ } @@ -206,6 +195,29 @@ siena_mcdi_poll_response( return (EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE) ? B_TRUE : B_FALSE); } + void +siena_mcdi_read_response( + __in efx_nic_t *enp, + __out void *bufferp, + __in size_t offset, + __in size_t length) +{ + efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); + unsigned int pdur; + unsigned int pos; + efx_dword_t data; + + EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2); + pdur = SIENA_MCDI_PDU(emip); + + for (pos = 0; pos < length; pos += sizeof (efx_dword_t)) { + EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, + pdur + ((offset + pos) >> 2), &data, B_FALSE); + memcpy((uint8_t *)bufferp + pos, &data, + MIN(sizeof (data), length - pos)); + } +} + __checkReturn boolean_t siena_mcdi_request_poll( __in efx_nic_t *enp) @@ -216,9 +228,9 @@ siena_mcdi_request_poll( efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); efx_mcdi_req_t *emrp; efx_dword_t hdr; - unsigned int pdur; + unsigned int hdr_len; + unsigned int data_len; unsigned int seq; - unsigned int length; int state; efx_rc_t rc; @@ -241,9 +253,6 @@ siena_mcdi_request_poll( } } - EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2); - pdur = SIENA_MCDI_PDU(emip); - /* Check if a response is available */ if (siena_mcdi_poll_response(enp) == B_FALSE) { EFSYS_UNLOCK(enp->en_eslp, state); @@ -251,7 +260,8 @@ siena_mcdi_request_poll( } /* Read the response header */ - EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &hdr, B_FALSE); + hdr_len = sizeof (hdr); + siena_mcdi_read_response(enp, &hdr, 0, hdr_len); /* Request complete */ emip->emi_pending_req = NULL; @@ -278,35 +288,36 @@ siena_mcdi_request_poll( goto fail3; } - length = EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN); + data_len = EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN); if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_ERROR)) { - efx_dword_t errdword; - int errcode; + efx_dword_t err; + int err_code = MC_CMD_ERR_EPROTO; + unsigned int err_len = MIN(data_len, sizeof (err)); - EFSYS_ASSERT3U(length, ==, 4); - EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, - pdur + 1 + (MC_CMD_ERR_CODE_OFST >> 2), - &errdword, B_FALSE); - errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0); + /* 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, sizeof (hdr), - &errdword, sizeof (errdword)); + &hdr, hdr_len, + &err, err_len); } #endif /* EFSYS_OPT_MCDI_LOGGING */ - rc = efx_mcdi_request_errcode(errcode); + rc = efx_mcdi_request_errcode(err_code); if (!emrp->emr_quiet) { EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd, - int, errcode); + int, err_code); } goto fail4; } else { - emrp->emr_out_length_used = length; + emrp->emr_out_length_used = data_len; emrp->emr_rc = 0; siena_mcdi_request_copyout(enp, emrp); }