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];
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to