Skip to content

Commit

Permalink
IB/hfi1: Fix serdes loopback set-up
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jan Sokolowski authored and Doug Ledford committed Oct 18, 2017
1 parent e19b205 commit 242b494
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 28 deletions.
42 changes: 14 additions & 28 deletions drivers/infiniband/hw/hfi1/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -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) {
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions drivers/infiniband/hw/hfi1/chip.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 242b494

Please sign in to comment.