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

Commit 0f77ba73 authored by Ravikumar Nelavelli's avatar Ravikumar Nelavelli Committed by David S. Miller
Browse files

be2net: fixup TX-rate setting code for Skyhawk-R



Skyhawk-R FW supports TX-rate setting only as a % value of the link
speed, set via the SET_PROFILE_CONFIG cmd.

This patch makes the necessary changes to the FW cmd descriptors to support
the above change and also introduces checks in be_set_vf_tx_rate() to allow
only discrete values (that map to % of the link-speed).

Signed-off-by: default avatarSathya Perla <sathya.perla@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a0794885
Loading
Loading
Loading
Loading
+27 −13
Original line number Diff line number Diff line
@@ -3562,33 +3562,47 @@ void be_reset_nic_desc(struct be_nic_res_desc *nic)
	nic->cq_count = 0xFFFF;
	nic->toe_conn_count = 0xFFFF;
	nic->eq_count = 0xFFFF;
	nic->iface_count = 0xFFFF;
	nic->link_param = 0xFF;
	nic->channel_id_param = cpu_to_le16(0xF000);
	nic->acpi_params = 0xFF;
	nic->wol_param = 0x0F;
	nic->bw_min = 0xFFFFFFFF;
	nic->tunnel_iface_count = 0xFFFF;
	nic->direct_tenant_iface_count = 0xFFFF;
	nic->bw_max = 0xFFFFFFFF;
}

int be_cmd_config_qos(struct be_adapter *adapter, u32 bps, u8 domain)
int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed,
		      u8 domain)
{
	if (lancer_chip(adapter)) {
	struct be_nic_res_desc nic_desc;
	u32 bw_percent;
	u16 version = 0;

	if (BE3_chip(adapter))
		return be_cmd_set_qos(adapter, max_rate / 10, domain);

	be_reset_nic_desc(&nic_desc);
	nic_desc.pf_num = adapter->pf_number;
	nic_desc.vf_num = domain;
	if (lancer_chip(adapter)) {
		nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V0;
		nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V0;
		nic_desc.flags = (1 << QUN_SHIFT) | (1 << IMM_SHIFT) |
					(1 << NOSV_SHIFT);
		nic_desc.pf_num = adapter->pf_number;
		nic_desc.vf_num = domain;
		nic_desc.bw_max = cpu_to_le32(bps);

		return be_cmd_set_profile_config(adapter, &nic_desc,
						 RESOURCE_DESC_SIZE_V0,
						 0, domain);
		nic_desc.bw_max = cpu_to_le32(max_rate / 10);
	} else {
		return be_cmd_set_qos(adapter, bps, domain);
		version = 1;
		nic_desc.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1;
		nic_desc.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
		nic_desc.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT);
		bw_percent = max_rate ? (max_rate * 100) / link_speed : 100;
		nic_desc.bw_max = cpu_to_le32(bw_percent);
	}

	return be_cmd_set_profile_config(adapter, &nic_desc,
					 nic_desc.hdr.desc_len,
					 version, domain);
}

int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op)
+9 −4
Original line number Diff line number Diff line
@@ -1891,16 +1891,20 @@ struct be_nic_res_desc {
	u16 cq_count;
	u16 toe_conn_count;
	u16 eq_count;
	u32 rsvd5;
	u16 vlan_id;
	u16 iface_count;
	u32 cap_flags;
	u8 link_param;
	u8 rsvd6[3];
	u8 rsvd6;
	u16 channel_id_param;
	u32 bw_min;
	u32 bw_max;
	u8 acpi_params;
	u8 wol_param;
	u16 rsvd7;
	u32 rsvd8[7];
	u16 tunnel_iface_count;
	u16 direct_tenant_iface_count;
	u32 rsvd8[6];
} __packed;

/************ Multi-Channel type ***********/
@@ -2101,7 +2105,8 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter,
int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
			u8 loopback_type, u8 enable);
