Commit 8009bb19 authored by Nikita Danilov's avatar Nikita Danilov Committed by David S. Miller
Browse files

net: atlantic: update flow control logic



We now differentiate requested and negotiated flow control
modes. Therefore `ethtool -A` now operates on local requested
FC values, and regular link settings shows the negotiated FC
settings.

Signed-off-by: default avatarNikita Danilov <ndanilov@marvell.com>
Signed-off-by: default avatarIgor Russkikh <irusskikh@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ddef5526
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -70,12 +70,6 @@

/*#define AQ_CFG_MAC_ADDR_PERMANENT {0x30, 0x0E, 0xE3, 0x12, 0x34, 0x56}*/

#define AQ_NIC_FC_OFF    0U
#define AQ_NIC_FC_TX     1U
#define AQ_NIC_FC_RX     2U
#define AQ_NIC_FC_FULL   3U
#define AQ_NIC_FC_AUTO   4U

#define AQ_CFG_FC_MODE AQ_NIC_FC_FULL

/* Default WOL modes used on initialization */
+5 −5
Original line number Diff line number Diff line
@@ -588,7 +588,7 @@ static void aq_ethtool_get_pauseparam(struct net_device *ndev,
				      struct ethtool_pauseparam *pause)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	u32 fc = aq_nic->aq_nic_cfg.flow_control;
	u32 fc = aq_nic->aq_nic_cfg.fc.req;

	pause->autoneg = 0;

@@ -610,14 +610,14 @@ static int aq_ethtool_set_pauseparam(struct net_device *ndev,
		return -EOPNOTSUPP;

	if (pause->rx_pause)
		aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_RX;
		aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX;
	else
		aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_RX;
		aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX;

	if (pause->tx_pause)
		aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_TX;
		aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX;
	else
		aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_TX;
		aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX;

	mutex_lock(&aq_nic->fwreq_mutex);
	err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
+12 −7
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ void aq_nic_cfg_start(struct aq_nic_s *self)
	cfg->is_rss = AQ_CFG_IS_RSS_DEF;
	cfg->num_rss_queues = AQ_CFG_NUM_RSS_QUEUES_DEF;
	cfg->aq_rss.base_cpu_number = AQ_CFG_RSS_BASE_CPU_NUM_DEF;
	cfg->flow_control = AQ_CFG_FC_MODE;
	cfg->fc.req = AQ_CFG_FC_MODE;
	cfg->wol = AQ_CFG_WOL_MODES;

	cfg->mtu = AQ_CFG_MTU_DEF;
@@ -144,6 +144,10 @@ static int aq_nic_update_link_status(struct aq_nic_s *self)
	if (err)
		return err;

	if (self->aq_fw_ops->get_flow_control)
		self->aq_fw_ops->get_flow_control(self->aq_hw, &fc);
	self->aq_nic_cfg.fc.cur = fc;

	if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps) {
		netdev_info(self->ndev, "%s: link change old %d new %d\n",
			    AQ_CFG_DRV_NAME, self->link_status.mbps,
@@ -161,8 +165,6 @@ static int aq_nic_update_link_status(struct aq_nic_s *self)
		 * on any link event.
		 * We should query FW whether it negotiated FC.
		 */
		if (self->aq_fw_ops->get_flow_control)
			self->aq_fw_ops->get_flow_control(self->aq_hw, &fc);
		if (self->aq_hw_ops->hw_set_fc)
			self->aq_hw_ops->hw_set_fc(self->aq_hw, fc, 0);
	}
@@ -862,9 +864,12 @@ void aq_nic_get_link_ksettings(struct aq_nic_s *self,
		ethtool_link_ksettings_add_link_mode(cmd, supported,
						     100baseT_Full);

	if (self->aq_nic_cfg.aq_hw_caps->flow_control)
	if (self->aq_nic_cfg.aq_hw_caps->flow_control) {
		ethtool_link_ksettings_add_link_mode(cmd, supported,
						     Pause);
		ethtool_link_ksettings_add_link_mode(cmd, supported,
						     Asym_Pause);
	}

	ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);

@@ -898,13 +903,13 @@ void aq_nic_get_link_ksettings(struct aq_nic_s *self,
		ethtool_link_ksettings_add_link_mode(cmd, advertising,
						     100baseT_Full);

	if (self->aq_nic_cfg.flow_control & AQ_NIC_FC_RX)
	if (self->aq_nic_cfg.fc.cur & AQ_NIC_FC_RX)
		ethtool_link_ksettings_add_link_mode(cmd, advertising,
						     Pause);

	/* Asym is when either RX or TX, but not both */
	if (!!(self->aq_nic_cfg.flow_control & AQ_NIC_FC_TX) ^
	    !!(self->aq_nic_cfg.flow_control & AQ_NIC_FC_RX))
	if (!!(self->aq_nic_cfg.fc.cur & AQ_NIC_FC_TX) ^
	    !!(self->aq_nic_cfg.fc.cur & AQ_NIC_FC_RX))
		ethtool_link_ksettings_add_link_mode(cmd, advertising,
						     Asym_Pause);

+13 −1
Original line number Diff line number Diff line
@@ -20,6 +20,18 @@ struct aq_vec_s;
struct aq_ptp_s;
enum aq_rx_filter_type;

enum aq_fc_mode {
	AQ_NIC_FC_OFF = 0,
	AQ_NIC_FC_TX,
	AQ_NIC_FC_RX,
	AQ_NIC_FC_FULL,
};

struct aq_fc_info {
	enum aq_fc_mode req;
	enum aq_fc_mode cur;
};

struct aq_nic_cfg_s {
	const struct aq_hw_caps_s *aq_hw_caps;
	u64 features;
@@ -34,7 +46,7 @@ struct aq_nic_cfg_s {
	u32 rxpageorder;
	u32 num_rss_queues;
	u32 mtu;
	u32 flow_control;
	struct aq_fc_info fc;
	u32 link_speed_msk;
	u32 wol;
	u8 is_vlan_rx_strip;
+1 −1
Original line number Diff line number Diff line
@@ -155,7 +155,7 @@ static int hw_atl_a0_hw_qos_set(struct aq_hw_s *self)

	/* QoS Rx buf size per TC */
	tc = 0;
	is_rx_flow_control = (AQ_NIC_FC_RX & self->aq_nic_cfg->flow_control);
	is_rx_flow_control = (AQ_NIC_FC_RX & self->aq_nic_cfg->fc.req);
	buff_size = HW_ATL_A0_RXBUF_MAX;

	hw_atl_rpb_rx_pkt_buff_size_per_tc_set(self, buff_size, tc);
Loading