Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F105791874
D6717.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D6717.diff
View Options
Index: head/sys/dev/sfxge/common/ef10_ev.c
===================================================================
--- head/sys/dev/sfxge/common/ef10_ev.c
+++ head/sys/dev/sfxge/common/ef10_ev.c
@@ -139,7 +139,8 @@
__in efsys_mem_t *esmp,
__in size_t nevs,
__in uint32_t irq,
- __in uint32_t us)
+ __in uint32_t us,
+ __in boolean_t low_latency)
{
efx_mcdi_req_t req;
uint8_t payload[
@@ -149,7 +150,7 @@
uint64_t addr;
int npages;
int i;
- int supports_rx_batching;
+ int ev_cut_through;
efx_rc_t rc;
npages = EFX_EVQ_NBUFS(nevs);
@@ -170,21 +171,19 @@
MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_IRQ_NUM, irq);
/*
- * On Huntington RX and TX event batching can only be requested
- * together (even if the datapath firmware doesn't actually support RX
- * batching).
- * Cut through is incompatible with RX batching and so enabling cut
- * through disables RX batching (but it does not affect TX batching).
+ * On Huntington RX and TX event batching can only be requested together
+ * (even if the datapath firmware doesn't actually support RX
+ * batching). If event cut through is enabled no RX batching will occur.
*
- * So always enable RX and TX event batching, and enable cut through
- * if RX event batching isn't supported (i.e. on low latency firmware).
+ * So always enable RX and TX event batching, and enable event cut
+ * through if we want low latency operation.
*/
- supports_rx_batching = enp->en_nic_cfg.enc_rx_batching_enabled ? 1 : 0;
+ ev_cut_through = low_latency ? 1 : 0;
MCDI_IN_POPULATE_DWORD_6(req, INIT_EVQ_IN_FLAGS,
INIT_EVQ_IN_FLAG_INTERRUPTING, 1,
INIT_EVQ_IN_FLAG_RPTR_DOS, 0,
INIT_EVQ_IN_FLAG_INT_ARMD, 0,
- INIT_EVQ_IN_FLAG_CUT_THRU, !supports_rx_batching,
+ INIT_EVQ_IN_FLAG_CUT_THRU, ev_cut_through,
INIT_EVQ_IN_FLAG_RX_MERGE, 1,
INIT_EVQ_IN_FLAG_TX_MERGE, 1);
@@ -250,6 +249,114 @@
return (rc);
}
+
+static __checkReturn efx_rc_t
+efx_mcdi_init_evq_v2(
+ __in efx_nic_t *enp,
+ __in unsigned int instance,
+ __in efsys_mem_t *esmp,
+ __in size_t nevs,
+ __in uint32_t irq,
+ __in uint32_t us)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[
+ MAX(MC_CMD_INIT_EVQ_V2_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
+ MC_CMD_INIT_EVQ_V2_OUT_LEN)];
+ efx_qword_t *dma_addr;
+ uint64_t addr;
+ int npages;
+ int i;
+ efx_rc_t rc;
+
+ npages = EFX_EVQ_NBUFS(nevs);
+ if (MC_CMD_INIT_EVQ_V2_IN_LEN(npages) > MC_CMD_INIT_EVQ_V2_IN_LENMAX) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_INIT_EVQ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_INIT_EVQ_V2_IN_LEN(npages);
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_INIT_EVQ_V2_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_SIZE, nevs);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_INSTANCE, instance);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_IRQ_NUM, irq);
+
+ MCDI_IN_POPULATE_DWORD_4(req, INIT_EVQ_V2_IN_FLAGS,
+ INIT_EVQ_V2_IN_FLAG_INTERRUPTING, 1,
+ INIT_EVQ_V2_IN_FLAG_RPTR_DOS, 0,
+ INIT_EVQ_V2_IN_FLAG_INT_ARMD, 0,
+ INIT_EVQ_V2_IN_FLAG_TYPE, MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_AUTO);
+
+ /* If the value is zero then disable the timer */
+ if (us == 0) {
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_MODE,
+ MC_CMD_INIT_EVQ_V2_IN_TMR_MODE_DIS);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_LOAD, 0);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_RELOAD, 0);
+ } else {
+ unsigned int ticks;
+
+ if ((rc = efx_ev_usecs_to_ticks(enp, us, &ticks)) != 0)
+ goto fail2;
+
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_MODE,
+ MC_CMD_INIT_EVQ_V2_IN_TMR_INT_HLDOFF);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_LOAD, ticks);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_RELOAD, ticks);
+ }
+
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_COUNT_MODE,
+ MC_CMD_INIT_EVQ_V2_IN_COUNT_MODE_DIS);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_COUNT_THRSHLD, 0);
+
+ dma_addr = MCDI_IN2(req, efx_qword_t, INIT_EVQ_V2_IN_DMA_ADDR);
+ addr = EFSYS_MEM_ADDR(esmp);
+
+ for (i = 0; i < npages; i++) {
+ EFX_POPULATE_QWORD_2(*dma_addr,
+ EFX_DWORD_1, (uint32_t)(addr >> 32),
+ EFX_DWORD_0, (uint32_t)(addr & 0xffffffff));
+
+ dma_addr++;
+ addr += EFX_BUF_SIZE;
+ }
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail3;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_INIT_EVQ_V2_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail4;
+ }
+
+ /* NOTE: ignore the returned IRQ param as firmware does not set it. */
+
+ EFSYS_PROBE1(mcdi_evq_flags, uint32_t,
+ MCDI_OUT_DWORD(req, INIT_EVQ_V2_OUT_FLAGS));
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
static __checkReturn efx_rc_t
efx_mcdi_fini_evq(
__in efx_nic_t *enp,
@@ -348,11 +455,41 @@
* Interrupts may be raised for events immediately after the queue is
* created. See bug58606.
*/
- if ((rc = efx_mcdi_init_evq(enp, index, esmp, n, irq, us)) != 0)
- goto fail4;
+
+ if (encp->enc_init_evq_v2_supported) {
+ /*
+ * On Medford the low latency license is required to enable RX
+ * and event cut through and to disable RX batching. We let the
+ * firmware decide the settings to use. If the adapter has a low
+ * latency license, it will choose the best settings for low
+ * latency, otherwise it choose the best settings for
+ * throughput.
+ */
+ rc = efx_mcdi_init_evq_v2(enp, index, esmp, n, irq, us);
+ if (rc != 0)
+ goto fail4;
+ } else {
+ /*
+ * On Huntington we need to specify the settings to use. We
+ * favour latency if the adapter is running low-latency firmware
+ * and throughput otherwise, and assume not support RX batching
+ * implies the adapter is running low-latency firmware. (This
+ * is how it's been done since Huntington GA. It doesn't make
+ * much sense with hindsight as the 'low-latency' firmware
+ * variant is also best for throughput, and does now support RX
+ * batching).
+ */
+ boolean_t low_latency = encp->enc_rx_batching_enabled ? 0 : 1;
+ rc = efx_mcdi_init_evq(enp, index, esmp, n, irq, us,
+ low_latency);
+ if (rc != 0)
+ goto fail5;
+ }
return (0);
+fail5:
+ EFSYS_PROBE(fail5);
fail4:
EFSYS_PROBE(fail4);
fail3:
Index: head/sys/dev/sfxge/common/ef10_nic.c
===================================================================
--- head/sys/dev/sfxge/common/ef10_nic.c
+++ head/sys/dev/sfxge/common/ef10_nic.c
@@ -1025,6 +1025,13 @@
encp->enc_enhanced_set_mac_supported =
CAP_FLAG(flags, SET_MAC_ENHANCED) ? B_TRUE : B_FALSE;
+ /*
+ * Check if firmware supports version 2 of MC_CMD_INIT_EVQ, which allows
+ * us to let the firmware choose the settings to use on an EVQ.
+ */
+ encp->enc_init_evq_v2_supported =
+ CAP_FLAG2(flags2, INIT_EVQ_V2) ? B_TRUE : B_FALSE;
+
#undef CAP_FLAG
#undef CAP_FLAG2
Index: head/sys/dev/sfxge/common/efx.h
===================================================================
--- head/sys/dev/sfxge/common/efx.h
+++ head/sys/dev/sfxge/common/efx.h
@@ -1148,6 +1148,7 @@
boolean_t enc_rx_disable_scatter_supported;
boolean_t enc_allow_set_mac_with_installed_filters;
boolean_t enc_enhanced_set_mac_supported;
+ boolean_t enc_init_evq_v2_supported;
/* External port identifier */
uint8_t enc_external_port;
uint32_t enc_mcdi_max_payload_length;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Dec 21, 6:28 PM (20 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15544851
Default Alt Text
D6717.diff (7 KB)
Attached To
Mode
D6717: sfxge(4): allow firmware to auto-configure event queues on Medford
Attached
Detach File
Event Timeline
Log In to Comment