Lines Matching refs:mcdi
64 struct efx_mcdi_iface *mcdi; in efx_siena_mcdi_init() local
68 efx->mcdi = kzalloc(sizeof(*efx->mcdi), GFP_KERNEL); in efx_siena_mcdi_init()
69 if (!efx->mcdi) in efx_siena_mcdi_init()
72 mcdi = efx_mcdi(efx); in efx_siena_mcdi_init()
73 mcdi->efx = efx; in efx_siena_mcdi_init()
76 mcdi->logging_buffer = (char *)__get_free_page(GFP_KERNEL); in efx_siena_mcdi_init()
77 if (!mcdi->logging_buffer) in efx_siena_mcdi_init()
79 mcdi->logging_enabled = efx_siena_mcdi_logging_default; in efx_siena_mcdi_init()
81 init_waitqueue_head(&mcdi->wq); in efx_siena_mcdi_init()
82 init_waitqueue_head(&mcdi->proxy_rx_wq); in efx_siena_mcdi_init()
83 spin_lock_init(&mcdi->iface_lock); in efx_siena_mcdi_init()
84 mcdi->state = MCDI_STATE_QUIESCENT; in efx_siena_mcdi_init()
85 mcdi->mode = MCDI_MODE_POLL; in efx_siena_mcdi_init()
86 spin_lock_init(&mcdi->async_lock); in efx_siena_mcdi_init()
87 INIT_LIST_HEAD(&mcdi->async_list); in efx_siena_mcdi_init()
88 timer_setup(&mcdi->async_timer, efx_mcdi_timeout_async, 0); in efx_siena_mcdi_init()
91 mcdi->new_epoch = true; in efx_siena_mcdi_init()
112 if (efx->mcdi->fn_flags & in efx_siena_mcdi_init()
119 free_page((unsigned long)mcdi->logging_buffer); in efx_siena_mcdi_init()
122 kfree(efx->mcdi); in efx_siena_mcdi_init()
123 efx->mcdi = NULL; in efx_siena_mcdi_init()
130 if (!efx->mcdi) in efx_siena_mcdi_detach()
133 BUG_ON(efx->mcdi->iface.state != MCDI_STATE_QUIESCENT); in efx_siena_mcdi_detach()
141 if (!efx->mcdi) in efx_siena_mcdi_fini()
145 free_page((unsigned long)efx->mcdi->iface.logging_buffer); in efx_siena_mcdi_fini()
148 kfree(efx->mcdi); in efx_siena_mcdi_fini()
154 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_send_request() local
156 char *buf = mcdi->logging_buffer; /* page-sized */ in efx_mcdi_send_request()
162 BUG_ON(mcdi->state == MCDI_STATE_QUIESCENT); in efx_mcdi_send_request()
165 spin_lock_bh(&mcdi->iface_lock); in efx_mcdi_send_request()
166 ++mcdi->seqno; in efx_mcdi_send_request()
167 seqno = mcdi->seqno & SEQ_MASK; in efx_mcdi_send_request()
168 spin_unlock_bh(&mcdi->iface_lock); in efx_mcdi_send_request()
171 if (mcdi->mode == MCDI_MODE_EVENTS) in efx_mcdi_send_request()
183 MCDI_HEADER_NOT_EPOCH, !mcdi->new_epoch); in efx_mcdi_send_request()
195 MCDI_HEADER_NOT_EPOCH, !mcdi->new_epoch); in efx_mcdi_send_request()
203 if (mcdi->logging_enabled && !WARN_ON_ONCE(!buf)) { in efx_mcdi_send_request()
231 mcdi->new_epoch = false; in efx_mcdi_send_request()
268 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_read_response_header() local
271 char *buf = mcdi->logging_buffer; /* page-sized */ in efx_mcdi_read_response_header()
281 mcdi->resp_hdr_len = 4; in efx_mcdi_read_response_header()
282 mcdi->resp_data_len = EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN); in efx_mcdi_read_response_header()
285 mcdi->resp_hdr_len = 8; in efx_mcdi_read_response_header()
286 mcdi->resp_data_len = in efx_mcdi_read_response_header()
291 if (mcdi->logging_enabled && !WARN_ON_ONCE(!buf)) { in efx_mcdi_read_response_header()
296 WARN_ON_ONCE(mcdi->resp_hdr_len % 4); in efx_mcdi_read_response_header()
297 hdr_len = mcdi->resp_hdr_len / 4; in efx_mcdi_read_response_header()
301 data_len = DIV_ROUND_UP(mcdi->resp_data_len, 4); in efx_mcdi_read_response_header()
314 mcdi->resp_hdr_len + (i * 4), 4); in efx_mcdi_read_response_header()
323 mcdi->resprc_raw = 0; in efx_mcdi_read_response_header()
324 if (error && mcdi->resp_data_len == 0) { in efx_mcdi_read_response_header()
326 mcdi->resprc = -EIO; in efx_mcdi_read_response_header()
327 } else if ((respseq ^ mcdi->seqno) & SEQ_MASK) { in efx_mcdi_read_response_header()
330 respseq, mcdi->seqno); in efx_mcdi_read_response_header()
331 mcdi->resprc = -EIO; in efx_mcdi_read_response_header()
333 efx->type->mcdi_read_response(efx, &hdr, mcdi->resp_hdr_len, 4); in efx_mcdi_read_response_header()
334 mcdi->resprc_raw = EFX_DWORD_FIELD(hdr, EFX_DWORD_0); in efx_mcdi_read_response_header()
335 mcdi->resprc = efx_mcdi_errno(mcdi->resprc_raw); in efx_mcdi_read_response_header()
337 mcdi->resprc = 0; in efx_mcdi_read_response_header()
343 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_poll_once() local
349 spin_lock_bh(&mcdi->iface_lock); in efx_mcdi_poll_once()
351 spin_unlock_bh(&mcdi->iface_lock); in efx_mcdi_poll_once()
358 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_poll() local
366 spin_lock_bh(&mcdi->iface_lock); in efx_mcdi_poll()
367 mcdi->resprc = rc; in efx_mcdi_poll()
368 mcdi->resp_hdr_len = 0; in efx_mcdi_poll()
369 mcdi->resp_data_len = 0; in efx_mcdi_poll()
370 spin_unlock_bh(&mcdi->iface_lock); in efx_mcdi_poll()
407 if (!efx->mcdi) in efx_siena_mcdi_poll_reboot()
413 static bool efx_mcdi_acquire_async(struct efx_mcdi_iface *mcdi) in efx_mcdi_acquire_async() argument
415 return cmpxchg(&mcdi->state, in efx_mcdi_acquire_async()
420 static void efx_mcdi_acquire_sync(struct efx_mcdi_iface *mcdi) in efx_mcdi_acquire_sync() argument
425 wait_event(mcdi->wq, in efx_mcdi_acquire_sync()
426 cmpxchg(&mcdi->state, in efx_mcdi_acquire_sync()
433 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_await_completion() local
435 if (wait_event_timeout(mcdi->wq, mcdi->state == MCDI_STATE_COMPLETED, in efx_mcdi_await_completion()
447 if (mcdi->mode == MCDI_MODE_POLL) in efx_mcdi_await_completion()
456 static bool efx_mcdi_complete_sync(struct efx_mcdi_iface *mcdi) in efx_mcdi_complete_sync() argument
458 if (cmpxchg(&mcdi->state, in efx_mcdi_complete_sync()
461 wake_up(&mcdi->wq); in efx_mcdi_complete_sync()
468 static void efx_mcdi_release(struct efx_mcdi_iface *mcdi) in efx_mcdi_release() argument
470 if (mcdi->mode == MCDI_MODE_EVENTS) { in efx_mcdi_release()
472 struct efx_nic *efx = mcdi->efx; in efx_mcdi_release()
475 spin_lock_bh(&mcdi->async_lock); in efx_mcdi_release()
477 &mcdi->async_list, struct efx_mcdi_async_param, list); in efx_mcdi_release()
479 mcdi->state = MCDI_STATE_RUNNING_ASYNC; in efx_mcdi_release()
483 mod_timer(&mcdi->async_timer, in efx_mcdi_release()
486 spin_unlock_bh(&mcdi->async_lock); in efx_mcdi_release()
492 mcdi->state = MCDI_STATE_QUIESCENT; in efx_mcdi_release()
493 wake_up(&mcdi->wq); in efx_mcdi_release()
501 static bool efx_mcdi_complete_async(struct efx_mcdi_iface *mcdi, bool timeout) in efx_mcdi_complete_async() argument
503 struct efx_nic *efx = mcdi->efx; in efx_mcdi_complete_async()
510 if (cmpxchg(&mcdi->state, in efx_mcdi_complete_async()
515 spin_lock(&mcdi->iface_lock); in efx_mcdi_complete_async()
520 ++mcdi->seqno; in efx_mcdi_complete_async()
521 ++mcdi->credits; in efx_mcdi_complete_async()
526 rc = mcdi->resprc; in efx_mcdi_complete_async()
527 hdr_len = mcdi->resp_hdr_len; in efx_mcdi_complete_async()
528 data_len = mcdi->resp_data_len; in efx_mcdi_complete_async()
530 spin_unlock(&mcdi->iface_lock); in efx_mcdi_complete_async()
537 del_timer_sync(&mcdi->async_timer); in efx_mcdi_complete_async()
539 spin_lock(&mcdi->async_lock); in efx_mcdi_complete_async()
540 async = list_first_entry(&mcdi->async_list, in efx_mcdi_complete_async()
543 spin_unlock(&mcdi->async_lock); in efx_mcdi_complete_async()
561 efx_mcdi_release(mcdi); in efx_mcdi_complete_async()
569 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_ev_cpl() local
572 spin_lock(&mcdi->iface_lock); in efx_mcdi_ev_cpl()
574 if ((seqno ^ mcdi->seqno) & SEQ_MASK) { in efx_mcdi_ev_cpl()
575 if (mcdi->credits) in efx_mcdi_ev_cpl()
577 --mcdi->credits; in efx_mcdi_ev_cpl()
581 "seq 0x%x\n", seqno, mcdi->seqno); in efx_mcdi_ev_cpl()
587 mcdi->resprc = efx_mcdi_errno(mcdi_err); in efx_mcdi_ev_cpl()
588 mcdi->resp_hdr_len = 4; in efx_mcdi_ev_cpl()
589 mcdi->resp_data_len = datalen; in efx_mcdi_ev_cpl()
595 spin_unlock(&mcdi->iface_lock); in efx_mcdi_ev_cpl()
598 if (!efx_mcdi_complete_async(mcdi, false)) in efx_mcdi_ev_cpl()
599 (void) efx_mcdi_complete_sync(mcdi); in efx_mcdi_ev_cpl()
612 struct efx_mcdi_iface *mcdi = from_timer(mcdi, t, async_timer); in efx_mcdi_timeout_async() local
614 efx_mcdi_complete_async(mcdi, true); in efx_mcdi_timeout_async()
658 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in _efx_mcdi_rpc_finish() local
662 if (mcdi->mode == MCDI_MODE_POLL) in _efx_mcdi_rpc_finish()
670 cmd, (int)inlen, mcdi->mode); in _efx_mcdi_rpc_finish()
672 if (mcdi->mode == MCDI_MODE_EVENTS && efx_mcdi_poll_once(efx)) { in _efx_mcdi_rpc_finish()
684 spin_lock_bh(&mcdi->iface_lock); in _efx_mcdi_rpc_finish()
685 ++mcdi->seqno; in _efx_mcdi_rpc_finish()
686 ++mcdi->credits; in _efx_mcdi_rpc_finish()
687 spin_unlock_bh(&mcdi->iface_lock); in _efx_mcdi_rpc_finish()
703 spin_lock_bh(&mcdi->iface_lock); in _efx_mcdi_rpc_finish()
704 rc = mcdi->resprc; in _efx_mcdi_rpc_finish()
706 *raw_rc = mcdi->resprc_raw; in _efx_mcdi_rpc_finish()
707 hdr_len = mcdi->resp_hdr_len; in _efx_mcdi_rpc_finish()
708 data_len = mcdi->resp_data_len; in _efx_mcdi_rpc_finish()
710 spin_unlock_bh(&mcdi->iface_lock); in _efx_mcdi_rpc_finish()
733 mcdi->proxy_rx_status = 0; in _efx_mcdi_rpc_finish()
734 mcdi->proxy_rx_handle = 0; in _efx_mcdi_rpc_finish()
735 mcdi->state = MCDI_STATE_PROXY_WAIT; in _efx_mcdi_rpc_finish()
744 mcdi->new_epoch = true; in _efx_mcdi_rpc_finish()
749 efx_mcdi_release(mcdi); in _efx_mcdi_rpc_finish()
753 static void efx_mcdi_proxy_abort(struct efx_mcdi_iface *mcdi) in efx_mcdi_proxy_abort() argument
755 if (mcdi->state == MCDI_STATE_PROXY_WAIT) { in efx_mcdi_proxy_abort()
757 mcdi->proxy_rx_status = -EINTR; in efx_mcdi_proxy_abort()
758 wake_up(&mcdi->proxy_rx_wq); in efx_mcdi_proxy_abort()
765 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_ev_proxy_response() local
767 WARN_ON(mcdi->state != MCDI_STATE_PROXY_WAIT); in efx_mcdi_ev_proxy_response()
769 mcdi->proxy_rx_status = efx_mcdi_errno(status); in efx_mcdi_ev_proxy_response()
774 mcdi->proxy_rx_handle = handle; in efx_mcdi_ev_proxy_response()
775 wake_up(&mcdi->proxy_rx_wq); in efx_mcdi_ev_proxy_response()
780 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_proxy_wait() local
784 rc = wait_event_timeout(mcdi->proxy_rx_wq, in efx_mcdi_proxy_wait()
785 mcdi->proxy_rx_handle != 0 || in efx_mcdi_proxy_wait()
786 mcdi->proxy_rx_status == -EINTR, in efx_mcdi_proxy_wait()
793 } else if (mcdi->proxy_rx_handle != handle) { in efx_mcdi_proxy_wait()
796 mcdi->proxy_rx_handle, handle); in efx_mcdi_proxy_wait()
800 return mcdi->proxy_rx_status; in efx_mcdi_proxy_wait()
829 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in _efx_mcdi_rpc() local
841 mcdi->state = MCDI_STATE_RUNNING_SYNC; in _efx_mcdi_rpc()
854 efx_mcdi_release(mcdi); in _efx_mcdi_rpc()
957 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_siena_mcdi_rpc_start() local
967 if (mcdi->mode == MCDI_MODE_FAIL) in efx_siena_mcdi_rpc_start()
970 efx_mcdi_acquire_sync(mcdi); in efx_siena_mcdi_rpc_start()
981 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in _efx_mcdi_rpc_async() local
1005 spin_lock_bh(&mcdi->async_lock); in _efx_mcdi_rpc_async()
1007 if (mcdi->mode == MCDI_MODE_EVENTS) { in _efx_mcdi_rpc_async()
1008 list_add_tail(&async->list, &mcdi->async_list); in _efx_mcdi_rpc_async()
1013 if (mcdi->async_list.next == &async->list && in _efx_mcdi_rpc_async()
1014 efx_mcdi_acquire_async(mcdi)) { in _efx_mcdi_rpc_async()
1016 mod_timer(&mcdi->async_timer, in _efx_mcdi_rpc_async()
1024 spin_unlock_bh(&mcdi->async_lock); in _efx_mcdi_rpc_async()
1106 struct efx_mcdi_iface *mcdi; in efx_siena_mcdi_mode_poll() local
1108 if (!efx->mcdi) in efx_siena_mcdi_mode_poll()
1111 mcdi = efx_mcdi(efx); in efx_siena_mcdi_mode_poll()
1116 if (mcdi->mode == MCDI_MODE_POLL || mcdi->mode == MCDI_MODE_FAIL) in efx_siena_mcdi_mode_poll()
1127 mcdi->mode = MCDI_MODE_POLL; in efx_siena_mcdi_mode_poll()
1129 efx_mcdi_complete_sync(mcdi); in efx_siena_mcdi_mode_poll()
1138 struct efx_mcdi_iface *mcdi; in efx_siena_mcdi_flush_async() local
1140 if (!efx->mcdi) in efx_siena_mcdi_flush_async()
1143 mcdi = efx_mcdi(efx); in efx_siena_mcdi_flush_async()
1146 BUG_ON(mcdi->mode == MCDI_MODE_EVENTS); in efx_siena_mcdi_flush_async()
1148 del_timer_sync(&mcdi->async_timer); in efx_siena_mcdi_flush_async()
1154 if (mcdi->state == MCDI_STATE_RUNNING_ASYNC) { in efx_siena_mcdi_flush_async()
1156 mcdi->state = MCDI_STATE_QUIESCENT; in efx_siena_mcdi_flush_async()
1164 list_for_each_entry_safe(async, next, &mcdi->async_list, list) { in efx_siena_mcdi_flush_async()
1174 struct efx_mcdi_iface *mcdi; in efx_siena_mcdi_mode_event() local
1176 if (!efx->mcdi) in efx_siena_mcdi_mode_event()
1179 mcdi = efx_mcdi(efx); in efx_siena_mcdi_mode_event()
1184 if (mcdi->mode == MCDI_MODE_EVENTS || mcdi->mode == MCDI_MODE_FAIL) in efx_siena_mcdi_mode_event()
1194 efx_mcdi_acquire_sync(mcdi); in efx_siena_mcdi_mode_event()
1195 mcdi->mode = MCDI_MODE_EVENTS; in efx_siena_mcdi_mode_event()
1196 efx_mcdi_release(mcdi); in efx_siena_mcdi_mode_event()
1201 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_ev_death() local
1227 spin_lock(&mcdi->iface_lock); in efx_mcdi_ev_death()
1228 efx_mcdi_proxy_abort(mcdi); in efx_mcdi_ev_death()
1230 if (efx_mcdi_complete_sync(mcdi)) { in efx_mcdi_ev_death()
1231 if (mcdi->mode == MCDI_MODE_EVENTS) { in efx_mcdi_ev_death()
1232 mcdi->resprc = rc; in efx_mcdi_ev_death()
1233 mcdi->resp_hdr_len = 0; in efx_mcdi_ev_death()
1234 mcdi->resp_data_len = 0; in efx_mcdi_ev_death()
1235 ++mcdi->credits; in efx_mcdi_ev_death()
1257 mcdi->new_epoch = true; in efx_mcdi_ev_death()
1263 spin_unlock(&mcdi->iface_lock); in efx_mcdi_ev_death()
1273 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_ev_bist() local
1275 spin_lock(&mcdi->iface_lock); in efx_mcdi_ev_bist()
1277 efx_mcdi_proxy_abort(mcdi); in efx_mcdi_ev_bist()
1279 if (efx_mcdi_complete_sync(mcdi)) { in efx_mcdi_ev_bist()
1280 if (mcdi->mode == MCDI_MODE_EVENTS) { in efx_mcdi_ev_bist()
1281 mcdi->resprc = -EIO; in efx_mcdi_ev_bist()
1282 mcdi->resp_hdr_len = 0; in efx_mcdi_ev_bist()
1283 mcdi->resp_data_len = 0; in efx_mcdi_ev_bist()
1284 ++mcdi->credits; in efx_mcdi_ev_bist()
1287 mcdi->new_epoch = true; in efx_mcdi_ev_bist()
1289 spin_unlock(&mcdi->iface_lock); in efx_mcdi_ev_bist()
1297 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_mcdi_abandon() local
1299 if (xchg(&mcdi->mode, MCDI_MODE_FAIL) == MCDI_MODE_FAIL) in efx_mcdi_abandon()
1498 efx->mcdi->fn_flags = in efx_mcdi_drv_attach()
1503 efx->mcdi->fn_flags = in efx_mcdi_drv_attach()
1875 if (efx->mcdi) { in efx_siena_mcdi_reset()
1876 struct efx_mcdi_iface *mcdi = efx_mcdi(efx); in efx_siena_mcdi_reset() local
1877 mcdi->mode = MCDI_MODE_POLL; in efx_siena_mcdi_reset()