diff mbox

[dpdk-dev,v3,2/3] net/ixgbe: add functions for VF management

Message ID 1474035333-7496-3-git-send-email-bernard.iremonger@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Bruce Richardson
Headers show

Commit Message

Iremonger, Bernard Sept. 16, 2016, 2:15 p.m. UTC
Add new functions to configure and manage VF's on an Intel 82559 NIC.

add ixgbe_vf_ping function.
add ixgbe_set_vf_vlan_anti_spoof function.
add ixgbe_set_vf_mac_anti_spoof function.

Signed-off-by: azelezniak <alexz@att.com>

add ixgbe_set_vf_vlan_insert function.
add ixgbe_set_tx_loopback function.
add ixgbe_set_all_queues_drop function.
add ixgbe_set_vf_split_drop_en function.
add ixgbe_set_vf_mac_addr function.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 166 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 166 insertions(+)
diff mbox

Patch

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index fb618ef..9875290 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -240,6 +240,8 @@  static void ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
 static void ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
 					   struct ether_addr *mac_addr);
+static int ixgbe_set_vf_mac_addr(struct rte_eth_dev *dev, uint16_t vf,
+				struct ether_addr *mac_addr);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config);
 
 /* For Virtual Function support */
@@ -280,6 +282,17 @@  static int ixgbe_set_pool_rx(struct rte_eth_dev *dev, uint16_t pool, uint8_t on)
 static int ixgbe_set_pool_tx(struct rte_eth_dev *dev, uint16_t pool, uint8_t on);
 static int ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 		uint64_t pool_mask, uint8_t vlan_on);
+static void ixgbe_set_vf_vlan_anti_spoof(struct rte_eth_dev *dev,
+		uint16_t vf, uint8_t on);
+static void ixgbe_set_vf_mac_anti_spoof(struct rte_eth_dev *dev,
+		uint16_t vf, uint8_t on);
+static int ixgbe_vf_ping(struct rte_eth_dev *dev, int32_t vf);
+static void ixgbe_set_vf_vlan_insert(struct rte_eth_dev *dev, uint16_t vf,
+		int vlan);
+static void ixgbe_set_tx_loopback(struct rte_eth_dev *dev, int on);
+static void ixgbe_set_all_queues_drop_en(struct rte_eth_dev *dev, int state);
+static void ixgbe_set_vf_split_drop_en(struct rte_eth_dev *dev, uint16_t vf,
+		int state);
 static int ixgbe_mirror_rule_set(struct rte_eth_dev *dev,
 		struct rte_eth_mirror_conf *mirror_conf,
 		uint8_t rule_id, uint8_t on);
@@ -562,6 +575,7 @@  static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.mac_addr_add         = ixgbe_add_rar,
 	.mac_addr_remove      = ixgbe_remove_rar,
 	.mac_addr_set         = ixgbe_set_default_mac_addr,
+	.set_vf_mac_addr      = ixgbe_set_vf_mac_addr,
 	.uc_hash_table_set    = ixgbe_uc_hash_table_set,
 	.uc_all_hash_table_set  = ixgbe_uc_all_hash_table_set,
 	.mirror_rule_set      = ixgbe_mirror_rule_set,
@@ -570,6 +584,13 @@  static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.set_vf_rx            = ixgbe_set_pool_rx,
 	.set_vf_tx            = ixgbe_set_pool_tx,
 	.set_vf_vlan_filter   = ixgbe_set_pool_vlan_filter,
+	.set_vf_vlan_anti_spoof  = ixgbe_set_vf_vlan_anti_spoof,
+	.set_vf_mac_anti_spoof   = ixgbe_set_vf_mac_anti_spoof,
+	.vf_ping              = ixgbe_vf_ping,
+	.set_vf_vlan_insert   = ixgbe_set_vf_vlan_insert,
+	.set_tx_loopback      = ixgbe_set_tx_loopback,
+	.set_all_queues_drop_en = ixgbe_set_all_queues_drop_en,
+	.set_vf_split_drop_en = ixgbe_set_vf_split_drop_en,
 	.set_queue_rate_limit = ixgbe_set_queue_rate_limit,
 	.set_vf_rate_limit    = ixgbe_set_vf_rate_limit,
 	.reta_update          = ixgbe_dev_rss_reta_update,
@@ -4069,6 +4090,22 @@  ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 }
 
 static int
