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 at 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 at intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 166 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 166 insertions(+)

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. */
-- 
2.9.0

Reply via email to