summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2015-10-11 20:58:00 +0000
committerConrad Meyer <cem@FreeBSD.org>2015-10-11 20:58:00 +0000
commit92bbfa507cdd85ccd02726f918f3fa335d105c01 (patch)
tree4b1370509f61fa7bdcc593efb974df6072fcad29 /sys
parent262d9f674f4271057ddbc6307b824e9fa77bbd8b (diff)
downloadsrc-test-92bbfa507cdd85ccd02726f918f3fa335d105c01.tar.gz
src-test-92bbfa507cdd85ccd02726f918f3fa335d105c01.zip
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ntb/if_ntb/if_ntb.c99
1 files changed, 65 insertions, 34 deletions
diff --git a/sys/dev/ntb/if_ntb/if_ntb.c b/sys/dev/ntb/if_ntb/if_ntb.c
index 1bc8c1535a2ee..101691d0bf0f8 100644
--- a/sys/dev/ntb/if_ntb/if_ntb.c
+++ b/sys/dev/ntb/if_ntb/if_ntb.c
@@ -194,11 +194,22 @@ struct ntb_payload_header {
};
enum {
+ /*
+ * The order of this enum is part of the if_ntb remote protocol. Do
+ * not reorder without bumping protocol version (and it's probably best
+ * to keep the protocol in lock-step with the Linux NTB driver.
+ */
IF_NTB_VERSION = 0,
- IF_NTB_MW0_SZ,
- IF_NTB_MW1_SZ,
- IF_NTB_NUM_QPS,
IF_NTB_QP_LINKS,
+ IF_NTB_NUM_QPS,
+ IF_NTB_NUM_MWS,
+ /*
+ * N.B.: transport_link_work assumes MW1 enums = MW0 + 2.
+ */
+ IF_NTB_MW0_SZ_HIGH,
+ IF_NTB_MW0_SZ_LOW,
+ IF_NTB_MW1_SZ_HIGH,
+ IF_NTB_MW1_SZ_LOW,
IF_NTB_MAX_SPAD,
};
@@ -242,6 +253,7 @@ static void ntb_rx_completion_task(void *arg, int pending);
static void ntb_transport_event_callback(void *data, enum ntb_hw_event event);
static void ntb_transport_link_work(void *arg);
static int ntb_set_mw(struct ntb_netdev *nt, int num_mw, unsigned int size);
+static void ntb_free_mw(struct ntb_netdev *nt, int num_mw);
static void ntb_transport_setup_qp_mw(struct ntb_netdev *nt,
unsigned int qp_num);
static void ntb_qp_link_work(void *arg);
@@ -514,9 +526,7 @@ ntb_transport_free(void *transport)
ntb_unregister_event_callback(ntb);
for (i = 0; i < NTB_NUM_MW; i++)
- if (nt->mw[i].virt_addr != NULL)
- contigfree(nt->mw[i].virt_addr, nt->mw[i].size,
- M_NTB_IF);
+ ntb_free_mw(nt, i);
free(nt->qps, M_NTB_IF);
ntb_unregister_transport(ntb);
@@ -1019,19 +1029,24 @@ ntb_transport_link_work(void *arg)
struct ntb_netdev *nt = arg;
struct ntb_softc *ntb = nt->ntb;
struct ntb_transport_qp *qp;
+ uint64_t val64;
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;
+ /* send the local info, in the opposite order of the way we read it */
+ for (i = 0; i < NTB_NUM_MW; i++) {
+ rc = ntb_write_remote_spad(ntb, IF_NTB_MW0_SZ_HIGH + (i * 2),
+ ntb_get_mw_size(ntb, i) >> 32);
+ if (rc != 0)
+ goto out;
+
+ rc = ntb_write_remote_spad(ntb, IF_NTB_MW0_SZ_LOW + (i * 2),
+ (uint32_t)ntb_get_mw_size(ntb, i));
+ if (rc != 0)
+ goto out;
+ }
- rc = ntb_write_remote_spad(ntb, IF_NTB_MW1_SZ, ntb_get_mw_size(ntb, 1));
+ rc = ntb_write_remote_spad(ntb, IF_NTB_NUM_MWS, NTB_NUM_MW);
if (rc != 0)
goto out;
@@ -1039,11 +1054,7 @@ ntb_transport_link_work(void *arg)
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);
+ rc = ntb_write_remote_spad(ntb, IF_NTB_VERSION, NTB_TRANSPORT_VERSION);
if (rc != 0)
goto out;
@@ -1062,27 +1073,32 @@ ntb_transport_link_work(void *arg)
if (val != nt->max_qps)
goto out;
- rc = ntb_read_local_spad(ntb, IF_NTB_MW0_SZ, &val);
+ rc = ntb_read_local_spad(ntb, IF_NTB_NUM_MWS, &val);
if (rc != 0)
goto out;
- if (val == 0)
+ if (val != NTB_NUM_MW)
goto out;
- rc = ntb_set_mw(nt, 0, val);
- if (rc != 0)
- return;
+ for (i = 0; i < NTB_NUM_MW; i++) {
+ rc = ntb_read_local_spad(ntb, IF_NTB_MW0_SZ_HIGH + (i * 2),
+ &val);
+ if (rc != 0)
+ goto free_mws;
- rc = ntb_read_local_spad(ntb, IF_NTB_MW1_SZ, &val);
- if (rc != 0)
- goto out;
+ val64 = (uint64_t)val << 32;
- if (val == 0)
- goto out;
+ rc = ntb_read_local_spad(ntb, IF_NTB_MW0_SZ_LOW + (i * 2),
+ &val);
+ if (rc != 0)
+ goto free_mws;
- rc = ntb_set_mw(nt, 1, val);
- if (rc != 0)
- return;
+ val64 |= val;
+
+ rc = ntb_set_mw(nt, i, val64);
+ if (rc != 0)
+ goto free_mws;
+ }
nt->transport_link = NTB_LINK_UP;
if (bootverbose)
@@ -1099,10 +1115,13 @@ ntb_transport_link_work(void *arg)
return;
+free_mws:
+ for (i = 0; i < NTB_NUM_MW; i++)
+ ntb_free_mw(nt, i);
out:
if (ntb_query_link_status(ntb))
callout_reset(&nt->link_work,
- NTB_LINK_DOWN_TIMEOUT * hz / 1000, ntb_transport_link_work, nt);
+ NTB_LINK_DOWN_TIMEOUT * hz / 1000, ntb_transport_link_work, nt);
}
static int
@@ -1130,6 +1149,18 @@ ntb_set_mw(struct ntb_netdev *nt, int num_mw, unsigned int size)
}
static void
+ntb_free_mw(struct ntb_netdev *nt, int num_mw)
+{
+ struct ntb_transport_mw *mw = &nt->mw[num_mw];
+
+ if (mw->virt_addr == NULL)
+ return;
+
+ contigfree(mw->virt_addr, mw->size, M_NTB_IF);
+ mw->virt_addr = NULL;
+}
+
+static void
ntb_transport_setup_qp_mw(struct ntb_netdev *nt, unsigned int qp_num)
{
struct ntb_transport_qp *qp = &nt->qps[qp_num];