/* * Initialize the software state of the iSCSI ULP driver. * * ENXIO means firmware didn't set up something that it was supposed to. */ static int cxgbei_init(struct adapter *sc, struct cxgbei_data *ci) { struct sysctl_oid *oid; struct sysctl_oid_list *children; struct ppod_region *pr; uint32_t r; int rc; MPASS(sc->vres.iscsi.size > 0); MPASS(ci != NULL); rc = alloc_ci_counters(ci); if (rc != 0) return (rc); read_pdu_limits(sc, &ci->max_tx_pdu_len, &ci->max_rx_pdu_len); pr = &ci->pr; r = t4_read_reg(sc, A_ULP_RX_ISCSI_PSZ); rc = t4_init_ppod_region(pr, &sc->vres.iscsi, r, "iSCSI page pods"); if (rc != 0) { device_printf(sc->dev, "%s: failed to initialize the iSCSI page pod region: %u.\n", __func__, rc); free_ci_counters(ci); return (rc); } r = t4_read_reg(sc, A_ULP_RX_ISCSI_TAGMASK); r &= V_ISCSITAGMASK(M_ISCSITAGMASK); if (r != pr->pr_tag_mask) { /* * Recent firmwares are supposed to set up the iSCSI tagmask * but we'll do it ourselves it the computed value doesn't match * what's in the register. */ device_printf(sc->dev, "tagmask 0x%08x does not match computed mask 0x%08x.\n", r, pr->pr_tag_mask); t4_set_reg_field(sc, A_ULP_RX_ISCSI_TAGMASK, V_ISCSITAGMASK(M_ISCSITAGMASK), pr->pr_tag_mask); } sysctl_ctx_init(&ci->ctx); oid = device_get_sysctl_tree(sc->dev); /* dev.t5nex.X */ children = SYSCTL_CHILDREN(oid); oid = SYSCTL_ADD_NODE(&ci->ctx, children, OID_AUTO, "iscsi", CTLFLAG_RD, NULL, "iSCSI ULP statistics"); children = SYSCTL_CHILDREN(oid); SYSCTL_ADD_COUNTER_U64(&ci->ctx, children, OID_AUTO, "ddp_setup_ok", CTLFLAG_RD, &ci->ddp_setup_ok, "# of times DDP buffer was setup successfully."); SYSCTL_ADD_COUNTER_U64(&ci->ctx, children, OID_AUTO, "ddp_setup_error", CTLFLAG_RD, &ci->ddp_setup_error, "# of times DDP buffer setup failed."); SYSCTL_ADD_COUNTER_U64(&ci->ctx, children, OID_AUTO, "ddp_bytes", CTLFLAG_RD, &ci->ddp_bytes, "# of bytes placed directly"); SYSCTL_ADD_COUNTER_U64(&ci->ctx, children, OID_AUTO, "ddp_pdus", CTLFLAG_RD, &ci->ddp_pdus, "# of PDUs with data placed directly."); SYSCTL_ADD_COUNTER_U64(&ci->ctx, children, OID_AUTO, "fl_bytes", CTLFLAG_RD, &ci->fl_bytes, "# of data bytes delivered in freelist"); SYSCTL_ADD_COUNTER_U64(&ci->ctx, children, OID_AUTO, "fl_pdus", CTLFLAG_RD, &ci->fl_pdus, "# of PDUs with data delivered in freelist"); ci->ddp_threshold = 2048; SYSCTL_ADD_UINT(&ci->ctx, children, OID_AUTO, "ddp_threshold", CTLFLAG_RW, &ci->ddp_threshold, 0, "Rx zero copy threshold"); return (0); }
int t4_set_tracer(struct adapter *sc, struct t4_tracer *t) { int rc; struct trace_params tp, *tpp; if (t->idx >= NTRACE) return (EINVAL); rc = begin_synchronized_op(sc, NULL, HOLD_LOCK | SLEEP_OK | INTR_OK, "t4sett"); if (rc) return (rc); /* * If no tracing filter is specified this time then check if the filter * at the index is valid anyway because it was set previously. If so * then this is a legitimate enable/disable operation. */ if (t->valid == 0) { if (isset(&sc->tracer_valid, t->idx)) tpp = NULL; else rc = EINVAL; goto done; } if (t->tp.port > 19 || t->tp.snap_len > 9600 || t->tp.min_len > M_TFMINPKTSIZE || t->tp.skip_len > M_TFLENGTH || t->tp.skip_ofst > M_TFOFFSET) { rc = EINVAL; goto done; } memcpy(&tp.data[0], &t->tp.data[0], sizeof(tp.data)); memcpy(&tp.mask[0], &t->tp.mask[0], sizeof(tp.mask)); tp.snap_len = t->tp.snap_len; tp.min_len = t->tp.min_len; tp.skip_ofst = t->tp.skip_ofst; tp.skip_len = t->tp.skip_len; tp.invert = !!t->tp.invert; /* convert port to channel iff 0 <= port < 8. */ if (t->tp.port < 4) { if (sc->port[t->tp.port] == NULL) { rc = EINVAL; goto done; } tp.port = sc->port[t->tp.port]->tx_chan; } else if (t->tp.port < 8) { if (sc->port[t->tp.port - 4] == NULL) { rc = EINVAL; goto done; } tp.port = sc->port[t->tp.port - 4]->tx_chan + 4; } tpp = &tp; done: if (rc == 0) { rc = -t4_set_trace_filter(sc, tpp, t->idx, t->enabled); if (rc == 0) { if (t->enabled) { setbit(&sc->tracer_valid, t->idx); if (sc->tracer_enabled == 0) { t4_set_reg_field(sc, A_MPS_TRC_CFG, F_TRCEN, F_TRCEN); } setbit(&sc->tracer_enabled, t->idx); } else { clrbit(&sc->tracer_enabled, t->idx); if (sc->tracer_enabled == 0) { t4_set_reg_field(sc, A_MPS_TRC_CFG, F_TRCEN, 0); } } } } end_synchronized_op(sc, LOCK_HELD); return (rc); }