int be_cmd_get_phy_info(struct be_adapter *adapter);
int be_cmd_config_qos(struct be_adapter *adapter, u32 bps, u8 domain);
int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate,
		      u16 link_speed, u8 domain);
void be_detect_error(struct be_adapter *adapter);
int be_cmd_get_die_temperature(struct be_adapter *adapter);
int be_cmd_get_cntl_attributes(struct be_adapter *adapter);
+45 −21
Original line number Diff line number Diff line
@@ -1352,7 +1352,10 @@ static int be_set_vf_tx_rate(struct net_device *netdev, int vf,
			     int min_tx_rate, int max_tx_rate)
{
	struct be_adapter *adapter = netdev_priv(netdev);
	int status = 0;
	struct device *dev = &adapter->pdev->dev;
	int percent_rate, status = 0;
	u16 link_speed = 0;
	u8 link_status;

	if (!sriov_enabled(adapter))
		return -EPERM;
@@ -1363,18 +1366,47 @@ static int be_set_vf_tx_rate(struct net_device *netdev, int vf,
	if (min_tx_rate)
		return -EINVAL;

	if (max_tx_rate < 100 || max_tx_rate > 10000) {
		dev_err(&adapter->pdev->dev,
			"max tx rate must be between 100 and 10000 Mbps\n");
		return -EINVAL;
	if (!max_tx_rate)
		goto config_qos;

	status = be_cmd_link_status_query(adapter, &link_speed,
					  &link_status, 0);
	if (status)
		goto err;

	if (!link_status) {
		dev_err(dev, "TX-rate setting not allowed when link is down\n");
		status = -EPERM;
		goto err;
	}

	if (max_tx_rate < 100 || max_tx_rate > link_speed) {
		dev_err(dev, "TX-rate must be between 100 and %d Mbps\n",
			link_speed);
		status = -EINVAL;
		goto err;
	}

	status = be_cmd_config_qos(adapter, max_tx_rate / 10, vf + 1);
	/* On Skyhawk the QOS setting must be done only as a % value */
	percent_rate = link_speed / 100;
	if (skyhawk_chip(adapter) && (max_tx_rate % percent_rate)) {
		dev_err(dev, "TX-rate must be a multiple of %d Mbps\n",
			percent_rate);
		status = -EINVAL;
		goto err;
	}

config_qos:
	status = be_cmd_config_qos(adapter, max_tx_rate, link_speed, vf + 1);
	if (status)
		dev_err(&adapter->pdev->dev,
			"max tx rate %d on VF %d failed\n", max_tx_rate, vf);
	else
		goto err;

	adapter->vf_cfg[vf].tx_rate = max_tx_rate;
	return 0;

err:
	dev_err(dev, "TX-rate setting of %dMbps on VF%d failed\n",
		max_tx_rate, vf);
	return status;
}
static int be_set_vf_link_state(struct net_device *netdev, int vf,
@@ -3135,7 +3167,6 @@ static int be_vf_setup(struct be_adapter *adapter)
	struct be_vf_cfg *vf_cfg;
	int status, old_vfs, vf;
	u32 privileges;
	u16 lnk_speed;

	old_vfs = pci_num_vf(adapter->pdev);
	if (old_vfs) {
@@ -3191,16 +3222,9 @@ static int be_vf_setup(struct be_adapter *adapter)
					 vf);
		}

		/* BE3 FW, by default, caps VF TX-rate to 100mbps.
		 * Allow full available bandwidth
		 */
		if (BE3_chip(adapter) && !old_vfs)
			be_cmd_config_qos(adapter, 1000, vf + 1);

		status = be_cmd_link_status_query(adapter, &lnk_speed,
						  NULL, vf + 1);
		if (!status)
			vf_cfg->tx_rate = lnk_speed;
		/* Allow full available bandwidth */
		if (!old_vfs)
			be_cmd_config_qos(adapter, 0, 0, vf + 1);

		if (!old_vfs) {
			be_cmd_enable_vf(adapter, vf + 1);