+ixgbe_set_vf_mac_addr(struct rte_eth_dev *dev, uint16_t vf, struct ether_addr *mac_addr)
+{
+	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_vf_info *vfinfo =
+		*(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
+	int rar_entry = hw->mac.num_rar_entries - (vf + 1);
+	uint8_t *new_mac = (uint8_t *)(mac_addr);
+
+	if (is_valid_assigned_ether_addr((struct ether_addr *)new_mac)) {
+		rte_memcpy(vfinfo[vf].vf_mac_addresses, new_mac, ETHER_ADDR_LEN);
+		return hw->mac.ops.set_rar(hw, rar_entry, new_mac, vf, IXGBE_RAH_AV);
+	}
+	return -1;
+}
+
+static int
 ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 {
 	uint32_t hlreg0;
@@ -4661,6 +4698,135 @@  ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 	return ret;
 }
 
+static void
+ixgbe_set_vf_vlan_anti_spoof(struct rte_eth_dev *dev,
+			uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw =
+			IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	struct ixgbe_mac_info *mac = &hw->mac;
+
+	mac->ops.set_vlan_anti_spoofing(hw, on, vf);
+}
+
+static void
+ixgbe_set_vf_mac_anti_spoof(struct rte_eth_dev *dev,
+			uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_mac_info *mac = &hw->mac;
+
+	mac->ops.set_mac_anti_spoofing(hw, on, vf);
+}
+
+static int
+ixgbe_vf_ping(struct rte_eth_dev *dev, int32_t vf)
+{
+	int ret = 0;
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	struct ixgbe_vf_info *vfinfo =
+		*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
+
+	u32 ping;
+	int i;
+
+	for (i = 0; i < dev->pci_dev->max_vfs; i++) {
+		ping = IXGBE_PF_CONTROL_MSG;
+		if (vfinfo[i].clear_to_send)
+			ping |= IXGBE_VT_MSGTYPE_CTS;
+
+		/* ping every VF or only one specified */
+		if (vf < 0 || vf == i)
+			ixgbe_write_mbx(hw, &ping, 1, i);
+	}
+
+	return ret;
+}
+
+static void
+ixgbe_set_vf_vlan_insert(struct rte_eth_dev *dev, uint16_t vf, int vlan)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t ctrl;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ctrl = IXGBE_READ_REG(hw, IXGBE_VMVIR(vf));
+	if (vlan) {
+		ctrl = vlan;
+		ctrl |= IXGBE_VMVIR_VLANA_DEFAULT;
+	} else {
+		ctrl = 0;
+	}
+
+	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), ctrl);
+}
+
+static void
+ixgbe_set_tx_loopback(struct rte_eth_dev *dev, int on)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t ctrl;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ctrl = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+	/* enable or disable VMDQ loopback */
+	if (on)
+		ctrl |= IXGBE_PFDTXGSWC_VT_LBEN;
+	else
+		ctrl &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, ctrl);
+}
+
+static void
+ixgbe_set_all_queues_drop_en(struct rte_eth_dev *dev, int state)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t reg_value;
+	int i;
+	int num_queues = (int)(IXGBE_QDE_IDX_MASK >> IXGBE_QDE_IDX_SHIFT);
+
+	PMD_INIT_FUNC_TRACE();
+
+	for (i = 0; i <= num_queues; i++) {
+		reg_value = IXGBE_QDE_WRITE |
+				(i << IXGBE_QDE_IDX_SHIFT) |
+				(state & IXGBE_QDE_ENABLE);
+		IXGBE_WRITE_REG(hw, IXGBE_QDE, reg_value);
+	}
+}
+
+static void
+ixgbe_set_vf_split_drop_en(struct rte_eth_dev *dev, uint16_t vf, int state)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t reg_value;
+
+	PMD_INIT_FUNC_TRACE();
+
+	/* only support VF's 0 to 63 */
+	if (vf > 63)
+		return;
+
+	reg_value = IXGBE_READ_REG(hw, IXGBE_SRRCTL(vf));
+	if (state)
+		reg_value |= IXGBE_SRRCTL_DROP_EN;
+	else
+		reg_value &= ~IXGBE_SRRCTL_DROP_EN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(vf), reg_value);
+}
+
 #define IXGBE_MRCTL_VPME  0x01 /* Virtual Pool Mirroring. */
 #define IXGBE_MRCTL_UPME  0x02 /* Uplink Port Mirroring. */
 #define IXGBE_MRCTL_DPME  0x04 /* Downlink Port Mirroring. */