forked from Minki/linux
IB/ipath: control receive polarity inversion
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
e35d710d0c
commit
30fc5c3130
@ -2116,5 +2116,22 @@ bail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv)
|
||||
{
|
||||
u64 val;
|
||||
if ( new_pol_inv > INFINIPATH_XGXS_RX_POL_MASK ) {
|
||||
return -1;
|
||||
}
|
||||
if ( dd->ipath_rx_pol_inv != new_pol_inv ) {
|
||||
dd->ipath_rx_pol_inv = new_pol_inv;
|
||||
val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig);
|
||||
val &= ~(INFINIPATH_XGXS_RX_POL_MASK <<
|
||||
INFINIPATH_XGXS_RX_POL_SHIFT);
|
||||
val |= ((u64)dd->ipath_rx_pol_inv) <<
|
||||
INFINIPATH_XGXS_RX_POL_SHIFT;
|
||||
ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
module_init(infinipath_init);
|
||||
module_exit(infinipath_cleanup);
|
||||
|
@ -1290,6 +1290,15 @@ static int ipath_ht_bringup_serdes(struct ipath_devdata *dd)
|
||||
val &= ~INFINIPATH_XGXS_RESET;
|
||||
change = 1;
|
||||
}
|
||||
if (((val >> INFINIPATH_XGXS_RX_POL_SHIFT) &
|
||||
INFINIPATH_XGXS_RX_POL_MASK) != dd->ipath_rx_pol_inv ) {
|
||||
/* need to compensate for Tx inversion in partner */
|
||||
val &= ~(INFINIPATH_XGXS_RX_POL_MASK <<
|
||||
INFINIPATH_XGXS_RX_POL_SHIFT);
|
||||
val |= dd->ipath_rx_pol_inv <<
|
||||
INFINIPATH_XGXS_RX_POL_SHIFT;
|
||||
change = 1;
|
||||
}
|
||||
if (change)
|
||||
ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val);
|
||||
|
||||
|
@ -654,6 +654,15 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
|
||||
val &= ~INFINIPATH_XGXS_RESET;
|
||||
change = 1;
|
||||
}
|
||||
if (((val >> INFINIPATH_XGXS_RX_POL_SHIFT) &
|
||||
INFINIPATH_XGXS_RX_POL_MASK) != dd->ipath_rx_pol_inv ) {
|
||||
/* need to compensate for Tx inversion in partner */
|
||||
val &= ~(INFINIPATH_XGXS_RX_POL_MASK <<
|
||||
INFINIPATH_XGXS_RX_POL_SHIFT);
|
||||
val |= dd->ipath_rx_pol_inv <<
|
||||
INFINIPATH_XGXS_RX_POL_SHIFT;
|
||||
change = 1;
|
||||
}
|
||||
if (change)
|
||||
ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val);
|
||||
|
||||
|
@ -503,6 +503,8 @@ struct ipath_devdata {
|
||||
u8 ipath_pci_cacheline;
|
||||
/* LID mask control */
|
||||
u8 ipath_lmc;
|
||||
/* Rx Polarity inversion (compensate for ~tx on partner) */
|
||||
u8 ipath_rx_pol_inv;
|
||||
|
||||
/* local link integrity counter */
|
||||
u32 ipath_lli_counter;
|
||||
@ -567,6 +569,7 @@ void ipath_get_faststats(unsigned long);
|
||||
int ipath_set_linkstate(struct ipath_devdata *, u8);
|
||||
int ipath_set_mtu(struct ipath_devdata *, u16);
|
||||
int ipath_set_lid(struct ipath_devdata *, u32, u8);
|
||||
int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv);
|
||||
|
||||
/* for use in system calls, where we want to know device type, etc. */
|
||||
#define port_fp(fp) ((struct ipath_portdata *) (fp)->private_data)
|
||||
|
@ -282,6 +282,8 @@
|
||||
#define INFINIPATH_XGXS_RESET 0x7ULL
|
||||
#define INFINIPATH_XGXS_MDIOADDR_MASK 0xfULL
|
||||
#define INFINIPATH_XGXS_MDIOADDR_SHIFT 4
|
||||
#define INFINIPATH_XGXS_RX_POL_SHIFT 19
|
||||
#define INFINIPATH_XGXS_RX_POL_MASK 0xfULL
|
||||
|
||||
#define INFINIPATH_RT_ADDR_MASK 0xFFFFFFFFFFULL /* 40 bits valid */
|
||||
|
||||
|
@ -561,6 +561,33 @@ bail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t store_rx_pol_inv(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct ipath_devdata *dd = dev_get_drvdata(dev);
|
||||
int ret, r;
|
||||
u16 val;
|
||||
|
||||
ret = ipath_parse_ushort(buf, &val);
|
||||
if (ret < 0)
|
||||
goto invalid;
|
||||
|
||||
r = ipath_set_rx_pol_inv(dd, val);
|
||||
if (r < 0) {
|
||||
ret = r;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
goto bail;
|
||||
invalid:
|
||||
ipath_dev_err(dd, "attempt to set invalid Rx Polarity invert\n");
|
||||
bail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static DRIVER_ATTR(num_units, S_IRUGO, show_num_units, NULL);
|
||||
static DRIVER_ATTR(version, S_IRUGO, show_version, NULL);
|
||||
|
||||
@ -587,6 +614,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
|
||||
static DEVICE_ATTR(status_str, S_IRUGO, show_status_str, NULL);
|
||||
static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL);
|
||||
static DEVICE_ATTR(unit, S_IRUGO, show_unit, NULL);
|
||||
static DEVICE_ATTR(rx_pol_inv, S_IWUSR, NULL, store_rx_pol_inv);
|
||||
|
||||
static struct attribute *dev_attributes[] = {
|
||||
&dev_attr_guid.attr,
|
||||
@ -601,6 +629,7 @@ static struct attribute *dev_attributes[] = {
|
||||
&dev_attr_boardversion.attr,
|
||||
&dev_attr_unit.attr,
|
||||
&dev_attr_enabled.attr,
|
||||
&dev_attr_rx_pol_inv.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user