cxgbe(4): Fixes related to the knob that controls link autonegotiation.

- Do not leak the adapter lock in sysctl_autoneg.
- Accept only 0 or 1 as valid settings for autonegotiation.
- A fixed speed must be requested by the driver when autonegotiation is
  disabled otherwise the firmware will reject the l1cfg command.  Use
  the top speed supported by the port for now.

MFC after:	3 days
Sponsored by:	Chelsio Communications
This commit is contained in:
Navdeep Parhar 2017-05-09 08:08:28 +00:00
parent f32adafde1
commit e006d2a6fd
2 changed files with 26 additions and 1 deletions

View File

@ -1085,6 +1085,24 @@ port_top_speed(const struct port_info *pi)
return (0);
}
static inline int
port_top_speed_raw(const struct port_info *pi)
{
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G)
return (FW_PORT_CAP_SPEED_100G);
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G)
return (FW_PORT_CAP_SPEED_40G);
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G)
return (FW_PORT_CAP_SPEED_25G);
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G)
return (FW_PORT_CAP_SPEED_10G);
if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G)
return (FW_PORT_CAP_SPEED_1G);
return (0);
}
static inline int
tx_resume_threshold(struct sge_eq *eq)
{

View File

@ -995,6 +995,7 @@ t4_attach(device_t dev)
lc->autoneg = t4_autoneg ? AUTONEG_ENABLE :
AUTONEG_DISABLE;
}
lc->requested_speed = port_top_speed_raw(pi);
rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc);
if (rc != 0) {
@ -5883,7 +5884,12 @@ sysctl_autoneg(SYSCTL_HANDLER_ARGS)
if ((lc->supported & FW_PORT_CAP_ANEG) == 0)
return (ENOTSUP);
val = val ? AUTONEG_ENABLE : AUTONEG_DISABLE;
if (val == 0)
val = AUTONEG_DISABLE;
else if (val == 1)
val = AUTONEG_ENABLE;
else
return (EINVAL);
if (lc->autoneg == val)
return (0); /* no change */
@ -5896,6 +5902,7 @@ sysctl_autoneg(SYSCTL_HANDLER_ARGS)
rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc);
if (rc != 0)
lc->autoneg = old;
end_synchronized_op(sc, 0);
return (rc);
}