Exemple #1
0
/**
 *      t4vf_fw_reset - issue a reset to FW
 *      @adapter: the adapter
 *
 *	Issues a reset command to FW.  For a Physical Function this would
 *	result in the Firmware reseting all of its state.  For a Virtual
 *	Function this just resets the state associated with the VF.
 */
int t4vf_fw_reset(struct adapter *adapter)
{
    struct fw_reset_cmd cmd;

    memset(&cmd, 0, sizeof(cmd));
    cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RESET_CMD) |
                                  F_FW_CMD_WRITE);
    cmd.retval_len16 = cpu_to_be32(V_FW_CMD_LEN16(FW_LEN16(cmd)));
    return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
}
Exemple #2
0
static int
alloc_nm_txq_hwq(struct port_info *pi, struct sge_nm_txq *nm_txq)
{
	int rc, cntxt_id;
	size_t len;
	struct adapter *sc = pi->adapter;
	struct netmap_adapter *na = NA(pi->nm_ifp);
	struct fw_eq_eth_cmd c;

	MPASS(na != NULL);
	MPASS(nm_txq->desc != NULL);

	len = na->num_tx_desc * EQ_ESIZE + spg_len;
	bzero(nm_txq->desc, len);

	bzero(&c, sizeof(c));
	c.op_to_vfn = htobe32(V_FW_CMD_OP(FW_EQ_ETH_CMD) | F_FW_CMD_REQUEST |
	    F_FW_CMD_WRITE | F_FW_CMD_EXEC | V_FW_EQ_ETH_CMD_PFN(sc->pf) |
	    V_FW_EQ_ETH_CMD_VFN(0));
	c.alloc_to_len16 = htobe32(F_FW_EQ_ETH_CMD_ALLOC |
	    F_FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c));
	c.autoequiqe_to_viid = htobe32(V_FW_EQ_ETH_CMD_VIID(pi->nm_viid));
	c.fetchszm_to_iqid =
	    htobe32(V_FW_EQ_ETH_CMD_HOSTFCMODE(X_HOSTFCMODE_NONE) |
		V_FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) | F_FW_EQ_ETH_CMD_FETCHRO |
		V_FW_EQ_ETH_CMD_IQID(sc->sge.nm_rxq[nm_txq->iqidx].iq_cntxt_id));
	c.dcaen_to_eqsize = htobe32(V_FW_EQ_ETH_CMD_FBMIN(X_FETCHBURSTMIN_64B) |
		      V_FW_EQ_ETH_CMD_FBMAX(X_FETCHBURSTMAX_512B) |
		      V_FW_EQ_ETH_CMD_EQSIZE(len / EQ_ESIZE));
	c.eqaddr = htobe64(nm_txq->ba);

	rc = -t4_wr_mbox(sc, sc->mbox, &c, sizeof(c), &c);
	if (rc != 0) {
		device_printf(pi->dev,
		    "failed to create netmap egress queue: %d\n", rc);
		return (rc);
	}

	nm_txq->cntxt_id = G_FW_EQ_ETH_CMD_EQID(be32toh(c.eqid_pkd));
	cntxt_id = nm_txq->cntxt_id - sc->sge.eq_start;
	if (cntxt_id >= sc->sge.neq)
	    panic("%s: nm_txq->cntxt_id (%d) more than the max (%d)", __func__,
		cntxt_id, sc->sge.neq - 1);
	sc->sge.eqmap[cntxt_id] = (void *)nm_txq;

	nm_txq->pidx = nm_txq->cidx = 0;
	MPASS(nm_txq->sidx == na->num_tx_desc);
	nm_txq->equiqidx = nm_txq-> equeqidx = nm_txq->dbidx = 0;

	nm_txq->doorbells = sc->doorbells;
	if (isset(&nm_txq->doorbells, DOORBELL_UDB) ||
	    isset(&nm_txq->doorbells, DOORBELL_UDBWC) ||
	    isset(&nm_txq->doorbells, DOORBELL_WCWR)) {
		uint32_t s_qpp = sc->sge.eq_s_qpp;
		uint32_t mask = (1 << s_qpp) - 1;
		volatile uint8_t *udb;

		udb = sc->udbs_base + UDBS_DB_OFFSET;
		udb += (nm_txq->cntxt_id >> s_qpp) << PAGE_SHIFT;
		nm_txq->udb_qid = nm_txq->cntxt_id & mask;
		if (nm_txq->udb_qid >= PAGE_SIZE / UDBS_SEG_SIZE)
	    		clrbit(&nm_txq->doorbells, DOORBELL_WCWR);
		else {
			udb += nm_txq->udb_qid << UDBS_SEG_SHIFT;
			nm_txq->udb_qid = 0;
		}
		nm_txq->udb = (volatile void *)udb;
	}
