IB/hfi1: Fix serdes loopback set-up
authorJan Sokolowski <jan.sokolowski@intel.com>
Mon, 9 Oct 2017 20:08:28 +0000 (13:08 -0700)
committerDoug Ledford <dledford@redhat.com>
Wed, 18 Oct 2017 14:12:59 +0000 (10:12 -0400)
Change serdes mode setting to use MISC_CONFIG_BITS in
VERIFY_CAP_LOCAL_LINK_WIDTH register. This method of
setting up serdes loopback is universally compatible
across all firmware versions.

Reviewed-by: Jakub Byczkowski <jakub.byczkowski@intel.com>
Signed-off-by: Jan Sokolowski <jan.sokolowski@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/hfi1/chip.c
drivers/infiniband/hw/hfi1/chip.h

index b2ed4b9cda6eef62f81b5ac22b71b4cc3a5a2d10..160ada91e8495374745b14685abedbf2834fd846 100644 (file)
@@ -9156,25 +9156,6 @@ static int do_quick_linkup(struct hfi1_devdata *dd)
        return 0; /* success */
 }
 
-/*
- * Set the SerDes to internal loopback mode.
- * Returns 0 on success, -errno on error.
- */
-static int set_serdes_loopback_mode(struct hfi1_devdata *dd)
-{
-       int ret;
-
-       ret = set_physical_link_state(dd, PLS_INTERNAL_SERDES_LOOPBACK);
-       if (ret == HCMD_SUCCESS)
-               return 0;
-       dd_dev_err(dd,
-                  "Set physical link state to SerDes Loopback failed with return %d\n",
-                  ret);
-       if (ret >= 0)
-               ret = -EINVAL;
-       return ret;
-}
-
 /*
  * Do all special steps to set up loopback.
  */
@@ -9200,13 +9181,11 @@ static int init_loopback(struct hfi1_devdata *dd)
                return 0;
        }
 
-       /* handle serdes loopback */
-       if (loopback == LOOPBACK_SERDES) {
-               /* internal serdes loopack needs quick linkup on RTL */
-               if (dd->icode == ICODE_RTL_SILICON)
-                       quick_linkup = 1;
-               return set_serdes_loopback_mode(dd);
-       }
+       /*
+        * SerDes loopback init sequence is handled in set_local_link_attributes
+        */
+       if (loopback == LOOPBACK_SERDES)
+               return 0;
 
        /* LCB loopback - handled at poll time */
        if (loopback == LOOPBACK_LCB) {
@@ -9265,7 +9244,7 @@ static int set_local_link_attributes(struct hfi1_pportdata *ppd)
        u8 tx_polarity_inversion;
        u8 rx_polarity_inversion;
        int ret;
-
+       u32 misc_bits = 0;
        /* reset our fabric serdes to clear any lingering problems */
        fabric_serdes_reset(dd);
 
@@ -9311,7 +9290,14 @@ static int set_local_link_attributes(struct hfi1_pportdata *ppd)
        if (ret != HCMD_SUCCESS)
                goto set_local_link_attributes_fail;
 
-       ret = write_vc_local_link_width(dd, 0, 0,
+       /*
+        * SerDes loopback init sequence requires
+        * setting bit 0 of MISC_CONFIG_BITS
+        */
+       if (loopback == LOOPBACK_SERDES)
+               misc_bits |= 1 << LOOPBACK_SERDES_CONFIG_BIT_MASK_SHIFT;
+
+       ret = write_vc_local_link_width(dd, misc_bits, 0,
                                        opa_to_vc_link_widths(
                                                ppd->link_width_enabled));
        if (ret != HCMD_SUCCESS)
index b8345a60a0fbc452215dba3c679daa6785fb4e4a..45b645e892c9da0f9a1ff4e4dbf36e8968ed05df 100644 (file)
@@ -582,6 +582,9 @@ enum {
 #define LOOPBACK_LCB   2
 #define LOOPBACK_CABLE 3       /* external cable */
 
+/* set up serdes bit in MISC_CONFIG_BITS */
+#define LOOPBACK_SERDES_CONFIG_BIT_MASK_SHIFT 0
+
 /* read and write hardware registers */
 u64 read_csr(const struct hfi1_devdata *dd, u32 offset);
 void write_csr(const struct hfi1_devdata *dd, u32 offset, u64 value);