Lines Matching refs:mcdi

63 	struct efx_mcdi_iface *mcdi;
67 efx->mcdi = kzalloc(sizeof(*efx->mcdi), GFP_KERNEL);
68 if (!efx->mcdi)
71 mcdi = efx_mcdi(efx);
72 mcdi->efx = efx;
75 mcdi->logging_buffer = (char *)__get_free_page(GFP_KERNEL);
76 if (!mcdi->logging_buffer)
78 mcdi->logging_enabled = mcdi_logging_default;
80 init_waitqueue_head(&mcdi->wq);
81 init_waitqueue_head(&mcdi->proxy_rx_wq);
82 spin_lock_init(&mcdi->iface_lock);
83 mcdi->state = MCDI_STATE_QUIESCENT;
84 mcdi->mode = MCDI_MODE_POLL;
85 spin_lock_init(&mcdi->async_lock);
86 INIT_LIST_HEAD(&mcdi->async_list);
87 timer_setup(&mcdi->async_timer, efx_mcdi_timeout_async, 0);
90 mcdi->new_epoch = true;
111 if (efx->mcdi->fn_flags &
118 free_page((unsigned long)mcdi->logging_buffer);
121 kfree(efx->mcdi);
122 efx->mcdi = NULL;
129 if (!efx->mcdi)
132 BUG_ON(efx->mcdi->iface.state != MCDI_STATE_QUIESCENT);
140 if (!efx->mcdi)
144 free_page((unsigned long)efx->mcdi->iface.logging_buffer);
147 kfree(efx->mcdi);
153 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
155 char *buf = mcdi->logging_buffer; /* page-sized */
161 BUG_ON(mcdi->state == MCDI_STATE_QUIESCENT);
164 spin_lock_bh(&mcdi->iface_lock);
165 ++mcdi->seqno;
166 seqno = mcdi->seqno & SEQ_MASK;
167 spin_unlock_bh(&mcdi->iface_lock);
170 if (mcdi->mode == MCDI_MODE_EVENTS)
182 MCDI_HEADER_NOT_EPOCH, !mcdi->new_epoch);
194 MCDI_HEADER_NOT_EPOCH, !mcdi->new_epoch);
202 if (mcdi->logging_enabled && !WARN_ON_ONCE(!buf)) {
230 mcdi->new_epoch = false;
267 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
270 char *buf = mcdi->logging_buffer; /* page-sized */
280 mcdi->resp_hdr_len = 4;
281 mcdi->resp_data_len = EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN);
284 mcdi->resp_hdr_len = 8;
285 mcdi->resp_data_len =
290 if (mcdi->logging_enabled && !WARN_ON_ONCE(!buf)) {
295 WARN_ON_ONCE(mcdi->resp_hdr_len % 4);
296 hdr_len = mcdi->resp_hdr_len / 4;
300 data_len = DIV_ROUND_UP(mcdi->resp_data_len, 4);
313 mcdi->resp_hdr_len + (i * 4), 4);
322 mcdi->resprc_raw = 0;
323 if (error && mcdi->resp_data_len == 0) {
325 mcdi->resprc = -EIO;
326 } else if ((respseq ^ mcdi->seqno) & SEQ_MASK) {
329 respseq, mcdi->seqno);
330 mcdi->resprc = -EIO;
332 efx->type->mcdi_read_response(efx, &hdr, mcdi->resp_hdr_len, 4);
333 mcdi->resprc_raw = EFX_DWORD_FIELD(hdr, EFX_DWORD_0);
334 mcdi->resprc = efx_mcdi_errno(mcdi->resprc_raw);
336 mcdi->resprc = 0;
342 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
348 spin_lock_bh(&mcdi->iface_lock);
350 spin_unlock_bh(&mcdi->iface_lock);
357 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
365 spin_lock_bh(&mcdi->iface_lock);
366 mcdi->resprc = rc;
367 mcdi->resp_hdr_len = 0;
368 mcdi->resp_data_len = 0;
369 spin_unlock_bh(&mcdi->iface_lock);
374 * because generally mcdi responses are fast. After that, back off
406 if (!efx->mcdi)
412 static bool efx_mcdi_acquire_async(struct efx_mcdi_iface *mcdi)
414 return cmpxchg(&mcdi->state,
419 static void efx_mcdi_acquire_sync(struct efx_mcdi_iface *mcdi)
424 wait_event(mcdi->wq,
425 cmpxchg(&mcdi->state,
432 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
434 if (wait_event_timeout(mcdi->wq, mcdi->state == MCDI_STATE_COMPLETED,
446 if (mcdi->mode == MCDI_MODE_POLL)
455 static bool efx_mcdi_complete_sync(struct efx_mcdi_iface *mcdi)
457 if (cmpxchg(&mcdi->state,
460 wake_up(&mcdi->wq);
467 static void efx_mcdi_release(struct efx_mcdi_iface *mcdi)
469 if (mcdi->mode == MCDI_MODE_EVENTS) {
471 struct efx_nic *efx = mcdi->efx;
474 spin_lock_bh(&mcdi->async_lock);
476 &mcdi->async_list, struct efx_mcdi_async_param, list);
478 mcdi->state = MCDI_STATE_RUNNING_ASYNC;
482 mod_timer(&mcdi->async_timer,
485 spin_unlock_bh(&mcdi->async_lock);
491 mcdi->state = MCDI_STATE_QUIESCENT;
492 wake_up(&mcdi->wq);
500 static bool efx_mcdi_complete_async(struct efx_mcdi_iface *mcdi, bool timeout)
502 struct efx_nic *efx = mcdi->efx;
509 if (cmpxchg(&mcdi->state,
514 spin_lock(&mcdi->iface_lock);
519 ++mcdi->seqno;
520 ++mcdi->credits;
525 rc = mcdi->resprc;
526 hdr_len = mcdi->resp_hdr_len;
527 data_len = mcdi->resp_data_len;
529 spin_unlock(&mcdi->iface_lock);
536 del_timer_sync(&mcdi->async_timer);
538 spin_lock(&mcdi->async_lock);
539 async = list_first_entry(&mcdi->async_list,
542 spin_unlock(&mcdi->async_lock);
560 efx_mcdi_release(mcdi);
568 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
571 spin_lock(&mcdi->iface_lock);
573 if ((seqno ^ mcdi->seqno) & SEQ_MASK) {
574 if (mcdi->credits)
576 --mcdi->credits;
580 "seq 0x%x\n", seqno, mcdi->seqno);
586 mcdi->resprc = efx_mcdi_errno(mcdi_err);
587 mcdi->resp_hdr_len = 4;
588 mcdi->resp_data_len = datalen;
594 spin_unlock(&mcdi->iface_lock);
597 if (!efx_mcdi_complete_async(mcdi, false))
598 (void) efx_mcdi_complete_sync(mcdi);
611 struct efx_mcdi_iface *mcdi = from_timer(mcdi, t, async_timer);
613 efx_mcdi_complete_async(mcdi, true);
657 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
661 if (mcdi->mode == MCDI_MODE_POLL)
669 cmd, (int)inlen, mcdi->mode);
671 if (mcdi->mode == MCDI_MODE_EVENTS && efx_mcdi_poll_once(efx)) {
683 spin_lock_bh(&mcdi->iface_lock);
684 ++mcdi->seqno;
685 ++mcdi->credits;
686 spin_unlock_bh(&mcdi->iface_lock);
702 spin_lock_bh(&mcdi->iface_lock);
703 rc = mcdi->resprc;
705 *raw_rc = mcdi->resprc_raw;
706 hdr_len = mcdi->resp_hdr_len;
707 data_len = mcdi->resp_data_len;
709 spin_unlock_bh(&mcdi->iface_lock);
732 mcdi->proxy_rx_status = 0;
733 mcdi->proxy_rx_handle = 0;
734 mcdi->state = MCDI_STATE_PROXY_WAIT;
743 mcdi->new_epoch = true;
748 efx_mcdi_release(mcdi);
752 static void efx_mcdi_proxy_abort(struct efx_mcdi_iface *mcdi)
754 if (mcdi->state == MCDI_STATE_PROXY_WAIT) {
756 mcdi->proxy_rx_status = -EINTR;
757 wake_up(&mcdi->proxy_rx_wq);
764 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
766 WARN_ON(mcdi->state != MCDI_STATE_PROXY_WAIT);
768 mcdi->proxy_rx_status = efx_mcdi_errno(status);
773 mcdi->proxy_rx_handle = handle;
774 wake_up(&mcdi->proxy_rx_wq);
779 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
783 rc = wait_event_timeout(mcdi->proxy_rx_wq,
784 mcdi->proxy_rx_handle != 0 ||
785 mcdi->proxy_rx_status == -EINTR,
792 } else if (mcdi->proxy_rx_handle != handle) {
795 mcdi->proxy_rx_handle, handle);
799 return mcdi->proxy_rx_status;
828 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
840 mcdi->state = MCDI_STATE_RUNNING_SYNC;
853 efx_mcdi_release(mcdi);
956 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
966 if (mcdi->mode == MCDI_MODE_FAIL)
969 efx_mcdi_acquire_sync(mcdi);
980 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
1004 spin_lock_bh(&mcdi->async_lock);
1006 if (mcdi->mode == MCDI_MODE_EVENTS) {
1007 list_add_tail(&async->list, &mcdi->async_list);
1012 if (mcdi->async_list.next == &async->list &&
1013 efx_mcdi_acquire_async(mcdi)) {
1015 mod_timer(&mcdi->async_timer,
1023 spin_unlock_bh(&mcdi->async_lock);
1103 struct efx_mcdi_iface *mcdi;
1105 if (!efx->mcdi)
1108 mcdi = efx_mcdi(efx);
1113 if (mcdi->mode == MCDI_MODE_POLL || mcdi->mode == MCDI_MODE_FAIL)
1117 * mcdi requests are always completed in shared memory. We do this by
1124 mcdi->mode = MCDI_MODE_POLL;
1126 efx_mcdi_complete_sync(mcdi);
1135 struct efx_mcdi_iface *mcdi;
1137 if (!efx->mcdi)
1140 mcdi = efx_mcdi(efx);
1143 BUG_ON(mcdi->mode == MCDI_MODE_EVENTS);
1145 del_timer_sync(&mcdi->async_timer);
1151 if (mcdi->state == MCDI_STATE_RUNNING_ASYNC) {
1153 mcdi->state = MCDI_STATE_QUIESCENT;
1161 list_for_each_entry_safe(async, next, &mcdi->async_list, list) {
1171 struct efx_mcdi_iface *mcdi;
1173 if (!efx->mcdi)
1176 mcdi = efx_mcdi(efx);
1181 if (mcdi->mode == MCDI_MODE_EVENTS || mcdi->mode == MCDI_MODE_FAIL)
1191 efx_mcdi_acquire_sync(mcdi);
1192 mcdi->mode = MCDI_MODE_EVENTS;
1193 efx_mcdi_release(mcdi);
1198 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
1201 * either by a BADASSERT or REBOOT event. If the mcdi interface is
1203 * set the header correctly. However, if the mcdi interface is waiting
1224 spin_lock(&mcdi->iface_lock);
1225 efx_mcdi_proxy_abort(mcdi);
1227 if (efx_mcdi_complete_sync(mcdi)) {
1228 if (mcdi->mode == MCDI_MODE_EVENTS) {
1229 mcdi->resprc = rc;
1230 mcdi->resp_hdr_len = 0;
1231 mcdi->resp_data_len = 0;
1232 ++mcdi->credits;
1254 mcdi->new_epoch = true;
1260 spin_unlock(&mcdi->iface_lock);
1270 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
1272 spin_lock(&mcdi->iface_lock);
1274 efx_mcdi_proxy_abort(mcdi);
1276 if (efx_mcdi_complete_sync(mcdi)) {
1277 if (mcdi->mode == MCDI_MODE_EVENTS) {
1278 mcdi->resprc = -EIO;
1279 mcdi->resp_hdr_len = 0;
1280 mcdi->resp_data_len = 0;
1281 ++mcdi->credits;
1284 mcdi->new_epoch = true;
1286 spin_unlock(&mcdi->iface_lock);
1294 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
1296 if (xchg(&mcdi->mode, MCDI_MODE_FAIL) == MCDI_MODE_FAIL)
1494 efx->mcdi->fn_flags =
1499 efx->mcdi->fn_flags =
1624 /* This function finds types using the new NVRAM_PARTITIONS mcdi. */
1706 /* This function tests nvram partitions using the new mcdi partition lookup scheme */
1931 if (efx->mcdi) {
1932 struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
1933 mcdi->mode = MCDI_MODE_POLL;