siena_mcdi.c (293937) | siena_mcdi.c (293939) |
---|---|
1/*- 2 * Copyright (c) 2012-2015 Solarflare Communications Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, --- 15 unchanged lines hidden (view full) --- 24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * The views and conclusions contained in the software and documentation are 27 * those of the authors and should not be interpreted as representing official 28 * policies, either expressed or implied, of the FreeBSD Project. 29 */ 30 31#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2012-2015 Solarflare Communications Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, --- 15 unchanged lines hidden (view full) --- 24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * The views and conclusions contained in the software and documentation are 27 * those of the authors and should not be interpreted as representing official 28 * policies, either expressed or implied, of the FreeBSD Project. 29 */ 30 31#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: stable/10/sys/dev/sfxge/common/siena_mcdi.c 293937 2016-01-14 14:25:49Z arybchik $"); | 32__FBSDID("$FreeBSD: stable/10/sys/dev/sfxge/common/siena_mcdi.c 293939 2016-01-14 14:28:30Z arybchik $"); |
33 34#include "efsys.h" 35#include "efx.h" 36#include "efx_impl.h" 37 38#if EFSYS_OPT_SIENA && EFSYS_OPT_MCDI 39 40#define SIENA_MCDI_PDU(_emip) \ --- 15 unchanged lines hidden (view full) --- 56 void 57siena_mcdi_request_copyin( 58 __in efx_nic_t *enp, 59 __in efx_mcdi_req_t *emrp, 60 __in unsigned int seq, 61 __in boolean_t ev_cpl, 62 __in boolean_t new_epoch) 63{ | 33 34#include "efsys.h" 35#include "efx.h" 36#include "efx_impl.h" 37 38#if EFSYS_OPT_SIENA && EFSYS_OPT_MCDI 39 40#define SIENA_MCDI_PDU(_emip) \ --- 15 unchanged lines hidden (view full) --- 56 void 57siena_mcdi_request_copyin( 58 __in efx_nic_t *enp, 59 __in efx_mcdi_req_t *emrp, 60 __in unsigned int seq, 61 __in boolean_t ev_cpl, 62 __in boolean_t new_epoch) 63{ |
64#if EFSYS_OPT_MCDI_LOGGING 65 const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; 66#endif |
|
64 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); | 67 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); |
68 efx_dword_t hdr; |
|
65 efx_dword_t dword; 66 unsigned int xflags; 67 unsigned int pdur; 68 unsigned int dbr; 69 unsigned int pos; 70 71 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 72 _NOTE(ARGUNUSED(new_epoch)) 73 74 EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2); 75 pdur = SIENA_MCDI_PDU(emip); 76 dbr = SIENA_MCDI_DOORBELL(emip); 77 78 xflags = 0; 79 if (ev_cpl) 80 xflags |= MCDI_HEADER_XFLAGS_EVREQ; 81 82 /* Construct the header in shared memory */ | 69 efx_dword_t dword; 70 unsigned int xflags; 71 unsigned int pdur; 72 unsigned int dbr; 73 unsigned int pos; 74 75 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 76 _NOTE(ARGUNUSED(new_epoch)) 77 78 EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2); 79 pdur = SIENA_MCDI_PDU(emip); 80 dbr = SIENA_MCDI_DOORBELL(emip); 81 82 xflags = 0; 83 if (ev_cpl) 84 xflags |= MCDI_HEADER_XFLAGS_EVREQ; 85 86 /* Construct the header in shared memory */ |
83 EFX_POPULATE_DWORD_6(dword, | 87 EFX_POPULATE_DWORD_6(hdr, |
84 MCDI_HEADER_CODE, emrp->emr_cmd, 85 MCDI_HEADER_RESYNC, 1, 86 MCDI_HEADER_DATALEN, emrp->emr_in_length, 87 MCDI_HEADER_SEQ, seq, 88 MCDI_HEADER_RESPONSE, 0, 89 MCDI_HEADER_XFLAGS, xflags); | 88 MCDI_HEADER_CODE, emrp->emr_cmd, 89 MCDI_HEADER_RESYNC, 1, 90 MCDI_HEADER_DATALEN, emrp->emr_in_length, 91 MCDI_HEADER_SEQ, seq, 92 MCDI_HEADER_RESPONSE, 0, 93 MCDI_HEADER_XFLAGS, xflags); |
90 EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_TRUE); | 94 EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &hdr, B_TRUE); |
91 | 95 |
96#if EFSYS_OPT_MCDI_LOGGING 97 if (emtp->emt_logger != NULL) { 98 emtp->emt_logger(emtp->emt_context, EFX_LOG_MCDI_REQUEST, 99 &hdr, sizeof (hdr), 100 emrp->emr_in_buf, emrp->emr_in_length); 101 } 102#endif /* EFSYS_OPT_MCDI_LOGGING */ 103 104 /* Construct the payload */ |
|
92 for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) { 93 memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos), 94 MIN(sizeof (dword), emrp->emr_in_length - pos)); 95 EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, 96 pdur + 1 + (pos >> 2), &dword, B_FALSE); 97 } 98 99 /* Ring the doorbell */ 100 EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 0xd004be11); 101 EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, dbr, &dword, B_FALSE); 102} 103 104 void 105siena_mcdi_request_copyout( 106 __in efx_nic_t *enp, 107 __in efx_mcdi_req_t *emrp) 108{ | 105 for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) { 106 memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos), 107 MIN(sizeof (dword), emrp->emr_in_length - pos)); 108 EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, 109 pdur + 1 + (pos >> 2), &dword, B_FALSE); 110 } 111 112 /* Ring the doorbell */ 113 EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 0xd004be11); 114 EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, dbr, &dword, B_FALSE); 115} 116 117 void 118siena_mcdi_request_copyout( 119 __in efx_nic_t *enp, 120 __in efx_mcdi_req_t *emrp) 121{ |
122#if EFSYS_OPT_MCDI_LOGGING 123 const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; 124 efx_dword_t hdr; 125#endif |
|
109 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); 110 unsigned int pos; 111 unsigned int pdur; 112 efx_dword_t data; 113 114 pdur = SIENA_MCDI_PDU(emip); 115 116 /* Copy payload out if caller supplied buffer */ 117 if (emrp->emr_out_buf != NULL) { 118 size_t bytes = MIN(emrp->emr_out_length_used, 119 emrp->emr_out_length); 120 for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) { 121 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, 122 pdur + 1 + (pos >> 2), &data, B_FALSE); 123 memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data, 124 MIN(sizeof (data), bytes - pos)); 125 } 126 } | 126 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); 127 unsigned int pos; 128 unsigned int pdur; 129 efx_dword_t data; 130 131 pdur = SIENA_MCDI_PDU(emip); 132 133 /* Copy payload out if caller supplied buffer */ 134 if (emrp->emr_out_buf != NULL) { 135 size_t bytes = MIN(emrp->emr_out_length_used, 136 emrp->emr_out_length); 137 for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) { 138 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, 139 pdur + 1 + (pos >> 2), &data, B_FALSE); 140 memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data, 141 MIN(sizeof (data), bytes - pos)); 142 } 143 } |
144 145#if EFSYS_OPT_MCDI_LOGGING 146 if (emtp->emt_logger != NULL) { 147 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &hdr, B_FALSE); 148 149 emtp->emt_logger(emtp->emt_context, 150 EFX_LOG_MCDI_RESPONSE, 151 &hdr, sizeof (hdr), 152 emrp->emr_out_buf, emrp->emr_out_length_used); 153 } 154#endif /* EFSYS_OPT_MCDI_LOGGING */ |
|
127} 128 129 efx_rc_t 130siena_mcdi_poll_reboot( 131 __in efx_nic_t *enp) 132{ 133#ifndef EFX_GRACEFUL_MC_REBOOT 134 /* --- 27 unchanged lines hidden (view full) --- 162 return (EIO); 163#endif 164} 165 166 __checkReturn boolean_t 167siena_mcdi_request_poll( 168 __in efx_nic_t *enp) 169{ | 155} 156 157 efx_rc_t 158siena_mcdi_poll_reboot( 159 __in efx_nic_t *enp) 160{ 161#ifndef EFX_GRACEFUL_MC_REBOOT 162 /* --- 27 unchanged lines hidden (view full) --- 190 return (EIO); 191#endif 192} 193 194 __checkReturn boolean_t 195siena_mcdi_request_poll( 196 __in efx_nic_t *enp) 197{ |
198#if EFSYS_OPT_MCDI_LOGGING 199 const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; 200#endif |
|
170 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); 171 efx_mcdi_req_t *emrp; | 201 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); 202 efx_mcdi_req_t *emrp; |
172 efx_dword_t dword; | 203 efx_dword_t hdr; |
173 unsigned int pdur; 174 unsigned int seq; 175 unsigned int length; 176 int state; 177 efx_rc_t rc; 178 179 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 180 --- 13 unchanged lines hidden (view full) --- 194 goto fail1; 195 } 196 } 197 198 EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2); 199 pdur = SIENA_MCDI_PDU(emip); 200 201 /* Read the command header */ | 204 unsigned int pdur; 205 unsigned int seq; 206 unsigned int length; 207 int state; 208 efx_rc_t rc; 209 210 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 211 --- 13 unchanged lines hidden (view full) --- 225 goto fail1; 226 } 227 } 228 229 EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2); 230 pdur = SIENA_MCDI_PDU(emip); 231 232 /* Read the command header */ |
202 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_FALSE); 203 if (EFX_DWORD_FIELD(dword, MCDI_HEADER_RESPONSE) == 0) { | 233 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &hdr, B_FALSE); 234 if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE) == 0) { |
204 EFSYS_UNLOCK(enp->en_eslp, state); 205 return (B_FALSE); 206 } 207 208 /* Request complete */ 209 emip->emi_pending_req = NULL; 210 seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ); 211 212 /* Check for synchronous reboot */ | 235 EFSYS_UNLOCK(enp->en_eslp, state); 236 return (B_FALSE); 237 } 238 239 /* Request complete */ 240 emip->emi_pending_req = NULL; 241 seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ); 242 243 /* Check for synchronous reboot */ |
213 if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR) != 0 && 214 EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN) == 0) { | 244 if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_ERROR) != 0 && 245 EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN) == 0) { |
215 /* Consume status word */ 216 EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US); 217 siena_mcdi_poll_reboot(enp); 218 EFSYS_UNLOCK(enp->en_eslp, state); 219 rc = EIO; 220 goto fail2; 221 } 222 223 EFSYS_UNLOCK(enp->en_eslp, state); 224 225 /* Check that the returned data is consistent */ | 246 /* Consume status word */ 247 EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US); 248 siena_mcdi_poll_reboot(enp); 249 EFSYS_UNLOCK(enp->en_eslp, state); 250 rc = EIO; 251 goto fail2; 252 } 253 254 EFSYS_UNLOCK(enp->en_eslp, state); 255 256 /* Check that the returned data is consistent */ |
226 if (EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE) != emrp->emr_cmd || 227 EFX_DWORD_FIELD(dword, MCDI_HEADER_SEQ) != seq) { | 257 if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_CODE) != emrp->emr_cmd || 258 EFX_DWORD_FIELD(hdr, MCDI_HEADER_SEQ) != seq) { |
228 /* Response is for a different request */ 229 rc = EIO; 230 goto fail3; 231 } 232 | 259 /* Response is for a different request */ 260 rc = EIO; 261 goto fail3; 262 } 263 |
233 length = EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN); 234 if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR)) { | 264 length = EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN); 265 if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_ERROR)) { |
235 efx_dword_t errdword; 236 int errcode; 237 238 EFSYS_ASSERT3U(length, ==, 4); 239 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, 240 pdur + 1 + (MC_CMD_ERR_CODE_OFST >> 2), 241 &errdword, B_FALSE); 242 errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0); | 266 efx_dword_t errdword; 267 int errcode; 268 269 EFSYS_ASSERT3U(length, ==, 4); 270 EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, 271 pdur + 1 + (MC_CMD_ERR_CODE_OFST >> 2), 272 &errdword, B_FALSE); 273 errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0); |
274 275#if EFSYS_OPT_MCDI_LOGGING 276 if (emtp->emt_logger != NULL) { 277 emtp->emt_logger(emtp->emt_context, 278 EFX_LOG_MCDI_RESPONSE, 279 &hdr, sizeof (hdr), 280 &errdword, sizeof (errdword)); 281 } 282#endif /* EFSYS_OPT_MCDI_LOGGING */ 283 |
|
243 rc = efx_mcdi_request_errcode(errcode); 244 if (!emrp->emr_quiet) { 245 EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd, 246 int, errcode); 247 } 248 goto fail4; 249 250 } else { --- 116 unchanged lines hidden --- | 284 rc = efx_mcdi_request_errcode(errcode); 285 if (!emrp->emr_quiet) { 286 EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd, 287 int, errcode); 288 } 289 goto fail4; 290 291 } else { --- 116 unchanged lines hidden --- |