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