Exemple #3
0
static int
alloc_nm_rxq_hwq(struct port_info *pi, struct sge_nm_rxq *nm_rxq)
{
	int rc, cntxt_id;
	__be32 v;
	struct adapter *sc = pi->adapter;
	struct netmap_adapter *na = NA(pi->nm_ifp);
	struct fw_iq_cmd c;

	MPASS(na != NULL);
	MPASS(nm_rxq->iq_desc != NULL);
	MPASS(nm_rxq->fl_desc != NULL);

	bzero(nm_rxq->iq_desc, pi->qsize_rxq * IQ_ESIZE);
	bzero(nm_rxq->fl_desc, na->num_rx_desc * EQ_ESIZE + spg_len);

	bzero(&c, sizeof(c));
	c.op_to_vfn = htobe32(V_FW_CMD_OP(FW_IQ_CMD) | F_FW_CMD_REQUEST |
	    F_FW_CMD_WRITE | F_FW_CMD_EXEC | V_FW_IQ_CMD_PFN(sc->pf) |
	    V_FW_IQ_CMD_VFN(0));
	c.alloc_to_len16 = htobe32(F_FW_IQ_CMD_ALLOC | F_FW_IQ_CMD_IQSTART |
	    FW_LEN16(c));
	if (pi->flags & INTR_NM_RXQ) {
		KASSERT(nm_rxq->intr_idx < sc->intr_count,
		    ("%s: invalid direct intr_idx %d", __func__,
		    nm_rxq->intr_idx));
		v = V_FW_IQ_CMD_IQANDSTINDEX(nm_rxq->intr_idx);
	} else {
		CXGBE_UNIMPLEMENTED(__func__);	/* XXXNM: needs review */
		v = V_FW_IQ_CMD_IQANDSTINDEX(nm_rxq->intr_idx) |
		    F_FW_IQ_CMD_IQANDST;
	}
	c.type_to_iqandstindex = htobe32(v |
	    V_FW_IQ_CMD_TYPE(FW_IQ_TYPE_FL_INT_CAP) |
	    V_FW_IQ_CMD_VIID(pi->nm_viid) |
	    V_FW_IQ_CMD_IQANUD(X_UPDATEDELIVERY_INTERRUPT));
	c.iqdroprss_to_iqesize = htobe16(V_FW_IQ_CMD_IQPCIECH(pi->tx_chan) |
	    F_FW_IQ_CMD_IQGTSMODE |
	    V_FW_IQ_CMD_IQINTCNTTHRESH(0) |
	    V_FW_IQ_CMD_IQESIZE(ilog2(IQ_ESIZE) - 4));
	c.iqsize = htobe16(pi->qsize_rxq);
	c.iqaddr = htobe64(nm_rxq->iq_ba);
	c.iqns_to_fl0congen |=
	    htobe32(V_FW_IQ_CMD_FL0HOSTFCMODE(X_HOSTFCMODE_NONE) |
		F_FW_IQ_CMD_FL0FETCHRO | F_FW_IQ_CMD_FL0DATARO |
		(fl_pad ? F_FW_IQ_CMD_FL0PADEN : 0));
	c.fl0dcaen_to_fl0cidxfthresh =
	    htobe16(V_FW_IQ_CMD_FL0FBMIN(X_FETCHBURSTMIN_64B) |
		V_FW_IQ_CMD_FL0FBMAX(X_FETCHBURSTMAX_512B));
	c.fl0size = htobe16(na->num_rx_desc + spg_len / EQ_ESIZE);
	c.fl0addr = htobe64(nm_rxq->fl_ba);

	rc = -t4_wr_mbox(sc, sc->mbox, &c, sizeof(c), &c);
	if (rc != 0) {
		device_printf(sc->dev,
		    "failed to create netmap ingress queue: %d\n", rc);
		return (rc);
	}

	nm_rxq->iq_cidx = 0;
	MPASS(nm_rxq->iq_sidx == pi->qsize_rxq - spg_len / IQ_ESIZE);
	nm_rxq->iq_gen = F_RSPD_GEN;
	nm_rxq->iq_cntxt_id = be16toh(c.iqid);
	nm_rxq->iq_abs_id = be16toh(c.physiqid);
	cntxt_id = nm_rxq->iq_cntxt_id - sc->sge.iq_start;
	if (cntxt_id >= sc->sge.niq) {
		panic ("%s: nm_rxq->iq_cntxt_id (%d) more than the max (%d)",
		    __func__, cntxt_id, sc->sge.niq - 1);
	}
	sc->sge.iqmap[cntxt_id] = (void *)nm_rxq;

	nm_rxq->fl_cntxt_id = be16toh(c.fl0id);
	nm_rxq->fl_pidx = nm_rxq->fl_cidx = 0;
	MPASS(nm_rxq->fl_sidx == na->num_rx_desc);
	cntxt_id = nm_rxq->fl_cntxt_id - sc->sge.eq_start;
	if (cntxt_id >= sc->sge.neq) {
		panic("%s: nm_rxq->fl_cntxt_id (%d) more than the max (%d)",
		    __func__, cntxt_id, sc->sge.neq - 1);
	}
	sc->sge.eqmap[cntxt_id] = (void *)nm_rxq;

	nm_rxq->fl_db_val = F_DBPRIO | V_QID(nm_rxq->fl_cntxt_id) | V_PIDX(0);
	if (is_t5(sc))
		nm_rxq->fl_db_val |= F_DBTYPE;

	t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), V_SEINTARM(F_QINTR_CNT_EN) |
	    V_INGRESSQID(nm_rxq->iq_cntxt_id));

	return (rc);
}