Lines Matching refs:mcdi

62 	struct efx_mcdi_iface *mcdi;  in efx_mcdi_init()  local
66 efx->mcdi = kzalloc(sizeof(*efx->mcdi), GFP_KERNEL); in efx_mcdi_init()
67 if (!efx->mcdi) in efx_mcdi_init()
70 mcdi = efx_mcdi(efx); in efx_mcdi_init()
71 mcdi->efx = efx; in efx_mcdi_init()
74 mcdi->logging_buffer = (char *)__get_free_page(GFP_KERNEL); in efx_mcdi_init()
75 if (!mcdi->logging_buffer) in efx_mcdi_init()
77 mcdi->logging_enabled = mcdi_logging_default; in efx_mcdi_init()
79 init_waitqueue_head(&mcdi->wq); in efx_mcdi_init()
80 init_waitqueue_head(&mcdi->proxy_rx_wq); in efx_mcdi_init()
81 spin_lock_init(&mcdi->iface_lock); in efx_mcdi_init()
82 mcdi->state = MCDI_STATE_QUIESCENT; in efx_mcdi_init()
83 mcdi->mode = MCDI_MODE_POLL; in efx_mcdi_init()
84 spin_lock_init(&mcdi->async_lock); in efx_mcdi_init()
85 INIT_LIST_HEAD(&mcdi->async_list); in efx_mcdi_init()
86 timer_setup(&mcdi->async_timer, efx_mcdi_timeout_async, 0); in efx_mcdi_init()
89 mcdi->new_epoch = true; in efx_mcdi_init()
108 if (efx->mcdi->fn_flags & in efx_mcdi_init()
115 free_page((unsigned long)mcdi->logging_buffer); in efx_mcdi_init()
118 kfree(efx->mcdi); in efx_mcdi_init()
119 efx->mcdi = NULL; in efx_mcdi_init()
126 if (!efx->mcdi) in efx_mcdi_detach()
129 BUG_ON(efx->mcdi->iface.state != MCDI_STATE_QUIESCENT); in efx_mcdi_detach()
137 if (!efx->mcdi) in efx_mcdi_fini()
141 free_page((unsigned long)efx->mcdi->iface.logging_buffer); in efx_mcdi_fini()
144 kfree(efx->mcdi); in efx_mcdi_fini()
150 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_send_request() local
152 char *buf = mcdi->logging_buffer; /* page-sized */ in efx_mcdi_send_request()
158 BUG_ON(mcdi->state == MCDI_STATE_QUIESCENT); in efx_mcdi_send_request()
161 spin_lock_bh(&mcdi->iface_lock); in efx_mcdi_send_request()
162 ++mcdi->seqno; in efx_mcdi_send_request()
163 seqno = mcdi->seqno & SEQ_MASK; in efx_mcdi_send_request()
164 spin_unlock_bh(&mcdi->iface_lock); in efx_mcdi_send_request()
167 if (mcdi->mode == MCDI_MODE_EVENTS) in efx_mcdi_send_request()
179 MCDI_HEADER_NOT_EPOCH, !mcdi->new_epoch); in efx_mcdi_send_request()
191 MCDI_HEADER_NOT_EPOCH, !mcdi->new_epoch); in efx_mcdi_send_request()
199 if (mcdi->logging_enabled && !WARN_ON_ONCE(!buf)) { in efx_mcdi_send_request()
227 mcdi->new_epoch = false; in efx_mcdi_send_request()
264 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_read_response_header() local
267 char *buf = mcdi->logging_buffer; /* page-sized */ in efx_mcdi_read_response_header()
277 mcdi->resp_hdr_len = 4; in efx_mcdi_read_response_header()
278 mcdi->resp_data_len = EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN); in efx_mcdi_read_response_header()
281 mcdi->resp_hdr_len = 8; in efx_mcdi_read_response_header()
282 mcdi->resp_data_len = in efx_mcdi_read_response_header()
287 if (mcdi->logging_enabled && !WARN_ON_ONCE(!buf)) { in efx_mcdi_read_response_header()
292 WARN_ON_ONCE(mcdi->resp_hdr_len % 4); in efx_mcdi_read_response_header()
293 hdr_len = mcdi->resp_hdr_len / 4; in efx_mcdi_read_response_header()
297 data_len = DIV_ROUND_UP(mcdi->resp_data_len, 4); in efx_mcdi_read_response_header()
310 mcdi->resp_hdr_len + (i * 4), 4); in efx_mcdi_read_response_header()
319 mcdi->resprc_raw = 0; in efx_mcdi_read_response_header()
320 if (error && mcdi->resp_data_len == 0) { in efx_mcdi_read_response_header()
322 mcdi->resprc = -EIO; in efx_mcdi_read_response_header()
323 } else if ((respseq ^ mcdi->seqno) & SEQ_MASK) { in efx_mcdi_read_response_header()
326 respseq, mcdi->seqno); in efx_mcdi_read_response_header()
327 mcdi->resprc = -EIO; in efx_mcdi_read_response_header()
329 efx->type->mcdi_read_response(efx, &hdr, mcdi->resp_hdr_len, 4); in efx_mcdi_read_response_header()
330 mcdi->resprc_raw = EFX_DWORD_FIELD(hdr, EFX_DWORD_0); in efx_mcdi_read_response_header()
331 mcdi->resprc = efx_mcdi_errno(mcdi->resprc_raw); in efx_mcdi_read_response_header()
333 mcdi->resprc = 0; in efx_mcdi_read_response_header()
339 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_poll_once() local
345 spin_lock_bh(&mcdi->iface_lock); in efx_mcdi_poll_once()
347 spin_unlock_bh(&mcdi->iface_lock); in efx_mcdi_poll_once()
354 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_poll() local
362 spin_lock_bh(&mcdi->iface_lock); in efx_mcdi_poll()
363 mcdi->resprc = rc; in efx_mcdi_poll()
364 mcdi->resp_hdr_len = 0; in efx_mcdi_poll()
365 mcdi->resp_data_len = 0; in efx_mcdi_poll()
366 spin_unlock_bh(&mcdi->iface_lock); in efx_mcdi_poll()
403 if (!efx->mcdi) in efx_mcdi_poll_reboot()
409 static bool efx_mcdi_acquire_async(struct efx_mcdi_iface *mcdi) in efx_mcdi_acquire_async() argument
411 return cmpxchg(&mcdi->state, in efx_mcdi_acquire_async()
416 static void efx_mcdi_acquire_sync(struct efx_mcdi_iface *mcdi) in efx_mcdi_acquire_sync() argument
421 wait_event(mcdi->wq, in efx_mcdi_acquire_sync()
422 cmpxchg(&mcdi->state, in efx_mcdi_acquire_sync()
429 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_await_completion() local
431 if (wait_event_timeout(mcdi->wq, mcdi->state == MCDI_STATE_COMPLETED, in efx_mcdi_await_completion()
443 if (mcdi->mode == MCDI_MODE_POLL) in efx_mcdi_await_completion()
452 static bool efx_mcdi_complete_sync(struct efx_mcdi_iface *mcdi) in efx_mcdi_complete_sync() argument
454 if (cmpxchg(&mcdi->state, in efx_mcdi_complete_sync()
457 wake_up(&mcdi->wq); in efx_mcdi_complete_sync()
464 static void efx_mcdi_release(struct efx_mcdi_iface *mcdi) in efx_mcdi_release() argument
466 if (mcdi->mode == MCDI_MODE_EVENTS) { in efx_mcdi_release()
468 struct efx_nic *efx = mcdi->efx; in efx_mcdi_release()
471 spin_lock_bh(&mcdi->async_lock); in efx_mcdi_release()
473 &mcdi->async_list, struct efx_mcdi_async_param, list); in efx_mcdi_release()
475 mcdi->state = MCDI_STATE_RUNNING_ASYNC; in efx_mcdi_release()
479 mod_timer(&mcdi->async_timer, in efx_mcdi_release()
482 spin_unlock_bh(&mcdi->async_lock); in efx_mcdi_release()
488 mcdi->state = MCDI_STATE_QUIESCENT; in efx_mcdi_release()
489 wake_up(&mcdi->wq); in efx_mcdi_release()
497 static bool efx_mcdi_complete_async(struct efx_mcdi_iface *mcdi, bool timeout) in efx_mcdi_complete_async() argument
499 struct efx_nic *efx = mcdi->efx; in efx_mcdi_complete_async()
506 if (cmpxchg(&mcdi->state, in efx_mcdi_complete_async()
511 spin_lock(&mcdi->iface_lock); in efx_mcdi_complete_async()
516 ++mcdi->seqno; in efx_mcdi_complete_async()
517 ++mcdi->credits; in efx_mcdi_complete_async()
522 rc = mcdi->resprc; in efx_mcdi_complete_async()
523 hdr_len = mcdi->resp_hdr_len; in efx_mcdi_complete_async()
524 data_len = mcdi->resp_data_len; in efx_mcdi_complete_async()
526 spin_unlock(&mcdi->iface_lock); in efx_mcdi_complete_async()
533 del_timer_sync(&mcdi->async_timer); in efx_mcdi_complete_async()
535 spin_lock(&mcdi->async_lock); in efx_mcdi_complete_async()
536 async = list_first_entry(&mcdi->async_list, in efx_mcdi_complete_async()
539 spin_unlock(&mcdi->async_lock); in efx_mcdi_complete_async()
557 efx_mcdi_release(mcdi); in efx_mcdi_complete_async()
565 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_ev_cpl() local
568 spin_lock(&mcdi->iface_lock); in efx_mcdi_ev_cpl()
570 if ((seqno ^ mcdi->seqno) & SEQ_MASK) { in efx_mcdi_ev_cpl()
571 if (mcdi->credits) in efx_mcdi_ev_cpl()
573 --mcdi->credits; in efx_mcdi_ev_cpl()
577 "seq 0x%x\n", seqno, mcdi->seqno); in efx_mcdi_ev_cpl()
583 mcdi->resprc = efx_mcdi_errno(mcdi_err); in efx_mcdi_ev_cpl()
584 mcdi->resp_hdr_len = 4; in efx_mcdi_ev_cpl()
585 mcdi->resp_data_len = datalen; in efx_mcdi_ev_cpl()
591 spin_unlock(&mcdi->iface_lock); in efx_mcdi_ev_cpl()
594 if (!efx_mcdi_complete_async(mcdi, false)) in efx_mcdi_ev_cpl()
595 (void) efx_mcdi_complete_sync(mcdi); in efx_mcdi_ev_cpl()
608 struct efx_mcdi_iface *mcdi = from_timer(mcdi, t, async_timer); in efx_mcdi_timeout_async() local
610 efx_mcdi_complete_async(mcdi, true); in efx_mcdi_timeout_async()
654 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in _efx_mcdi_rpc_finish() local
658 if (mcdi->mode == MCDI_MODE_POLL) in _efx_mcdi_rpc_finish()
666 cmd, (int)inlen, mcdi->mode); in _efx_mcdi_rpc_finish()
668 if (mcdi->mode == MCDI_MODE_EVENTS && efx_mcdi_poll_once(efx)) { in _efx_mcdi_rpc_finish()
680 spin_lock_bh(&mcdi->iface_lock); in _efx_mcdi_rpc_finish()
681 ++mcdi->seqno; in _efx_mcdi_rpc_finish()
682 ++mcdi->credits; in _efx_mcdi_rpc_finish()
683 spin_unlock_bh(&mcdi->iface_lock); in _efx_mcdi_rpc_finish()
699 spin_lock_bh(&mcdi->iface_lock); in _efx_mcdi_rpc_finish()
700 rc = mcdi->resprc; in _efx_mcdi_rpc_finish()
702 *raw_rc = mcdi->resprc_raw; in _efx_mcdi_rpc_finish()
703 hdr_len = mcdi->resp_hdr_len; in _efx_mcdi_rpc_finish()
704 data_len = mcdi->resp_data_len; in _efx_mcdi_rpc_finish()
706 spin_unlock_bh(&mcdi->iface_lock); in _efx_mcdi_rpc_finish()
729 mcdi->proxy_rx_status = 0; in _efx_mcdi_rpc_finish()
730 mcdi->proxy_rx_handle = 0; in _efx_mcdi_rpc_finish()
731 mcdi->state = MCDI_STATE_PROXY_WAIT; in _efx_mcdi_rpc_finish()
740 mcdi->new_epoch = true; in _efx_mcdi_rpc_finish()
745 efx_mcdi_release(mcdi); in _efx_mcdi_rpc_finish()
749 static void efx_mcdi_proxy_abort(struct efx_mcdi_iface *mcdi) in efx_mcdi_proxy_abort() argument
751 if (mcdi->state == MCDI_STATE_PROXY_WAIT) { in efx_mcdi_proxy_abort()
753 mcdi->proxy_rx_status = -EINTR; in efx_mcdi_proxy_abort()
754 wake_up(&mcdi->proxy_rx_wq); in efx_mcdi_proxy_abort()
761 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_ev_proxy_response() local
763 WARN_ON(mcdi->state != MCDI_STATE_PROXY_WAIT); in efx_mcdi_ev_proxy_response()
765 mcdi->proxy_rx_status = efx_mcdi_errno(status); in efx_mcdi_ev_proxy_response()
770 mcdi->proxy_rx_handle = handle; in efx_mcdi_ev_proxy_response()
771 wake_up(&mcdi->proxy_rx_wq); in efx_mcdi_ev_proxy_response()
776 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_proxy_wait() local
780 rc = wait_event_timeout(mcdi->proxy_rx_wq, in efx_mcdi_proxy_wait()
781 mcdi->proxy_rx_handle != 0 || in efx_mcdi_proxy_wait()
782 mcdi->proxy_rx_status == -EINTR, in efx_mcdi_proxy_wait()
789 } else if (mcdi->proxy_rx_handle != handle) { in efx_mcdi_proxy_wait()
792 mcdi->proxy_rx_handle, handle); in efx_mcdi_proxy_wait()
796 return mcdi->proxy_rx_status; in efx_mcdi_proxy_wait()
825 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in _efx_mcdi_rpc() local
837 mcdi->state = MCDI_STATE_RUNNING_SYNC; in _efx_mcdi_rpc()
850 efx_mcdi_release(mcdi); in _efx_mcdi_rpc()
953 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_rpc_start() local
963 if (mcdi->mode == MCDI_MODE_FAIL) in efx_mcdi_rpc_start()
966 efx_mcdi_acquire_sync(mcdi); in efx_mcdi_rpc_start()
977 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in _efx_mcdi_rpc_async() local
1001 spin_lock_bh(&mcdi->async_lock); in _efx_mcdi_rpc_async()
1003 if (mcdi->mode == MCDI_MODE_EVENTS) { in _efx_mcdi_rpc_async()
1004 list_add_tail(&async->list, &mcdi->async_list); in _efx_mcdi_rpc_async()
1009 if (mcdi->async_list.next == &async->list && in _efx_mcdi_rpc_async()
1010 efx_mcdi_acquire_async(mcdi)) { in _efx_mcdi_rpc_async()
1012 mod_timer(&mcdi->async_timer, in _efx_mcdi_rpc_async()
1020 spin_unlock_bh(&mcdi->async_lock); in _efx_mcdi_rpc_async()
1100 struct efx_mcdi_iface *mcdi; in efx_mcdi_mode_poll() local
1102 if (!efx->mcdi) in efx_mcdi_mode_poll()
1105 mcdi = efx_mcdi(efx); in efx_mcdi_mode_poll()
1110 if (mcdi->mode == MCDI_MODE_POLL || mcdi->mode == MCDI_MODE_FAIL) in efx_mcdi_mode_poll()
1121 mcdi->mode = MCDI_MODE_POLL; in efx_mcdi_mode_poll()
1123 efx_mcdi_complete_sync(mcdi); in efx_mcdi_mode_poll()
1132 struct efx_mcdi_iface *mcdi; in efx_mcdi_flush_async() local
1134 if (!efx->mcdi) in efx_mcdi_flush_async()
1137 mcdi = efx_mcdi(efx); in efx_mcdi_flush_async()
1140 BUG_ON(mcdi->mode == MCDI_MODE_EVENTS); in efx_mcdi_flush_async()
1142 del_timer_sync(&mcdi->async_timer); in efx_mcdi_flush_async()
1148 if (mcdi->state == MCDI_STATE_RUNNING_ASYNC) { in efx_mcdi_flush_async()
1150 mcdi->state = MCDI_STATE_QUIESCENT; in efx_mcdi_flush_async()
1158 list_for_each_entry_safe(async, next, &mcdi->async_list, list) { in efx_mcdi_flush_async()
1168 struct efx_mcdi_iface *mcdi; in efx_mcdi_mode_event() local
1170 if (!efx->mcdi) in efx_mcdi_mode_event()
1173 mcdi = efx_mcdi(efx); in efx_mcdi_mode_event()
1178 if (mcdi->mode == MCDI_MODE_EVENTS || mcdi->mode == MCDI_MODE_FAIL) in efx_mcdi_mode_event()
1188 efx_mcdi_acquire_sync(mcdi); in efx_mcdi_mode_event()
1189 mcdi->mode = MCDI_MODE_EVENTS; in efx_mcdi_mode_event()
1190 efx_mcdi_release(mcdi); in efx_mcdi_mode_event()
1195 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_ev_death() local
1221 spin_lock(&mcdi->iface_lock); in efx_mcdi_ev_death()
1222 efx_mcdi_proxy_abort(mcdi); in efx_mcdi_ev_death()
1224 if (efx_mcdi_complete_sync(mcdi)) { in efx_mcdi_ev_death()
1225 if (mcdi->mode == MCDI_MODE_EVENTS) { in efx_mcdi_ev_death()
1226 mcdi->resprc = rc; in efx_mcdi_ev_death()
1227 mcdi->resp_hdr_len = 0; in efx_mcdi_ev_death()
1228 mcdi->resp_data_len = 0; in efx_mcdi_ev_death()
1229 ++mcdi->credits; in efx_mcdi_ev_death()
1251 mcdi->new_epoch = true; in efx_mcdi_ev_death()
1257 spin_unlock(&mcdi->iface_lock); in efx_mcdi_ev_death()
1267 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_ev_bist() local
1269 spin_lock(&mcdi->iface_lock); in efx_mcdi_ev_bist()
1271 efx_mcdi_proxy_abort(mcdi); in efx_mcdi_ev_bist()
1273 if (efx_mcdi_complete_sync(mcdi)) { in efx_mcdi_ev_bist()
1274 if (mcdi->mode == MCDI_MODE_EVENTS) { in efx_mcdi_ev_bist()
1275 mcdi->resprc = -EIO; in efx_mcdi_ev_bist()
1276 mcdi->resp_hdr_len = 0; in efx_mcdi_ev_bist()
1277 mcdi->resp_data_len = 0; in efx_mcdi_ev_bist()
1278 ++mcdi->credits; in efx_mcdi_ev_bist()
1281 mcdi->new_epoch = true; in efx_mcdi_ev_bist()
1283 spin_unlock(&mcdi->iface_lock); in efx_mcdi_ev_bist()
1291 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_abandon() local
1293 if (xchg(&mcdi->mode, MCDI_MODE_FAIL) == MCDI_MODE_FAIL) in efx_mcdi_abandon()
1486 efx->mcdi->fn_flags = in efx_mcdi_drv_attach()
1491 efx->mcdi->fn_flags = in efx_mcdi_drv_attach()
1923 if (efx->mcdi) { in efx_mcdi_reset()
1924 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_reset() local
1925 mcdi->mode = MCDI_MODE_POLL; in efx_mcdi_reset()