Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f764898 authored by Vishal Kulkarni's avatar Vishal Kulkarni Committed by David S. Miller
Browse files

cxgb4/cxgb4vf: Display advertised FEC in ethtool



This patch advertises Forward Error Correction in ethtool

Signed-off-by: default avatarCasey Leedom <leedom@chelsio.com>
Signed-off-by: default avatarVishal Kulkarni <vishal@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5d10de34
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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)
+5 −18
Original line number Diff line number Diff line
@@ -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,
+77 −30
Original line number Diff line number Diff line
@@ -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;
}

/**
+0 −16
Original line number Diff line number Diff line
@@ -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,
+10 −0
Original line number Diff line number Diff line
@@ -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)

/**