Beispiel #1
0
/* Link bring up */
static void
ntb_transport_link_work(void *arg)
{
	struct ntb_netdev *nt = arg;
	struct ntb_softc *ntb = nt->ntb;
	struct ntb_transport_qp *qp;
	uint32_t val;
	int rc, i;

	/* send the local info */
	rc = ntb_write_remote_spad(ntb, IF_NTB_VERSION, NTB_TRANSPORT_VERSION);
	if (rc != 0)
		goto out;

	rc = ntb_write_remote_spad(ntb, IF_NTB_MW0_SZ, ntb_get_mw_size(ntb, 0));
	if (rc != 0)
		goto out;

	rc = ntb_write_remote_spad(ntb, IF_NTB_MW1_SZ, ntb_get_mw_size(ntb, 1));
	if (rc != 0)
		goto out;

	rc = ntb_write_remote_spad(ntb, IF_NTB_NUM_QPS, nt->max_qps);
	if (rc != 0)
		goto out;

	rc = ntb_read_remote_spad(ntb, IF_NTB_QP_LINKS, &val);
	if (rc != 0)
		goto out;

	rc = ntb_write_remote_spad(ntb, IF_NTB_QP_LINKS, val);
	if (rc != 0)
		goto out;

	/* Query the remote side for its info */
	rc = ntb_read_local_spad(ntb, IF_NTB_VERSION, &val);
	if (rc != 0)
		goto out;

	if (val != NTB_TRANSPORT_VERSION)
		goto out;

	rc = ntb_read_local_spad(ntb, IF_NTB_NUM_QPS, &val);
	if (rc != 0)
		goto out;

	if (val != nt->max_qps)
		goto out;

	rc = ntb_read_local_spad(ntb, IF_NTB_MW0_SZ, &val);
	if (rc != 0)
		goto out;

	if (val == 0)
		goto out;

	rc = ntb_set_mw(nt, 0, val);
	if (rc != 0)
		return;

	rc = ntb_read_local_spad(ntb, IF_NTB_MW1_SZ, &val);
	if (rc != 0)
		goto out;

	if (val == 0)
		goto out;

	rc = ntb_set_mw(nt, 1, val);
	if (rc != 0)
		return;

	nt->transport_link = NTB_LINK_UP;
	if (bootverbose)
		device_printf(ntb_get_device(ntb), "transport link up\n");

	for (i = 0; i < nt->max_qps; i++) {
		qp = &nt->qps[i];

		ntb_transport_setup_qp_mw(nt, i);

		if (qp->client_ready == NTB_LINK_UP)
			callout_reset(&qp->link_work, 0, ntb_qp_link_work, qp);
	}

	return;

out:
	if (ntb_query_link_status(ntb))
		callout_reset(&nt->link_work,
				      NTB_LINK_DOWN_TIMEOUT * hz / 1000, ntb_transport_link_work, nt);
}
Beispiel #2
0
/* Link bring up */
static void
ntb_transport_link_work(void *arg)
{
	struct ntb_transport_ctx *nt = arg;
	struct ntb_softc *ntb = nt->ntb;
	struct ntb_transport_qp *qp;
	uint64_t val64, size;
	uint32_t val;
	unsigned i;
	int rc;

	/* send the local info, in the opposite order of the way we read it */
	for (i = 0; i < nt->mw_count; i++) {
		size = nt->mw_vec[i].phys_size;

		if (max_mw_size != 0 && size > max_mw_size)
			size = max_mw_size;

		ntb_peer_spad_write(ntb, IF_NTB_MW0_SZ_HIGH + (i * 2),
		    size >> 32);
		ntb_peer_spad_write(ntb, IF_NTB_MW0_SZ_LOW + (i * 2), size);
	}

	ntb_peer_spad_write(ntb, IF_NTB_NUM_MWS, nt->mw_count);

	ntb_peer_spad_write(ntb, IF_NTB_NUM_QPS, nt->qp_count);

	ntb_peer_spad_write(ntb, IF_NTB_VERSION, NTB_TRANSPORT_VERSION);

	/* Query the remote side for its info */
	val = 0;
	ntb_spad_read(ntb, IF_NTB_VERSION, &val);
	if (val != NTB_TRANSPORT_VERSION)
		goto out;

	ntb_spad_read(ntb, IF_NTB_NUM_QPS, &val);
	if (val != nt->qp_count)
		goto out;

	ntb_spad_read(ntb, IF_NTB_NUM_MWS, &val);
	if (val != nt->mw_count)
		goto out;

	for (i = 0; i < nt->mw_count; i++) {
		ntb_spad_read(ntb, IF_NTB_MW0_SZ_HIGH + (i * 2), &val);
		val64 = (uint64_t)val << 32;

		ntb_spad_read(ntb, IF_NTB_MW0_SZ_LOW + (i * 2), &val);
		val64 |= val;

		rc = ntb_set_mw(nt, i, val64);
		if (rc != 0)
			goto free_mws;
	}

	nt->link_is_up = true;
	ntb_printf(1, "transport link up\n");

	for (i = 0; i < nt->qp_count; i++) {
		qp = &nt->qp_vec[i];

		ntb_transport_setup_qp_mw(nt, i);

		if (qp->client_ready)
			callout_reset(&qp->link_work, 0, ntb_qp_link_work, qp);
	}

	return;

free_mws:
	for (i = 0; i < nt->mw_count; i++)
		ntb_free_mw(nt, i);
out:
	if (ntb_link_is_up(ntb, NULL, NULL))
		callout_reset(&nt->link_work,
		    NTB_LINK_DOWN_TIMEOUT * hz / 1000, ntb_transport_link_work, nt);
}