ef10_mcdi.c (291928) | ef10_mcdi.c (291985) |
---|---|
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: head/sys/dev/sfxge/common/hunt_mcdi.c 291928 2015-12-07 07:22:21Z arybchik $"); | 32__FBSDID("$FreeBSD: head/sys/dev/sfxge/common/hunt_mcdi.c 291985 2015-12-08 06:25:52Z arybchik $"); |
33 34#include "efsys.h" 35#include "efx.h" 36#include "efx_impl.h" 37 38 39#if EFSYS_OPT_HUNTINGTON 40 --- 183 unchanged lines hidden (view full) --- 224 EFX_BAR_WRITED(enp, ER_DZ_MC_DB_HWRD_REG, &dword, B_FALSE); 225} 226 227 void 228hunt_mcdi_request_copyout( 229 __in efx_nic_t *enp, 230 __in efx_mcdi_req_t *emrp) 231{ | 33 34#include "efsys.h" 35#include "efx.h" 36#include "efx_impl.h" 37 38 39#if EFSYS_OPT_HUNTINGTON 40 --- 183 unchanged lines hidden (view full) --- 224 EFX_BAR_WRITED(enp, ER_DZ_MC_DB_HWRD_REG, &dword, B_FALSE); 225} 226 227 void 228hunt_mcdi_request_copyout( 229 __in efx_nic_t *enp, 230 __in efx_mcdi_req_t *emrp) 231{ |
232#if EFSYS_OPT_MCDI_LOGGING |
|
232 const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; | 233 const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; |
233 efsys_mem_t *esmp = emtp->emt_dma_mem; 234 unsigned int pos; 235 unsigned int offset; | 234#endif /* EFSYS_OPT_MCDI_LOGGING */ |
236 efx_dword_t hdr[2]; | 235 efx_dword_t hdr[2]; |
237 efx_dword_t data; | 236 unsigned int hdr_len; |
238 size_t bytes; 239 240 if (emrp->emr_out_buf == NULL) 241 return; 242 243 /* Read the command header to detect MCDI response format */ | 237 size_t bytes; 238 239 if (emrp->emr_out_buf == NULL) 240 return; 241 242 /* Read the command header to detect MCDI response format */ |
244 EFSYS_MEM_READD(esmp, 0, &hdr[0]); | 243 hdr_len = sizeof (hdr[0]); 244 hunt_mcdi_read_response(enp, &hdr[0], 0, hdr_len); |
245 if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) { | 245 if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) { |
246 offset = 2 * sizeof (efx_dword_t); 247 | |
248 /* 249 * Read the actual payload length. The length given in the event 250 * is only correct for responses with the V1 format. 251 */ | 246 /* 247 * Read the actual payload length. The length given in the event 248 * is only correct for responses with the V1 format. 249 */ |
252 EFSYS_MEM_READD(esmp, sizeof (efx_dword_t), &hdr[1]); | 250 hunt_mcdi_read_response(enp, &hdr[1], hdr_len, sizeof (hdr[1])); 251 hdr_len += sizeof (hdr[1]); 252 |
253 emrp->emr_out_length_used = EFX_DWORD_FIELD(hdr[1], 254 MC_CMD_V2_EXTN_IN_ACTUAL_LEN); | 253 emrp->emr_out_length_used = EFX_DWORD_FIELD(hdr[1], 254 MC_CMD_V2_EXTN_IN_ACTUAL_LEN); |
255 } else { 256 offset = sizeof (efx_dword_t); | |
257 } 258 259 /* Copy payload out into caller supplied buffer */ 260 bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length); | 255 } 256 257 /* Copy payload out into caller supplied buffer */ 258 bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length); |
261 for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) { 262 EFSYS_MEM_READD(esmp, offset + pos, &data); 263 memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data, 264 MIN(sizeof (data), bytes - pos)); 265 } | 259 hunt_mcdi_read_response(enp, emrp->emr_out_buf, hdr_len, bytes); |
266 267#if EFSYS_OPT_MCDI_LOGGING 268 if (emtp->emt_logger != NULL) { 269 emtp->emt_logger(emtp->emt_context, 270 EFX_LOG_MCDI_RESPONSE, | 260 261#if EFSYS_OPT_MCDI_LOGGING 262 if (emtp->emt_logger != NULL) { 263 emtp->emt_logger(emtp->emt_context, 264 EFX_LOG_MCDI_RESPONSE, |
271 &hdr, offset, 272 emrp->emr_out_buf, emrp->emr_out_length_used); | 265 &hdr, hdr_len, 266 emrp->emr_out_buf, bytes); |
273 } 274#endif /* EFSYS_OPT_MCDI_LOGGING */ 275} 276 277static __checkReturn boolean_t 278hunt_mcdi_poll_response( 279 __in efx_nic_t *enp) 280{ 281 const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; 282 efsys_mem_t *esmp = emtp->emt_dma_mem; 283 efx_dword_t hdr; 284 285 EFSYS_MEM_READD(esmp, 0, &hdr); 286 return (EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE) ? B_TRUE : B_FALSE); 287} 288 | 267 } 268#endif /* EFSYS_OPT_MCDI_LOGGING */ 269} 270 271static __checkReturn boolean_t 272hunt_mcdi_poll_response( 273 __in efx_nic_t *enp) 274{ 275 const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; 276 efsys_mem_t *esmp = emtp->emt_dma_mem; 277 efx_dword_t hdr; 278 279 EFSYS_MEM_READD(esmp, 0, &hdr); 280 return (EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE) ? B_TRUE : B_FALSE); 281} 282 |
283 void 284hunt_mcdi_read_response( 285 __in efx_nic_t *enp, 286 __out void *bufferp, 287 __in size_t offset, 288 __in size_t length) 289{ 290 const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; 291 efsys_mem_t *esmp = emtp->emt_dma_mem; 292 unsigned int pos; 293 efx_dword_t data; 294 295 for (pos = 0; pos < length; pos += sizeof (efx_dword_t)) { 296 EFSYS_MEM_READD(esmp, offset + pos, &data); 297 memcpy((uint8_t *)bufferp + pos, &data, 298 MIN(sizeof (data), length - pos)); 299 } 300} 301 |
|
289 __checkReturn boolean_t 290hunt_mcdi_request_poll( 291 __in efx_nic_t *enp) 292{ | 302 __checkReturn boolean_t 303hunt_mcdi_request_poll( 304 __in efx_nic_t *enp) 305{ |
293 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); | 306#if EFSYS_OPT_MCDI_LOGGING |
294 const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; | 307 const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp; |
295 efsys_mem_t *esmp = emtp->emt_dma_mem; | 308#endif /* EFSYS_OPT_MCDI_LOGGING */ 309 efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip); |
296 efx_mcdi_req_t *emrp; 297 efx_dword_t hdr[2]; | 310 efx_mcdi_req_t *emrp; 311 efx_dword_t hdr[2]; |
312 unsigned int hdr_len; 313 unsigned int data_len; |
|
298 unsigned int seq; 299 unsigned int cmd; | 314 unsigned int seq; 315 unsigned int cmd; |
300 unsigned int length; 301 size_t offset; | |
302 int state; 303 efx_rc_t rc; 304 305 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON); 306 307 /* Serialise against post-watchdog efx_mcdi_ev* */ 308 EFSYS_LOCK(enp->en_eslp, state); 309 310 EFSYS_ASSERT(emip->emi_pending_req != NULL); 311 EFSYS_ASSERT(!emip->emi_ev_cpl); 312 emrp = emip->emi_pending_req; 313 | 316 int state; 317 efx_rc_t rc; 318 319 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON); 320 321 /* Serialise against post-watchdog efx_mcdi_ev* */ 322 EFSYS_LOCK(enp->en_eslp, state); 323 324 EFSYS_ASSERT(emip->emi_pending_req != NULL); 325 EFSYS_ASSERT(!emip->emi_ev_cpl); 326 emrp = emip->emi_pending_req; 327 |
314 offset = 0; 315 | |
316 /* Check if a response is available */ 317 if (hunt_mcdi_poll_response(enp) == B_FALSE) { 318 EFSYS_UNLOCK(enp->en_eslp, state); 319 return (B_FALSE); 320 } 321 322 /* Read the response header */ | 328 /* Check if a response is available */ 329 if (hunt_mcdi_poll_response(enp) == B_FALSE) { 330 EFSYS_UNLOCK(enp->en_eslp, state); 331 return (B_FALSE); 332 } 333 334 /* Read the response header */ |
323 EFSYS_MEM_READD(esmp, offset, &hdr[0]); 324 offset += sizeof (efx_dword_t); | 335 hdr_len = sizeof (hdr[0]); 336 hunt_mcdi_read_response(enp, &hdr[0], 0, hdr_len); 337 |
325 if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) { | 338 if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) { |
326 EFSYS_MEM_READD(esmp, offset, &hdr[1]); 327 offset += sizeof (efx_dword_t); | 339 hunt_mcdi_read_response(enp, &hdr[1], hdr_len, sizeof (hdr[1])); 340 hdr_len += sizeof (hdr[1]); |
328 329 cmd = EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_EXTENDED_CMD); | 341 342 cmd = EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_EXTENDED_CMD); |
330 length = EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN); | 343 data_len = 344 EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN); |
331 } else { 332 cmd = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE); | 345 } else { 346 cmd = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE); |
333 length = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_DATALEN); | 347 data_len = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_DATALEN); |
334 } 335 336 /* Request complete */ 337 emip->emi_pending_req = NULL; 338 seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ); 339 340 /* Check for synchronous reboot */ | 348 } 349 350 /* Request complete */ 351 emip->emi_pending_req = NULL; 352 seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ); 353 354 /* Check for synchronous reboot */ |
341 if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR) != 0 && length == 0) { | 355 if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR) != 0 && data_len == 0) { |
342 /* The MC has rebooted since the request was sent. */ 343 EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US); 344 hunt_mcdi_poll_reboot(enp); 345 346 EFSYS_UNLOCK(enp->en_eslp, state); 347 rc = EIO; 348 goto fail1; 349 } --- 7 unchanged lines hidden (view full) --- 357 if (cmd != emrp->emr_cmd || 358 EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_SEQ) != seq) { 359 /* Response is for a different request */ 360 rc = EIO; 361 goto fail2; 362 } 363 if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR)) { 364 efx_dword_t err[2]; | 356 /* The MC has rebooted since the request was sent. */ 357 EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US); 358 hunt_mcdi_poll_reboot(enp); 359 360 EFSYS_UNLOCK(enp->en_eslp, state); 361 rc = EIO; 362 goto fail1; 363 } --- 7 unchanged lines hidden (view full) --- 371 if (cmd != emrp->emr_cmd || 372 EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_SEQ) != seq) { 373 /* Response is for a different request */ 374 rc = EIO; 375 goto fail2; 376 } 377 if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR)) { 378 efx_dword_t err[2]; |
365 int errcode; 366 int argnum; | 379 unsigned int err_len = MIN(data_len, sizeof (err)); 380 int err_code = MC_CMD_ERR_EPROTO; 381 int err_arg = 0; |
367 368 /* Read error code (and arg num for MCDI v2 commands) */ | 382 383 /* Read error code (and arg num for MCDI v2 commands) */ |
369 EFSYS_MEM_READD(esmp, offset + MC_CMD_ERR_CODE_OFST, &err[0]); 370 errcode = EFX_DWORD_FIELD(err[0], EFX_DWORD_0); | 384 hunt_mcdi_read_response(enp, &err[0], hdr_len, err_len); |
371 | 385 |
372 EFSYS_MEM_READD(esmp, offset + MC_CMD_ERR_ARG_OFST, &err[1]); 373 argnum = EFX_DWORD_FIELD(err[1], EFX_DWORD_0); | 386 if (err_len >= MC_CMD_ERR_CODE_OFST + sizeof (efx_dword_t)) 387 err_code = EFX_DWORD_FIELD(err[0], EFX_DWORD_0); |
374 | 388 |
389 if (err_len >= MC_CMD_ERR_ARG_OFST + sizeof (efx_dword_t)) 390 err_arg = EFX_DWORD_FIELD(err[1], EFX_DWORD_0); 391 |
|
375#if EFSYS_OPT_MCDI_LOGGING 376 if (emtp->emt_logger != NULL) { 377 emtp->emt_logger(emtp->emt_context, 378 EFX_LOG_MCDI_RESPONSE, | 392#if EFSYS_OPT_MCDI_LOGGING 393 if (emtp->emt_logger != NULL) { 394 emtp->emt_logger(emtp->emt_context, 395 EFX_LOG_MCDI_RESPONSE, |
379 &hdr, offset, 380 &err, sizeof (err)); | 396 &hdr, hdr_len, 397 &err, err_len); |
381 } 382#endif /* EFSYS_OPT_MCDI_LOGGING */ 383 | 398 } 399#endif /* EFSYS_OPT_MCDI_LOGGING */ 400 |
384 rc = efx_mcdi_request_errcode(errcode); | 401 rc = efx_mcdi_request_errcode(err_code); |
385 if (!emrp->emr_quiet) { 386 EFSYS_PROBE3(mcdi_err_arg, int, emrp->emr_cmd, | 402 if (!emrp->emr_quiet) { 403 EFSYS_PROBE3(mcdi_err_arg, int, emrp->emr_cmd, |
387 int, errcode, int, argnum); | 404 int, err_code, int, err_arg); |
388 } 389 goto fail3; 390 391 } else { | 405 } 406 goto fail3; 407 408 } else { |
392 emrp->emr_out_length_used = length; | 409 emrp->emr_out_length_used = data_len; |
393 emrp->emr_rc = 0; 394 hunt_mcdi_request_copyout(enp, emrp); 395 } 396 397 goto out; 398 399fail3: 400 if (!emrp->emr_quiet) --- 138 unchanged lines hidden --- | 410 emrp->emr_rc = 0; 411 hunt_mcdi_request_copyout(enp, emrp); 412 } 413 414 goto out; 415 416fail3: 417 if (!emrp->emr_quiet) --- 138 unchanged lines hidden --- |