diff options
author | Martin Braun <martin.braun@ettus.com> | 2017-07-27 14:38:07 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2017-12-22 15:04:00 -0800 |
commit | ef6382c6ab869d19fd29191768d5a748343c2b69 (patch) | |
tree | 59c97f3ba70d959aaef1b3669d5eff1c2b3f27fb /mpm/python/n3xx_bist | |
parent | 39bd5b1bad753c3634f09f023c37feb557924d51 (diff) | |
download | uhd-ef6382c6ab869d19fd29191768d5a748343c2b69.tar.gz uhd-ef6382c6ab869d19fd29191768d5a748343c2b69.tar.bz2 uhd-ef6382c6ab869d19fd29191768d5a748343c2b69.zip |
n3xx bist: Added SFP loopback tests
Diffstat (limited to 'mpm/python/n3xx_bist')
-rwxr-xr-x | mpm/python/n3xx_bist | 129 |
1 files changed, 114 insertions, 15 deletions
diff --git a/mpm/python/n3xx_bist b/mpm/python/n3xx_bist index a6740b51a..e7a7d41e6 100755 --- a/mpm/python/n3xx_bist +++ b/mpm/python/n3xx_bist @@ -29,6 +29,55 @@ from datetime import datetime import argparse import pyudev +############################################################################## +# Aurora/SFP BIST code +############################################################################## +def get_sfp_bist_defaults(): + " Default dictionary for SFP/Aurora BIST dry-runs " + return { + 'elapsed_time': 1.0, + 'max_roundtrip_latency': 0.8e-6, + 'throughput': 1000e6, + 'max_ber': 8.5e-11, + 'errors': 0, + 'bits': 12012486656, + } + +def run_aurora_bist(master, slave=None): + """ + Spawn a BER test + """ + from usrp_mpm import aurora_control + from usrp_mpm.uio import UIO + master_au_ctrl = aurora_control.AuroraControl( + UIO(label=master, read_only=False), + ) + slave_au_ctrl = None if slave is None else aurora_control.AuroraControl( + UIO(label=slave, read_only=False), + ) + return master_au_ctrl.run_ber_loopback_bist( + duration=10, + requested_rate=1300 * 8e6, + slave=slave_au_ctrl, + ) + +def aurora_results_to_status(bist_results): + """ + Convert a dictionary coming from AuroraControl BIST to one that we can use + for this BIST + """ + return bist_results['mst_errors'] == 0, { + 'elapsed_time': bist_results['time_elapsed'], + 'max_roundtrip_latency': bist_results['mst_latency_us'], + 'throughput': bist_results['approx_throughput'], + 'max_ber': bist_results['max_ber'], + 'errors': bist_results['mst_errors'], + 'bits': bist_results['mst_samps'], + } + +############################################################################## +# Helpers +############################################################################## def post_results(results): """ Given a dictionary, post the results. @@ -42,7 +91,9 @@ def post_results(results): separators=(',', ': ') )) - +############################################################################## +# Bist class +############################################################################## class N310BIST(object): """ BIST Tool for the USRP N3xx series @@ -82,6 +133,12 @@ class N310BIST(object): self.tests_to_run.add(test) else: self.tests_to_run.add(test) + try: + # Keep this import here so we can do dry-runs without any MPM code + from usrp_mpm import get_main_logger + self.log = get_main_logger().getChild('main') + except ImportError: + pass def expand_collection(self, coll): """ @@ -120,6 +177,7 @@ class N310BIST(object): sys.stderr.write("Test not defined: {}\n".format(testname)) return False, {} except Exception as ex: + raise sys.stderr.write( "Test {} failed to execute: {}\n".format(testname, str(ex)) ) @@ -312,13 +370,13 @@ class N310BIST(object): sys.stderr.write("Test not implemented.\n") return True, {} - def bist_sfp(self): + def bist_sfp0_loopback(self): """ BIST for SFP+ ports: Description: Uses one SFP+ port to test the other. Pipes data out through one SFP, back to the other. - External Equipment: External loopback cable between SFP+ port 0 and 1 is + External Equipment: Loopback module in SFP0 required required. Return dictionary: @@ -329,19 +387,57 @@ class N310BIST(object): - errors: Number of errors - bits: Number of bits that were transferred """ - assert 'sfp' in self.tests_to_run if self.args.dry_run: - return True, { - 'elapsed_time': 1.0, - 'max_roundtrip_latency': 0.8e-6, - 'throughput': 1000e6, - 'max_ber': 8.5e-11, - 'errors': 0, - 'bits': 12012486656, - } - # FIXME implement - sys.stderr.write("Test not implemented.\n") - return True, {} + return True, get_sfp_bist_defaults() + sfp_bist_results = run_aurora_bist(master='misc-enet-regs0') + return aurora_results_to_status(sfp_bist_results) + + def bist_sfp1_loopback(self): + """ + BIST for SFP+ ports: + Description: Uses one SFP+ port to test the other. Pipes data out + through one SFP, back to the other. + + External Equipment: Loopback module in SFP1 required + required. + + Return dictionary: + - elapsed_time: Float value, test time in seconds + - max_roundtrip_latency: Float value, max roundtrip latency in seconds + - throughput: Approximate data throughput in bytes/s + - max_ber: Estimated maximum BER, float value. + - errors: Number of errors + - bits: Number of bits that were transferred + """ + if self.args.dry_run: + return True, get_sfp_bist_defaults() + sfp_bist_results = run_aurora_bist(master='misc-enet-regs1') + return aurora_results_to_status(sfp_bist_results) + + def bist_sfp_loopback(self): + """ + BIST for SFP+ ports: + Description: Uses one SFP+ port to test the other. Pipes data out + through one SFP, back to the other. + + External Equipment: Loopback cable between the two SFP+ ports + required. + + Return dictionary: + - elapsed_time: Float value, test time in seconds + - max_roundtrip_latency: Float value, max roundtrip latency in seconds + - throughput: Approximate data throughput in bytes/s + - max_ber: Estimated maximum BER, float value. + - errors: Number of errors + - bits: Number of bits that were transferred + """ + if self.args.dry_run: + return True, get_sfp_bist_defaults() + sfp_bist_results = run_aurora_bist( + master='misc-enet-regs0', + slave='misc-enet-regs1', + ) + return aurora_results_to_status(sfp_bist_results) def bist_gpio(self): """ @@ -415,6 +511,9 @@ class N310BIST(object): } return True, result +############################################################################## +# main +############################################################################## def main(): " Go, go, go! " return N310BIST().run() |