Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151031086
D11702.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D11702.diff
View Options
Index: head/sys/dev/bnxt/bnxt.h
===================================================================
--- head/sys/dev/bnxt/bnxt.h
+++ head/sys/dev/bnxt/bnxt.h
@@ -214,6 +214,18 @@
/* Chip info */
#define BNXT_TSO_SIZE UINT16_MAX
+#define min_t(type, x, y) ({ \
+ type __min1 = (x); \
+ type __min2 = (y); \
+ __min1 < __min2 ? __min1 : __min2; })
+
+#define max_t(type, x, y) ({ \
+ type __max1 = (x); \
+ type __max2 = (y); \
+ __max1 > __max2 ? __max1 : __max2; })
+
+#define clamp_t(type, _x, min, max) min_t(type, max_t(type, _x, min), max)
+
/* NVRAM access */
enum bnxt_nvm_directory_type {
BNX_DIR_TYPE_UNUSED = 0,
@@ -569,6 +581,20 @@
struct bnxt_nvram_info *nvm_info;
bool wol;
uint8_t wol_filter_id;
+ uint16_t rx_coal_usecs;
+ uint16_t rx_coal_usecs_irq;
+ uint16_t rx_coal_frames;
+ uint16_t rx_coal_frames_irq;
+ uint16_t tx_coal_usecs;
+ uint16_t tx_coal_usecs_irq;
+ uint16_t tx_coal_frames;
+ uint16_t tx_coal_frames_irq;
+
+#define BNXT_USEC_TO_COAL_TIMER(x) ((x) * 25 / 2)
+#define BNXT_DEF_STATS_COAL_TICKS 1000000
+#define BNXT_MIN_STATS_COAL_TICKS 250000
+#define BNXT_MAX_STATS_COAL_TICKS 1000000
+
};
struct bnxt_filter_info {
Index: head/sys/dev/bnxt/bnxt_hwrm.h
===================================================================
--- head/sys/dev/bnxt/bnxt_hwrm.h
+++ head/sys/dev/bnxt/bnxt_hwrm.h
@@ -101,5 +101,7 @@
uint16_t bnxt_hwrm_get_wol_fltrs(struct bnxt_softc *softc, uint16_t handle);
int bnxt_hwrm_alloc_wol_fltr(struct bnxt_softc *softc);
int bnxt_hwrm_free_wol_fltr(struct bnxt_softc *softc);
-
+int bnxt_hwrm_set_coal(struct bnxt_softc *softc);
+int bnxt_hwrm_func_rgtr_async_events(struct bnxt_softc *softc, unsigned long *bmap,
+ int bmap_size);
#endif
Index: head/sys/dev/bnxt/bnxt_hwrm.c
===================================================================
--- head/sys/dev/bnxt/bnxt_hwrm.c
+++ head/sys/dev/bnxt/bnxt_hwrm.c
@@ -30,6 +30,7 @@
__FBSDID("$FreeBSD$");
#include <sys/endian.h>
+#include <sys/bitstring.h>
#include "bnxt.h"
#include "bnxt_hwrm.h"
@@ -1547,3 +1548,131 @@
req.wol_filter_id = softc->wol_filter_id;
return hwrm_send_message(softc, &req, sizeof(req));
}
+
+static void bnxt_hwrm_set_coal_params(struct bnxt_softc *softc, uint32_t max_frames,
+ uint32_t buf_tmrs, uint16_t flags,
+ struct hwrm_ring_cmpl_ring_cfg_aggint_params_input *req)
+{
+ req->flags = htole16(flags);
+ req->num_cmpl_dma_aggr = htole16((uint16_t)max_frames);
+ req->num_cmpl_dma_aggr_during_int = htole16(max_frames >> 16);
+ req->cmpl_aggr_dma_tmr = htole16((uint16_t)buf_tmrs);
+ req->cmpl_aggr_dma_tmr_during_int = htole16(buf_tmrs >> 16);
+ /* Minimum time between 2 interrupts set to buf_tmr x 2 */
+ req->int_lat_tmr_min = htole16((uint16_t)buf_tmrs * 2);
+ req->int_lat_tmr_max = htole16((uint16_t)buf_tmrs * 4);
+ req->num_cmpl_aggr_int = htole16((uint16_t)max_frames * 4);
+}
+
+
+int bnxt_hwrm_set_coal(struct bnxt_softc *softc)
+{
+ int i, rc = 0;
+ struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req_rx = {0},
+ req_tx = {0}, *req;
+ uint16_t max_buf, max_buf_irq;
+ uint16_t buf_tmr, buf_tmr_irq;
+ uint32_t flags;
+
+ bnxt_hwrm_cmd_hdr_init(softc, &req_rx,
+ HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
+ bnxt_hwrm_cmd_hdr_init(softc, &req_tx,
+ HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
+
+ /* Each rx completion (2 records) should be DMAed immediately.
+ * DMA 1/4 of the completion buffers at a time.
+ */
+ max_buf = min_t(uint16_t, softc->rx_coal_frames / 4, 2);
+ /* max_buf must not be zero */
+ max_buf = clamp_t(uint16_t, max_buf, 1, 63);
+ max_buf_irq = clamp_t(uint16_t, softc->rx_coal_frames_irq, 1, 63);
+ buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs);
+ /* buf timer set to 1/4 of interrupt timer */
+ buf_tmr = max_t(uint16_t, buf_tmr / 4, 1);
+ buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs_irq);
+ buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1);
+
+ flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET;
+
+ /* RING_IDLE generates more IRQs for lower latency. Enable it only
+ * if coal_usecs is less than 25 us.
+ */
+ if (softc->rx_coal_usecs < 25)
+ flags |= HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_RING_IDLE;
+
+ bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf,
+ buf_tmr_irq << 16 | buf_tmr, flags, &req_rx);
+
+ /* max_buf must not be zero */
+ max_buf = clamp_t(uint16_t, softc->tx_coal_frames, 1, 63);
+ max_buf_irq = clamp_t(uint16_t, softc->tx_coal_frames_irq, 1, 63);
+ buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs);
+ /* buf timer set to 1/4 of interrupt timer */
+ buf_tmr = max_t(uint16_t, buf_tmr / 4, 1);
+ buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs_irq);
+ buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1);
+ flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET;
+ bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf,
+ buf_tmr_irq << 16 | buf_tmr, flags, &req_tx);
+
+ for (i = 0; i < softc->nrxqsets; i++) {
+
+
+ req = &req_rx;
+ /*
+ * TBD:
+ * Check if Tx also needs to be done
+ * So far, Tx processing has been done in softirq contest
+ *
+ * req = &req_tx;
+ */
+ req->ring_id = htole16(softc->grp_info[i].cp_ring_id);
+
+ rc = hwrm_send_message(softc, req, sizeof(*req));
+ if (rc)
+ break;
+ }
+ return rc;
+}
+
+
+
+int bnxt_hwrm_func_rgtr_async_events(struct bnxt_softc *softc, unsigned long *bmap,
+ int bmap_size)
+{
+ struct hwrm_func_drv_rgtr_input req = {0};
+ bitstr_t *async_events_bmap;
+ uint32_t *events;
+ int i;
+
+ async_events_bmap = bit_alloc(256, M_DEVBUF, M_WAITOK|M_ZERO);
+ events = (uint32_t *)async_events_bmap;
+
+ bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_DRV_RGTR);
+
+ req.enables =
+ htole32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD);
+
+ memset(async_events_bmap, 0, sizeof(256 / 8));
+
+ bit_set(async_events_bmap, HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE);
+ bit_set(async_events_bmap, HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD);
+ bit_set(async_events_bmap, HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED);
+ bit_set(async_events_bmap, HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE);
+ bit_set(async_events_bmap, HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE);
+
+ if (bmap && bmap_size) {
+ for (i = 0; i < bmap_size; i++) {
+ if (bit_test(bmap, i))
+ bit_set(async_events_bmap, i);
+ }
+ }
+
+ for (i = 0; i < 8; i++)
+ req.async_event_fwd[i] |= htole32(events[i]);
+
+ free(async_events_bmap, M_DEVBUF);
+
+ return hwrm_send_message(softc, &req, sizeof(req));
+}
+
Index: head/sys/dev/bnxt/bnxt_sysctl.c
===================================================================
--- head/sys/dev/bnxt/bnxt_sysctl.c
+++ head/sys/dev/bnxt/bnxt_sysctl.c
@@ -549,6 +549,166 @@
return rc;
}
+static int
+bnxt_set_coal_rx_usecs(SYSCTL_HANDLER_ARGS) {
+ struct bnxt_softc *softc = arg1;
+ int rc;
+ int val;
+
+ if (softc == NULL)
+ return EBUSY;
+
+ val = softc->rx_coal_usecs;
+ rc = sysctl_handle_int(oidp, &val, 0, req);
+ if (rc || !req->newptr)
+ return rc;
+
+ softc->rx_coal_usecs = val;
+ rc = bnxt_hwrm_set_coal(softc);
+
+ return rc;
+}
+
+static int
+bnxt_set_coal_rx_frames(SYSCTL_HANDLER_ARGS) {
+ struct bnxt_softc *softc = arg1;
+ int rc;
+ int val;
+
+ if (softc == NULL)
+ return EBUSY;
+
+ val = softc->rx_coal_frames;
+ rc = sysctl_handle_int(oidp, &val, 0, req);
+ if (rc || !req->newptr)
+ return rc;
+
+ softc->rx_coal_frames = val;
+ rc = bnxt_hwrm_set_coal(softc);
+
+ return rc;
+}
+
+static int
+bnxt_set_coal_rx_usecs_irq(SYSCTL_HANDLER_ARGS) {
+ struct bnxt_softc *softc = arg1;
+ int rc;
+ int val;
+
+ if (softc == NULL)
+ return EBUSY;
+
+ val = softc->rx_coal_usecs_irq;
+ rc = sysctl_handle_int(oidp, &val, 0, req);
+ if (rc || !req->newptr)
+ return rc;
+
+ softc->rx_coal_usecs_irq = val;
+ rc = bnxt_hwrm_set_coal(softc);
+
+ return rc;
+}
+
+static int
+bnxt_set_coal_rx_frames_irq(SYSCTL_HANDLER_ARGS) {
+ struct bnxt_softc *softc = arg1;
+ int rc;
+ int val;
+
+ if (softc == NULL)
+ return EBUSY;
+
+ val = softc->rx_coal_frames_irq;
+ rc = sysctl_handle_int(oidp, &val, 0, req);
+ if (rc || !req->newptr)
+ return rc;
+
+ softc->rx_coal_frames_irq = val;
+ rc = bnxt_hwrm_set_coal(softc);
+
+ return rc;
+}
+
+static int
+bnxt_set_coal_tx_usecs(SYSCTL_HANDLER_ARGS) {
+ struct bnxt_softc *softc = arg1;
+ int rc;
+ int val;
+
+ if (softc == NULL)
+ return EBUSY;
+
+ val = softc->tx_coal_usecs;
+ rc = sysctl_handle_int(oidp, &val, 0, req);
+ if (rc || !req->newptr)
+ return rc;
+
+ softc->tx_coal_usecs = val;
+ rc = bnxt_hwrm_set_coal(softc);
+
+ return rc;
+}
+
+static int
+bnxt_set_coal_tx_frames(SYSCTL_HANDLER_ARGS) {
+ struct bnxt_softc *softc = arg1;
+ int rc;
+ int val;
+
+ if (softc == NULL)
+ return EBUSY;
+
+ val = softc->tx_coal_frames;
+ rc = sysctl_handle_int(oidp, &val, 0, req);
+ if (rc || !req->newptr)
+ return rc;
+
+ softc->tx_coal_frames = val;
+ rc = bnxt_hwrm_set_coal(softc);
+
+ return rc;
+}
+
+static int
+bnxt_set_coal_tx_usecs_irq(SYSCTL_HANDLER_ARGS) {
+ struct bnxt_softc *softc = arg1;
+ int rc;
+ int val;
+
+ if (softc == NULL)
+ return EBUSY;
+
+ val = softc->tx_coal_usecs_irq;
+ rc = sysctl_handle_int(oidp, &val, 0, req);
+ if (rc || !req->newptr)
+ return rc;
+
+ softc->tx_coal_usecs_irq = val;
+ rc = bnxt_hwrm_set_coal(softc);
+
+ return rc;
+}
+
+static int
+bnxt_set_coal_tx_frames_irq(SYSCTL_HANDLER_ARGS) {
+ struct bnxt_softc *softc = arg1;
+ int rc;
+ int val;
+
+ if (softc == NULL)
+ return EBUSY;
+
+ val = softc->tx_coal_frames_irq;
+ rc = sysctl_handle_int(oidp, &val, 0, req);
+ if (rc || !req->newptr)
+ return rc;
+
+ softc->tx_coal_frames_irq = val;
+ rc = bnxt_hwrm_set_coal(softc);
+
+ return rc;
+}
+
int
bnxt_create_config_sysctls_pre(struct bnxt_softc *softc)
{
@@ -571,6 +731,31 @@
"strip VLAN tag in the RX path");
SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "if_name", CTLFLAG_RD,
iflib_get_ifp(softc->ctx)->if_xname, 0, "interface name");
+
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_rx_usecs",
+ CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, bnxt_set_coal_rx_usecs,
+ "I", "interrupt coalescing Rx Usecs");
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_rx_frames",
+ CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, bnxt_set_coal_rx_frames,
+ "I", "interrupt coalescing Rx Frames");
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_rx_usecs_irq",
+ CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, bnxt_set_coal_rx_usecs_irq,
+ "I", "interrupt coalescing Rx Usecs IRQ");
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_rx_frames_irq",
+ CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, bnxt_set_coal_rx_frames_irq,
+ "I", "interrupt coalescing Rx Frames IRQ");
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_tx_usecs",
+ CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, bnxt_set_coal_tx_usecs,
+ "I", "interrupt coalescing Tx Usces");
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_tx_frames",
+ CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, bnxt_set_coal_tx_frames,
+ "I", "interrupt coalescing Tx Frames");
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_tx_usecs_irq",
+ CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, bnxt_set_coal_tx_usecs_irq,
+ "I", "interrupt coalescing Tx Usecs IRQ");
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_tx_frames_irq",
+ CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, bnxt_set_coal_tx_frames_irq,
+ "I", "interrupt coalescing Tx Frames IRQ");
return 0;
}
Index: head/sys/dev/bnxt/if_bnxt.c
===================================================================
--- head/sys/dev/bnxt/if_bnxt.c
+++ head/sys/dev/bnxt/if_bnxt.c
@@ -691,6 +691,12 @@
goto drv_rgtr_fail;
}
+ rc = bnxt_hwrm_func_rgtr_async_events(softc, NULL, 0);
+ if (rc) {
+ device_printf(softc->dev, "attach: hwrm rgtr async evts failed\n");
+ goto drv_rgtr_fail;
+ }
+
/* Get the HW capabilities */
rc = bnxt_hwrm_func_qcaps(softc);
if (rc)
@@ -2286,11 +2292,11 @@
HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)
flow_ctrl = "FC - receive";
else
- flow_ctrl = "none";
+ flow_ctrl = "FC - none";
iflib_link_state_change(softc->ctx, LINK_STATE_UP,
IF_Gbps(100));
- device_printf(softc->dev, "Link is UP %s, %s\n", duplex,
- flow_ctrl);
+ device_printf(softc->dev, "Link is UP %s, %s - %d Mbps \n", duplex,
+ flow_ctrl, (softc->link_info.link_speed * 100));
} else {
iflib_link_state_change(softc->ctx, LINK_STATE_DOWN,
bnxt_get_baudrate(&softc->link_info));
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 6, 1:37 PM (15 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30973267
Default Alt Text
D11702.diff (13 KB)
Attached To
Mode
D11702: bnxt: Implement interrupt coalescing options using sysctl.
Attached
Detach File
Event Timeline
Log In to Comment