X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcommon%2Fsfc_efx%2Fbase%2Frhead_ev.c;h=2b5635f1cd2e430aab0513f9345b4c2905389333;hb=ea42cae43de6ea83972ee18b7ced8d8c2b3b9299;hp=df5e3e26c675385449b54cb60b0b1cc5eff3e3ea;hpb=1a4448be57aa7851a3d73b969ebe58fa9eb51631;p=dpdk.git diff --git a/drivers/common/sfc_efx/base/rhead_ev.c b/drivers/common/sfc_efx/base/rhead_ev.c index df5e3e26c6..2b5635f1cd 100644 --- a/drivers/common/sfc_efx/base/rhead_ev.c +++ b/drivers/common/sfc_efx/base/rhead_ev.c @@ -16,6 +16,13 @@ */ #define EFX_RHEAD_ALWAYS_INTERRUPTING_EVQ_INDEX (0) +static boolean_t +rhead_ev_dispatch( + __in efx_evq_t *eep, + __in efx_qword_t *eventp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg); + static __checkReturn boolean_t rhead_ev_rx_packets( __in efx_evq_t *eep, @@ -51,6 +58,22 @@ rhead_ev_ew_qpoll( __inout unsigned int *countp, __in const efx_ev_callbacks_t *eecp, __in_opt void *arg); + +#if EFSYS_OPT_DESC_PROXY +static boolean_t +rhead_ev_ew_txq_desc( + __in efx_evq_t *eep, + __in efx_xword_t *eventp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg); + +static boolean_t +rhead_ev_ew_virtq_desc( + __in efx_evq_t *eep, + __in efx_xword_t *eventp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg); +#endif /* EFSYS_OPT_DESC_PROXY */ #endif /* EFSYS_OPT_EV_EXTENDED_WIDTH */ @@ -108,6 +131,11 @@ rhead_ev_qcreate( eep->ee_drv_gen = NULL; /* FIXME */ eep->ee_mcdi = rhead_ev_mcdi; +#if EFSYS_OPT_DESC_PROXY + eep->ee_ew_txq_desc = rhead_ev_ew_txq_desc; + eep->ee_ew_virtq_desc = rhead_ev_ew_virtq_desc; +#endif /* EFSYS_OPT_DESC_PROXY */ + /* Set up the event queue */ /* INIT_EVQ expects function-relative vector number */ if ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) == @@ -181,6 +209,41 @@ rhead_ev_qpost( EFSYS_ASSERT(B_FALSE); } +static __checkReturn boolean_t +rhead_ev_dispatch( + __in efx_evq_t *eep, + __in efx_qword_t *eventp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg) +{ + boolean_t should_abort; + uint32_t code; + + code = EFX_QWORD_FIELD(*eventp, ESF_GZ_E_TYPE); + switch (code) { + case ESE_GZ_EF100_EV_RX_PKTS: + should_abort = eep->ee_rx(eep, eventp, eecp, arg); + break; + case ESE_GZ_EF100_EV_TX_COMPLETION: + should_abort = eep->ee_tx(eep, eventp, eecp, arg); + break; + case ESE_GZ_EF100_EV_MCDI: + should_abort = eep->ee_mcdi(eep, eventp, eecp, arg); + break; + default: + EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index, + uint32_t, EFX_QWORD_FIELD(*eventp, EFX_DWORD_1), + uint32_t, EFX_QWORD_FIELD(*eventp, EFX_DWORD_0)); + + EFSYS_ASSERT(eecp->eec_exception != NULL); + (void) eecp->eec_exception(arg, EFX_EXCEPTION_EV_ERROR, code); + should_abort = B_TRUE; + break; + } + + return (should_abort); +} + /* * Poll event queue in batches. Size of the batch is equal to cache line * size divided by event size. @@ -248,37 +311,12 @@ rhead_ev_qpoll( /* Process the batch of events */ for (index = 0; index < total; ++index) { boolean_t should_abort; - uint32_t code; EFX_EV_QSTAT_INCR(eep, EV_ALL); - code = EFX_QWORD_FIELD(ev[index], ESF_GZ_E_TYPE); - switch (code) { - case ESE_GZ_EF100_EV_RX_PKTS: - should_abort = eep->ee_rx(eep, - &(ev[index]), eecp, arg); - break; - case ESE_GZ_EF100_EV_TX_COMPLETION: - should_abort = eep->ee_tx(eep, - &(ev[index]), eecp, arg); - break; - case ESE_GZ_EF100_EV_MCDI: - should_abort = eep->ee_mcdi(eep, - &(ev[index]), eecp, arg); - break; - default: - EFSYS_PROBE3(bad_event, - unsigned int, eep->ee_index, - uint32_t, - EFX_QWORD_FIELD(ev[index], EFX_DWORD_1), - uint32_t, - EFX_QWORD_FIELD(ev[index], EFX_DWORD_0)); - - EFSYS_ASSERT(eecp->eec_exception != NULL); - (void) eecp->eec_exception(arg, - EFX_EXCEPTION_EV_ERROR, code); - should_abort = B_TRUE; - } + should_abort = + rhead_ev_dispatch(eep, &(ev[index]), eecp, arg); + if (should_abort) { /* Ignore subsequent events */ total = index + 1; @@ -322,6 +360,22 @@ rhead_ev_ew_dispatch( code = EFX_XWORD_FIELD(*eventp, ESF_GZ_EV_256_EV32_TYPE); switch (code) { + case ESE_GZ_EF100_EVEW_64BIT: + /* NOTE: ignore phase bit in encapsulated 64bit event. */ + should_abort = + rhead_ev_dispatch(eep, &eventp->ex_qword[0], eecp, arg); + break; + +#if EFSYS_OPT_DESC_PROXY + case ESE_GZ_EF100_EVEW_TXQ_DESC: + should_abort = eep->ee_ew_txq_desc(eep, eventp, eecp, arg); + break; + + case ESE_GZ_EF100_EVEW_VIRTQ_DESC: + should_abort = eep->ee_ew_virtq_desc(eep, eventp, eecp, arg); + break; +#endif /* EFSYS_OPT_DESC_PROXY */ + default: /* Omit currently unused reserved bits from the probe. */ EFSYS_PROBE7(ew_bad_event, unsigned int, eep->ee_index, @@ -566,4 +620,68 @@ rhead_ev_mcdi( return (ret); } +#if EFSYS_OPT_DESC_PROXY +static boolean_t +rhead_ev_ew_txq_desc( + __in efx_evq_t *eep, + __in efx_xword_t *eventp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg) +{ + efx_oword_t txq_desc; + uint16_t vi_id; + boolean_t should_abort; + + _NOTE(ARGUNUSED(eep)) + + vi_id = EFX_XWORD_FIELD(*eventp, ESF_GZ_EV_TXQ_DP_VI_ID); + + /* + * NOTE: This is the raw descriptor data, and has not been converted + * to host endian. The handler callback must use the EFX_OWORD macros + * to extract the descriptor fields as host endian values. + */ + txq_desc = eventp->ex_oword[0]; + + EFSYS_ASSERT(eecp->eec_desc_proxy_txq_desc != NULL); + should_abort = eecp->eec_desc_proxy_txq_desc(arg, vi_id, txq_desc); + + return (should_abort); +} +#endif /* EFSYS_OPT_DESC_PROXY */ + + +#if EFSYS_OPT_DESC_PROXY +static boolean_t +rhead_ev_ew_virtq_desc( + __in efx_evq_t *eep, + __in efx_xword_t *eventp, + __in const efx_ev_callbacks_t *eecp, + __in_opt void *arg) +{ + efx_oword_t virtq_desc; + uint16_t vi_id; + uint16_t avail; + boolean_t should_abort; + + _NOTE(ARGUNUSED(eep)) + + vi_id = EFX_XWORD_FIELD(*eventp, ESF_GZ_EV_VQ_DP_VI_ID); + avail = EFX_XWORD_FIELD(*eventp, ESF_GZ_EV_VQ_DP_AVAIL_ENTRY); + + /* + * NOTE: This is the raw descriptor data, and has not been converted + * to host endian. The handler callback must use the EFX_OWORD macros + * to extract the descriptor fields as host endian values. + */ + virtq_desc = eventp->ex_oword[0]; + + EFSYS_ASSERT(eecp->eec_desc_proxy_virtq_desc != NULL); + should_abort = + eecp->eec_desc_proxy_virtq_desc(arg, vi_id, avail, virtq_desc); + + return (should_abort); +} +#endif /* EFSYS_OPT_DESC_PROXY */ + #endif /* EFSYS_OPT_RIVERHEAD */