cxgb4/cxgb4vf: Display advertised FEC in ethtool
This patch advertises Forward Error Correction in ethtool Signed-off-by: Casey Leedom <leedom@chelsio.com> Signed-off-by: Vishal Kulkarni <vishal@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5d10de34d4
commit
9f764898c7
@ -1575,9 +1575,11 @@ int t4_slow_intr_handler(struct adapter *adapter);
|
||||
|
||||
int t4_wait_dev_ready(void __iomem *regs);
|
||||
|
||||
fw_port_cap32_t t4_link_acaps(struct adapter *adapter, unsigned int port,
|
||||
struct link_config *lc);
|
||||
int t4_link_l1cfg_core(struct adapter *adap, unsigned int mbox,
|
||||
unsigned int port, struct link_config *lc,
|
||||
bool sleep_ok, int timeout);
|
||||
u8 sleep_ok, int timeout);
|
||||
|
||||
static inline int t4_link_l1cfg(struct adapter *adapter, unsigned int mbox,
|
||||
unsigned int port, struct link_config *lc)
|
||||
|
@ -442,7 +442,7 @@ static unsigned int speed_to_fw_caps(int speed)
|
||||
* Link Mode Mask.
|
||||
*/
|
||||
static void fw_caps_to_lmm(enum fw_port_type port_type,
|
||||
unsigned int fw_caps,
|
||||
fw_port_cap32_t fw_caps,
|
||||
unsigned long *link_mode_mask)
|
||||
{
|
||||
#define SET_LMM(__lmm_name) \
|
||||
@ -632,7 +632,10 @@ static int get_link_ksettings(struct net_device *dev,
|
||||
|
||||
fw_caps_to_lmm(pi->port_type, pi->link_cfg.pcaps,
|
||||
link_ksettings->link_modes.supported);
|
||||
fw_caps_to_lmm(pi->port_type, pi->link_cfg.acaps,
|
||||
fw_caps_to_lmm(pi->port_type,
|
||||
t4_link_acaps(pi->adapter,
|
||||
pi->lport,
|
||||
&pi->link_cfg),
|
||||
link_ksettings->link_modes.advertising);
|
||||
fw_caps_to_lmm(pi->port_type, pi->link_cfg.lpacaps,
|
||||
link_ksettings->link_modes.lp_advertising);
|
||||
@ -642,22 +645,6 @@ static int get_link_ksettings(struct net_device *dev,
|
||||
: SPEED_UNKNOWN);
|
||||
base->duplex = DUPLEX_FULL;
|
||||
|
||||
if (pi->link_cfg.fc & PAUSE_RX) {
|
||||
if (pi->link_cfg.fc & PAUSE_TX) {
|
||||
ethtool_link_ksettings_add_link_mode(link_ksettings,
|
||||
advertising,
|
||||
Pause);
|
||||
} else {
|
||||
ethtool_link_ksettings_add_link_mode(link_ksettings,
|
||||
advertising,
|
||||
Asym_Pause);
|
||||
}
|
||||
} else if (pi->link_cfg.fc & PAUSE_TX) {
|
||||
ethtool_link_ksettings_add_link_mode(link_ksettings,
|
||||
advertising,
|
||||
Asym_Pause);
|
||||
}
|
||||
|
||||
base->autoneg = pi->link_cfg.autoneg;
|
||||
if (pi->link_cfg.pcaps & FW_PORT_CAP32_ANEG)
|
||||
ethtool_link_ksettings_add_link_mode(link_ksettings,
|
||||
|
@ -3964,6 +3964,14 @@ void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf)
|
||||
}
|
||||
}
|
||||
|
||||
/* The ADVERT_MASK is used to mask out all of the Advertised Firmware Port
|
||||
* Capabilities which we control with separate controls -- see, for instance,
|
||||
* Pause Frames and Forward Error Correction. In order to determine what the
|
||||
* full set of Advertised Port Capabilities are, the base Advertised Port
|
||||
* Capabilities (masked by ADVERT_MASK) must be combined with the Advertised
|
||||
* Port Capabilities associated with those other controls. See
|
||||
* t4_link_acaps() for how this is done.
|
||||
*/
|
||||
#define ADVERT_MASK (FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_M) | \
|
||||
FW_PORT_CAP32_ANEG)
|
||||
|
||||
@ -4061,6 +4069,9 @@ static inline enum cc_pause fwcap_to_cc_pause(fw_port_cap32_t fw_pause)
|
||||
/* Translate Common Code Pause specification into Firmware Port Capabilities */
|
||||
static inline fw_port_cap32_t cc_to_fwcap_pause(enum cc_pause cc_pause)
|
||||
{
|
||||
/* Translate orthogonal RX/TX Pause Controls for L1 Configure
|
||||
* commands, etc.
|
||||
*/
|
||||
fw_port_cap32_t fw_pause = 0;
|
||||
|
||||
if (cc_pause & PAUSE_RX)
|
||||
@ -4070,6 +4081,19 @@ static inline fw_port_cap32_t cc_to_fwcap_pause(enum cc_pause cc_pause)
|
||||
if (!(cc_pause & PAUSE_AUTONEG))
|
||||
fw_pause |= FW_PORT_CAP32_FORCE_PAUSE;
|
||||
|
||||
/* Translate orthogonal Pause controls into IEEE 802.3 Pause,
|
||||
* Asymetrical Pause for use in reporting to upper layer OS code, etc.
|
||||
* Note that these bits are ignored in L1 Configure commands.
|
||||
*/
|
||||
if (cc_pause & PAUSE_RX) {
|
||||
if (cc_pause & PAUSE_TX)
|
||||
fw_pause |= FW_PORT_CAP32_802_3_PAUSE;
|
||||
else
|
||||
fw_pause |= FW_PORT_CAP32_802_3_ASM_DIR;
|
||||
} else if (cc_pause & PAUSE_TX) {
|
||||
fw_pause |= FW_PORT_CAP32_802_3_ASM_DIR;
|
||||
}
|
||||
|
||||
return fw_pause;
|
||||
}
|
||||
|
||||
@ -4100,31 +4124,22 @@ static inline fw_port_cap32_t cc_to_fwcap_fec(enum cc_fec cc_fec)
|
||||
}
|
||||
|
||||
/**
|
||||
* t4_link_l1cfg - apply link configuration to MAC/PHY
|
||||
* t4_link_acaps - compute Link Advertised Port Capabilities
|
||||
* @adapter: the adapter
|
||||
* @mbox: the Firmware Mailbox to use
|
||||
* @port: the Port ID
|
||||
* @lc: the Port's Link Configuration
|
||||
* @sleep_ok: if true we may sleep while awaiting command completion
|
||||
* @timeout: time to wait for command to finish before timing out
|
||||
* (negative implies @sleep_ok=false)
|
||||
*
|
||||
* Set up a port's MAC and PHY according to a desired link configuration.
|
||||
* - If the PHY can auto-negotiate first decide what to advertise, then
|
||||
* enable/disable auto-negotiation as desired, and reset.
|
||||
* - If the PHY does not auto-negotiate just reset it.
|
||||
* - If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
|
||||
* otherwise do it later based on the outcome of auto-negotiation.
|
||||
* Synthesize the Advertised Port Capabilities we'll be using based on
|
||||
* the base Advertised Port Capabilities (which have been filtered by
|
||||
* ADVERT_MASK) plus the individual controls for things like Pause
|
||||
* Frames, Forward Error Correction, MDI, etc.
|
||||
*/
|
||||
int t4_link_l1cfg_core(struct adapter *adapter, unsigned int mbox,
|
||||
unsigned int port, struct link_config *lc,
|
||||
bool sleep_ok, int timeout)
|
||||
fw_port_cap32_t t4_link_acaps(struct adapter *adapter, unsigned int port,
|
||||
struct link_config *lc)
|
||||
{
|
||||
unsigned int fw_caps = adapter->params.fw_caps_support;
|
||||
fw_port_cap32_t fw_fc, cc_fec, fw_fec, rcap;
|
||||
struct fw_port_cmd cmd;
|
||||
fw_port_cap32_t fw_fc, fw_fec, acaps;
|
||||
unsigned int fw_mdi;
|
||||
int ret;
|
||||
char cc_fec;
|
||||
|
||||
fw_mdi = (FW_PORT_CAP32_MDI_V(FW_PORT_CAP32_MDI_AUTO) & lc->pcaps);
|
||||
|
||||
@ -4151,18 +4166,15 @@ int t4_link_l1cfg_core(struct adapter *adapter, unsigned int mbox,
|
||||
* init_link_config().
|
||||
*/
|
||||
if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) {
|
||||
if (lc->autoneg == AUTONEG_ENABLE)
|
||||
return -EINVAL;
|
||||
|
||||
rcap = lc->acaps | fw_fc | fw_fec;
|
||||
acaps = lc->acaps | fw_fc | fw_fec;
|
||||
lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
|
||||
lc->fec = cc_fec;
|
||||
} else if (lc->autoneg == AUTONEG_DISABLE) {
|
||||
rcap = lc->speed_caps | fw_fc | fw_fec | fw_mdi;
|
||||
acaps = lc->speed_caps | fw_fc | fw_fec | fw_mdi;
|
||||
lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
|
||||
lc->fec = cc_fec;
|
||||
} else {
|
||||
rcap = lc->acaps | fw_fc | fw_fec | fw_mdi;
|
||||
acaps = lc->acaps | fw_fc | fw_fec | fw_mdi;
|
||||
}
|
||||
|
||||
/* Some Requested Port Capabilities are trivially wrong if they exceed
|
||||
@ -4173,15 +4185,50 @@ int t4_link_l1cfg_core(struct adapter *adapter, unsigned int mbox,
|
||||
* we need to exclude this from this check in order to maintain
|
||||
* compatibility ...
|
||||
*/
|
||||
if ((rcap & ~lc->pcaps) & ~FW_PORT_CAP32_FORCE_PAUSE) {
|
||||
dev_err(adapter->pdev_dev,
|
||||
"Requested Port Capabilities %#x exceed Physical Port Capabilities %#x\n",
|
||||
rcap, lc->pcaps);
|
||||
if ((acaps & ~lc->pcaps) & ~FW_PORT_CAP32_FORCE_PAUSE) {
|
||||
dev_err(adapter->pdev_dev, "Requested Port Capabilities %#x exceed Physical Port Capabilities %#x\n",
|
||||
acaps, lc->pcaps);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* And send that on to the Firmware ...
|
||||
return acaps;
|
||||
}
|
||||
|
||||
/**
|
||||
* t4_link_l1cfg_core - apply link configuration to MAC/PHY
|
||||
* @adapter: the adapter
|
||||
* @mbox: the Firmware Mailbox to use
|
||||
* @port: the Port ID
|
||||
* @lc: the Port's Link Configuration
|
||||
* @sleep_ok: if true we may sleep while awaiting command completion
|
||||
* @timeout: time to wait for command to finish before timing out
|
||||
* (negative implies @sleep_ok=false)
|
||||
*
|
||||
* Set up a port's MAC and PHY according to a desired link configuration.
|
||||
* - If the PHY can auto-negotiate first decide what to advertise, then
|
||||
* enable/disable auto-negotiation as desired, and reset.
|
||||
* - If the PHY does not auto-negotiate just reset it.
|
||||
* - If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
|
||||
* otherwise do it later based on the outcome of auto-negotiation.
|
||||
*/
|
||||
int t4_link_l1cfg_core(struct adapter *adapter, unsigned int mbox,
|
||||
unsigned int port, struct link_config *lc,
|
||||
u8 sleep_ok, int timeout)
|
||||
{
|
||||
unsigned int fw_caps = adapter->params.fw_caps_support;
|
||||
struct fw_port_cmd cmd;
|
||||
fw_port_cap32_t rcap;
|
||||
int ret;
|
||||
|
||||
if (!(lc->pcaps & FW_PORT_CAP32_ANEG) &&
|
||||
lc->autoneg == AUTONEG_ENABLE) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Compute our Requested Port Capabilities and send that on to the
|
||||
* Firmware.
|
||||
*/
|
||||
rcap = t4_link_acaps(adapter, port, lc);
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
|
||||
FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
|
||||
@ -4211,7 +4258,7 @@ int t4_link_l1cfg_core(struct adapter *adapter, unsigned int mbox,
|
||||
rcap, -ret);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1479,22 +1479,6 @@ static int cxgb4vf_get_link_ksettings(struct net_device *dev,
|
||||
base->duplex = DUPLEX_UNKNOWN;
|
||||
}
|
||||
|
||||
if (pi->link_cfg.fc & PAUSE_RX) {
|
||||
if (pi->link_cfg.fc & PAUSE_TX) {
|
||||
ethtool_link_ksettings_add_link_mode(link_ksettings,
|
||||
advertising,
|
||||
Pause);
|
||||
} else {
|
||||
ethtool_link_ksettings_add_link_mode(link_ksettings,
|
||||
advertising,
|
||||
Asym_Pause);
|
||||
}
|
||||
} else if (pi->link_cfg.fc & PAUSE_TX) {
|
||||
ethtool_link_ksettings_add_link_mode(link_ksettings,
|
||||
advertising,
|
||||
Asym_Pause);
|
||||
}
|
||||
|
||||
base->autoneg = pi->link_cfg.autoneg;
|
||||
if (pi->link_cfg.pcaps & FW_PORT_CAP32_ANEG)
|
||||
ethtool_link_ksettings_add_link_mode(link_ksettings,
|
||||
|
@ -313,7 +313,17 @@ int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* In the Physical Function Driver Common Code, the ADVERT_MASK is used to
|
||||
* mask out bits in the Advertised Port Capabilities which are managed via
|
||||
* separate controls, like Pause Frames and Forward Error Correction. In the
|
||||
* Virtual Function Common Code, since we never perform L1 Configuration on
|
||||
* the Link, the only things we really need to filter out are things which
|
||||
* we decode and report separately like Speed.
|
||||
*/
|
||||
#define ADVERT_MASK (FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_M) | \
|
||||
FW_PORT_CAP32_802_3_PAUSE | \
|
||||
FW_PORT_CAP32_802_3_ASM_DIR | \
|
||||
FW_PORT_CAP32_FEC_V(FW_PORT_CAP32_FEC_M) | \
|
||||
FW_PORT_CAP32_ANEG)
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user