svn commit: r289153 - head/sys/dev/ntb/if_ntb

Conrad E. Meyer cem at FreeBSD.org
Sun Oct 11 20:58:01 UTC 2015


Author: cem
Date: Sun Oct 11 20:58:00 2015
New Revision: 289153
URL: https://svnweb.freebsd.org/changeset/base/289153

Log:
  NTB: MFV 113fc505: Handle 64bit BAR sizes
  
  64bit BAR sizes are permissible with an NTB device.  To support them
  various modifications and clean-ups were required, most significantly
  using 2 32bit scratch pad registers for each BAR.
  
  Also, modify the driver to allow more than 2 Memory Windows.
  
  Authored by:	Jon Mason
  Obtained from:	Linux
  Sponsored by:	EMC / Isilon Storage Division

Modified:
  head/sys/dev/ntb/if_ntb/if_ntb.c

Modified: head/sys/dev/ntb/if_ntb/if_ntb.c
==============================================================================
--- head/sys/dev/ntb/if_ntb/if_ntb.c	Sun Oct 11 20:57:09 2015	(r289152)
+++ head/sys/dev/ntb/if_ntb/if_ntb.c	Sun Oct 11 20:58:00 2015	(r289153)
@@ -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 
 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);
-	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);
+	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, 1, 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;
+
+		val64 = (uint64_t)val << 32;
+
+		rc = ntb_read_local_spad(ntb, IF_NTB_MW0_SZ_LOW + (i * 2),
+		    &val);
+		if (rc != 0)
+			goto free_mws;
+
+		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 nu
 }
 
 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];


More information about the svn-src-all mailing list