25 #define MCDI_RPC_TIMEOUT 10
27 #define MCDI_PDU(efx) \
28 (efx_port_num(efx) ? MC_SMEM_P1_PDU_OFST : MC_SMEM_P0_PDU_OFST)
29 #define MCDI_DOORBELL(efx) \
30 (efx_port_num(efx) ? MC_SMEM_P1_DOORBELL_OFST : MC_SMEM_P0_DOORBELL_OFST)
31 #define MCDI_STATUS(efx) \
32 (efx_port_num(efx) ? MC_SMEM_P1_STATUS_OFST : MC_SMEM_P0_STATUS_OFST)
37 #define MCDI_STATUS_DELAY_US 100
38 #define MCDI_STATUS_DELAY_COUNT 100
39 #define MCDI_STATUS_SLEEP_MS \
40 (MCDI_STATUS_DELAY_US * MCDI_STATUS_DELAY_COUNT / 1000)
43 EFX_MASK32(EFX_WIDTH(MCDI_HEADER_SEQ))
50 return &nic_data->
mcdi;
69 static void efx_mcdi_copyin(
struct efx_nic *efx,
unsigned cmd,
88 MCDI_HEADER_RESPONSE, 0,
89 MCDI_HEADER_RESYNC, 1,
90 MCDI_HEADER_CODE, cmd,
91 MCDI_HEADER_DATALEN, inlen,
92 MCDI_HEADER_SEQ, seqno,
93 MCDI_HEADER_XFLAGS, xflags);
95 efx_writed(efx, &hdr, pdu);
97 for (i = 0; i <
inlen; i += 4)
98 _efx_writed(efx, *((
__le32 *)(inbuf + i)), pdu + 4 + i);
107 static void efx_mcdi_copyout(
struct efx_nic *efx,
u8 *outbuf,
size_t outlen)
116 for (i = 0; i <
outlen; i += 4)
117 *((
__le32 *)(outbuf + i)) = _efx_readd(efx, pdu + 4 + i);
120 static int efx_mcdi_poll(
struct efx_nic *efx)
123 unsigned int time, finish;
124 unsigned int respseq, respcmd,
error;
126 unsigned int rc, spins;
152 efx_readd(efx, ®, pdu);
170 if (error && mcdi->
resplen == 0) {
175 "MC response mismatch tx seq 0x%x rx seq 0x%x\n",
176 respseq, mcdi->
seqno);
179 efx_readd(efx, ®, pdu + 4);
181 #define TRANSLATE_ERROR(name) \
182 case MC_CMD_ERR_ ## name: \
193 #undef TRANSLATE_ERROR
220 efx_readd(efx, ®, addr);
227 efx_writed(efx, ®, addr);
246 static int efx_mcdi_await_completion(
struct efx_nic *efx)
265 return efx_mcdi_poll(efx);
294 static void efx_mcdi_ev_cpl(
struct efx_nic *efx,
unsigned int seqno,
295 unsigned int datalen,
unsigned int errno)
302 if ((seqno ^ mcdi->
seqno) & SEQ_MASK) {
308 "MC response mismatch tx seq 0x%x rx "
309 "seq 0x%x\n", seqno, mcdi->
seqno);
320 efx_mcdi_complete(mcdi);
324 const u8 *inbuf,
size_t inlen,
u8 *outbuf,
size_t outlen,
325 size_t *outlen_actual)
329 outbuf, outlen, outlen_actual);
339 efx_mcdi_acquire(mcdi);
346 efx_mcdi_copyin(efx, cmd, inbuf, inlen);
350 u8 *outbuf,
size_t outlen,
size_t *outlen_actual)
358 rc = efx_mcdi_poll(efx);
360 rc = efx_mcdi_await_completion(efx);
373 "MC command 0x%x inlen %d mode %d timed out\n",
374 cmd, (
int)inlen, mcdi->
mode);
388 efx_mcdi_copyout(efx, outbuf,
390 if (outlen_actual !=
NULL)
394 else if (rc == -
EIO || rc == -
EINTR) {
400 "MC command 0x%x inlen %d failed rc=%d\n",
401 cmd, (
int)inlen, -rc);
409 efx_mcdi_release(mcdi);
420 mcdi = efx_mcdi(efx);
434 efx_mcdi_complete(mcdi);
444 mcdi = efx_mcdi(efx);
456 efx_mcdi_acquire(mcdi);
458 efx_mcdi_release(mcdi);
461 static void efx_mcdi_ev_death(
struct efx_nic *efx,
int rc)
482 if (efx_mcdi_complete(mcdi)) {
505 static unsigned int efx_mcdi_event_link_speed[] = {
518 speed = efx_mcdi_event_link_speed[speed];
546 "MC watchdog or assertion failure at 0x%x\n", data);
547 efx_mcdi_ev_death(efx,
EINTR);
562 efx_mcdi_process_link_change(efx, event);
569 "MC Scheduler error address=0x%x\n", data);
573 efx_mcdi_ev_death(efx,
EIO);
610 outbuf,
sizeof(outbuf), &outlength);
639 driver_operating ? 1 : 0);
643 outbuf,
sizeof(outbuf), &outlen);
651 if (was_attached !=
NULL)
652 *was_attached =
MCDI_DWORD(outbuf, DRV_ATTACH_OUT_OLD_STATE);
671 outbuf,
sizeof(outbuf), &outlen);
685 if (fw_subtype_list) {
700 GET_BOARD_CFG_OUT_CAPABILITIES_PORT1);
703 GET_BOARD_CFG_OUT_CAPABILITIES_PORT0);
710 __func__, rc, (
int)outlen);
752 outbuf,
sizeof(outbuf), &outlen);
760 *nvram_types_out =
MCDI_DWORD(outbuf, NVRAM_TYPES_OUT_TYPES);
770 size_t *size_out,
size_t *erase_size_out,
781 outbuf,
sizeof(outbuf), &outlen);
789 *size_out =
MCDI_DWORD(outbuf, NVRAM_INFO_OUT_SIZE);
790 *erase_size_out =
MCDI_DWORD(outbuf, NVRAM_INFO_OUT_ERASESIZE);
791 *protected_out = !!(
MCDI_DWORD(outbuf, NVRAM_INFO_OUT_FLAGS) &
834 outbuf,
sizeof(outbuf), &outlen);
838 memcpy(buffer,
MCDI_PTR(outbuf, NVRAM_READ_OUT_READ_BUFFER), length);
855 memcpy(
MCDI_PTR(inbuf, NVRAM_WRITE_IN_WRITE_BUFFER), buffer, length);
917 static int efx_mcdi_nvram_test(
struct efx_nic *efx,
unsigned int type)
926 outbuf,
sizeof(outbuf),
NULL);
930 switch (
MCDI_DWORD(outbuf, NVRAM_TEST_OUT_RESULT)) {
950 while (nvram_types != 0) {
951 if (nvram_types & 1) {
952 rc = efx_mcdi_nvram_test(efx, type);
970 static int efx_mcdi_read_assertion(
struct efx_nic *efx)
990 outbuf,
sizeof(outbuf), &outlen);
991 }
while ((rc == -
EINTR || rc == -
EIO) && retry-- > 0);
999 flags =
MCDI_DWORD(outbuf, GET_ASSERTS_OUT_GLOBAL_FLAGS);
1004 ?
"system-level assertion"
1006 ?
"thread-level assertion"
1009 :
"unknown assertion";
1011 "MCPU %s at PC = 0x%.8x in thread 0x%.8x\n", reason,
1012 MCDI_DWORD(outbuf, GET_ASSERTS_OUT_SAVED_PC_OFFS),
1013 MCDI_DWORD(outbuf, GET_ASSERTS_OUT_THREAD_OFFS));
1017 for (index = 1; index < 32; index++) {
1026 static void efx_mcdi_exit_assertion(
struct efx_nic *efx)
1047 rc = efx_mcdi_read_assertion(efx);
1051 efx_mcdi_exit_assertion(efx);
1103 static int efx_mcdi_wol_filter_set(
struct efx_nic *efx,
u32 type,
1104 const u8 *
mac,
int *id_out)
1117 outbuf,
sizeof(outbuf), &outlen);
1126 *id_out = (
int)
MCDI_DWORD(outbuf, WOL_FILTER_SET_OUT_FILTER_ID);
1152 outbuf,
sizeof(outbuf), &outlen);
1161 *id_out = (
int)
MCDI_DWORD(outbuf, WOL_FILTER_GET_OUT_FILTER_ID);
1212 efx_rx_queue_index(rx_queue));
1218 count *
sizeof(*qid),
NULL, 0,
NULL);