Ejemplo n.º 1
0
int bnxt_get_vf_config(struct net_device *dev, int vf_id,
		       struct ifla_vf_info *ivi)
{
	struct bnxt *bp = netdev_priv(dev);
	struct bnxt_vf_info *vf;
	int rc;

	rc = bnxt_vf_ndo_prep(bp, vf_id);
	if (rc)
		return rc;

	ivi->vf = vf_id;
	vf = &bp->pf.vf[vf_id];

	memcpy(&ivi->mac, vf->mac_addr, ETH_ALEN);
	ivi->max_tx_rate = vf->max_tx_rate;
	ivi->min_tx_rate = vf->min_tx_rate;
	ivi->vlan = vf->vlan;
	ivi->qos = vf->flags & BNXT_VF_QOS;
	ivi->spoofchk = vf->flags & BNXT_VF_SPOOFCHK;
	if (!(vf->flags & BNXT_VF_LINK_FORCED))
		ivi->linkstate = IFLA_VF_LINK_STATE_AUTO;
	else if (vf->flags & BNXT_VF_LINK_UP)
		ivi->linkstate = IFLA_VF_LINK_STATE_ENABLE;
	else
		ivi->linkstate = IFLA_VF_LINK_STATE_DISABLE;

	return 0;
}
Ejemplo n.º 2
0
int bnxt_set_vf_link_state(struct net_device *dev, int vf_id, int link)
{
	struct bnxt *bp = netdev_priv(dev);
	struct bnxt_vf_info *vf;
	int rc;

	rc = bnxt_vf_ndo_prep(bp, vf_id);
	if (rc)
		return rc;

	vf = &bp->pf.vf[vf_id];

	vf->flags &= ~(BNXT_VF_LINK_UP | BNXT_VF_LINK_FORCED);
	switch (link) {
	case IFLA_VF_LINK_STATE_AUTO:
		vf->flags |= BNXT_VF_LINK_UP;
		break;
	case IFLA_VF_LINK_STATE_DISABLE:
		vf->flags |= BNXT_VF_LINK_FORCED;
		break;
	case IFLA_VF_LINK_STATE_ENABLE:
		vf->flags |= BNXT_VF_LINK_UP | BNXT_VF_LINK_FORCED;
		break;
	default:
		netdev_err(bp->dev, "Invalid link option\n");
		rc = -EINVAL;
		break;
	}
	/* CHIMP TODO: send msg to VF to update new link state */

	return rc;
}
Ejemplo n.º 3
0
int bnxt_set_vf_vlan(struct net_device *dev, int vf_id, u16 vlan_id, u8 qos)
{
	struct hwrm_func_cfg_input req = {0};
	struct bnxt *bp = netdev_priv(dev);
	struct bnxt_vf_info *vf;
	u16 vlan_tag;
	int rc;

	rc = bnxt_vf_ndo_prep(bp, vf_id);
	if (rc)
		return rc;

	/* TODO: needed to implement proper handling of user priority,
	 * currently fail the command if there is valid priority
	 */
	if (vlan_id > 4095 || qos)
		return -EINVAL;

	vf = &bp->pf.vf[vf_id];
	vlan_tag = vlan_id;
	if (vlan_tag == vf->vlan)
		return 0;

	bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1);
	req.fid = cpu_to_le16(vf->fw_fid);
	req.flags = cpu_to_le32(vf->func_flags);
	req.dflt_vlan = cpu_to_le16(vlan_tag);
	req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_DFLT_VLAN);
	rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
	if (!rc)
		vf->vlan = vlan_tag;
	return rc;
}
Ejemplo n.º 4
0
int bnxt_set_vf_mac(struct net_device *dev, int vf_id, u8 *mac)
{
	struct hwrm_func_cfg_input req = {0};
	struct bnxt *bp = netdev_priv(dev);
	struct bnxt_vf_info *vf;
	int rc;

	rc = bnxt_vf_ndo_prep(bp, vf_id);
	if (rc)
		return rc;
	/* reject bc or mc mac addr, zero mac addr means allow
	 * VF to use its own mac addr
	 */
	if (is_multicast_ether_addr(mac)) {
		netdev_err(dev, "Invalid VF ethernet address\n");
		return -EINVAL;
	}
	vf = &bp->pf.vf[vf_id];

	memcpy(vf->mac_addr, mac, ETH_ALEN);
	bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1);
	req.fid = cpu_to_le16(vf->fw_fid);
	req.flags = cpu_to_le32(vf->func_flags);
	req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_DFLT_MAC_ADDR);
	memcpy(req.dflt_mac_addr, mac, ETH_ALEN);
	return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
}
Ejemplo n.º 5
0
int bnxt_set_vf_trust(struct net_device *dev, int vf_id, bool trusted)
{
	struct bnxt *bp = netdev_priv(dev);
	struct bnxt_vf_info *vf;

	if (bnxt_vf_ndo_prep(bp, vf_id))
		return -EINVAL;

	vf = &bp->pf.vf[vf_id];
	if (trusted)
		vf->flags |= BNXT_VF_TRUST;
	else
		vf->flags &= ~BNXT_VF_TRUST;

	return 0;
}
Ejemplo n.º 6
0
int bnxt_set_vf_spoofchk(struct net_device *dev, int vf_id, bool setting)
{
	struct hwrm_func_cfg_input req = {0};
	struct bnxt *bp = netdev_priv(dev);
	struct bnxt_vf_info *vf;
	bool old_setting = false;
	u32 func_flags;
	int rc;

	if (bp->hwrm_spec_code < 0x10701)
		return -ENOTSUPP;

	rc = bnxt_vf_ndo_prep(bp, vf_id);
	if (rc)
		return rc;

	vf = &bp->pf.vf[vf_id];
	if (vf->flags & BNXT_VF_SPOOFCHK)
		old_setting = true;
	if (old_setting == setting)
		return 0;

	func_flags = vf->func_flags;
	if (setting)
		func_flags |= FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE;
	else
		func_flags |= FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE;
	/*TODO: if the driver supports VLAN filter on guest VLAN,
	 * the spoof check should also include vlan anti-spoofing
	 */
	bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1);
	req.fid = cpu_to_le16(vf->fw_fid);
	req.flags = cpu_to_le32(func_flags);
	rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
	if (!rc) {
		vf->func_flags = func_flags;
		if (setting)
			vf->flags |= BNXT_VF_SPOOFCHK;
		else
			vf->flags &= ~BNXT_VF_SPOOFCHK;
	}
	return rc;
}
Ejemplo n.º 7
0
int bnxt_set_vf_bw(struct net_device *dev, int vf_id, int min_tx_rate,
		   int max_tx_rate)
{
	struct hwrm_func_cfg_input req = {0};
	struct bnxt *bp = netdev_priv(dev);
	struct bnxt_vf_info *vf;
	u32 pf_link_speed;
	int rc;

	rc = bnxt_vf_ndo_prep(bp, vf_id);
	if (rc)
		return rc;

	vf = &bp->pf.vf[vf_id];
	pf_link_speed = bnxt_fw_to_ethtool_speed(bp->link_info.link_speed);
	if (max_tx_rate > pf_link_speed) {
		netdev_info(bp->dev, "max tx rate %d exceed PF link speed for VF %d\n",
			    max_tx_rate, vf_id);
		return -EINVAL;
	}

	if (min_tx_rate > pf_link_speed || min_tx_rate > max_tx_rate) {
		netdev_info(bp->dev, "min tx rate %d is invalid for VF %d\n",
			    min_tx_rate, vf_id);
		return -EINVAL;
	}
	if (min_tx_rate == vf->min_tx_rate && max_tx_rate == vf->max_tx_rate)
		return 0;
	bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1);
	req.fid = cpu_to_le16(vf->fw_fid);
	req.flags = cpu_to_le32(vf->func_flags);
	req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_MAX_BW);
	req.max_bw = cpu_to_le32(max_tx_rate);
	req.enables |= cpu_to_le32(FUNC_CFG_REQ_ENABLES_MIN_BW);
	req.min_bw = cpu_to_le32(min_tx_rate);
	rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
	if (!rc) {
		vf->min_tx_rate = min_tx_rate;
		vf->max_tx_rate = max_tx_rate;
	}
	return rc;
}
Ejemplo n.º 8
0
int bnxt_get_vf_config(struct net_device *dev, int vf_id,
		       struct ifla_vf_info *ivi)
{
	struct bnxt *bp = netdev_priv(dev);
	struct bnxt_vf_info *vf;
	int rc;

	rc = bnxt_vf_ndo_prep(bp, vf_id);
	if (rc)
		return rc;

	ivi->vf = vf_id;
	vf = &bp->pf.vf[vf_id];

	memcpy(&ivi->mac, vf->mac_addr, ETH_ALEN);
	ivi->max_tx_rate = vf->max_tx_rate;
	ivi->min_tx_rate = vf->min_tx_rate;
	ivi->vlan = vf->vlan;
	if (vf->flags & BNXT_VF_QOS)
		ivi->qos = vf->vlan >> VLAN_PRIO_SHIFT;
	else