From ee15dbebf7938e261a747709dd62966816ba479a Mon Sep 17 00:00:00 2001
From: Vidush <vidush.vishwanath@ettus.com>
Date: Mon, 16 Jul 2018 17:14:37 -0700
Subject: B200: Fix SC8 RX Streaming

Coerces recv_frame_size to size of words (8 bytes) to prevent
USB_TRANSFER_OVERFLOW error.
---
 host/lib/usrp/b200/b200_impl.cpp | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

(limited to 'host/lib/usrp/b200')

diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index a034ef632..239bd97b1 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -536,18 +536,27 @@ b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::s
             << " is too large. It will be set to "
             << B200_USB_DATA_MAX_RECV_FRAME_SIZE << ".";
         recv_frame_size = B200_USB_DATA_MAX_RECV_FRAME_SIZE;
-    } else if (recv_frame_size % max_transfer == 0) {
+    } else if (recv_frame_size % max_transfer == 0 or recv_frame_size % 8 != 0) {
         // The Cypress FX3 does not properly handle recv_frame_sizes that are
-        // aligned to the maximum transfer size.  The code below coerces the
-        // recv_frame_size down to a value that is not a multiple of of the
-        // maximum transfer size and aligns to full 8 byte words for sc8, sc12,
-        // and sc16 data types for best performance on the FPGA.
-        recv_frame_size = (((recv_frame_size - 16) / 24) * 24) + 16;
+        // aligned to the maximum transfer size and the FPGA code requires the
+        // data to be aligned to 8 byte words.  The code below coerces the
+        // recv_frame_size to a value that is a multiple of 8 bytes, not
+        // a multiple of the maximum transfer size, and aligned to 24 bytes
+        // to support full 8 byte word alignment for sc8, sc12, and sc16 data
+        // types.
+
+        // Align to 8 byte words
+        recv_frame_size += 8 - (recv_frame_size % 8);
+        if (recv_frame_size % max_transfer == 0) {
+            recv_frame_size = (((recv_frame_size - 16) / 24) * 24) + 16;
+        }
         UHD_LOGGER_WARNING("B200")
-            << "Multiples of 512 not supported for recv_frame_size. "
-            << "Requested recv_frame_size of " << device_addr["recv_frame_size"]
-            << " reduced to " << recv_frame_size << ".";
+            << "The recv_frame_size must be a multiple of 8 bytes and not a multiple of "
+            << max_transfer << " bytes.  Requested recv_frame_size of "
+            << device_addr["recv_frame_size"]
+            << " coerced to " << recv_frame_size << ".";
     }
+
     data_xport_args["recv_frame_size"] = std::to_string(recv_frame_size);
     data_xport_args["num_recv_frames"] = device_addr.get("num_recv_frames", "16");
     data_xport_args["send_frame_size"] = device_addr.get("send_frame_size", std::to_string(B200_USB_DATA_DEFAULT_FRAME_SIZE));
-- 
cgit v1.2.3