-#define IXGBE_MRCTL_VPME 0x01 /* Virtual Pool Mirroring. */
-#define IXGBE_MRCTL_UPME 0x02 /* Uplink Port Mirroring. */
-#define IXGBE_MRCTL_DPME 0x04 /* Downlink Port Mirroring. */
-#define IXGBE_MRCTL_VLME 0x08 /* VLAN Mirroring. */
-#define IXGBE_INVALID_MIRROR_TYPE(mirror_type) \
- ((mirror_type) & ~(uint8_t)(ETH_MIRROR_VIRTUAL_POOL_UP | \
- ETH_MIRROR_UPLINK_PORT | ETH_MIRROR_DOWNLINK_PORT | ETH_MIRROR_VLAN))
-
-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)
-{
- uint32_t mr_ctl, vlvf;
- uint32_t mp_lsb = 0;
- uint32_t mv_msb = 0;
- uint32_t mv_lsb = 0;
- uint32_t mp_msb = 0;
- uint8_t i = 0;
- int reg_index = 0;
- uint64_t vlan_mask = 0;
-
- const uint8_t pool_mask_offset = 32;
- const uint8_t vlan_mask_offset = 32;
- const uint8_t dst_pool_offset = 8;
- const uint8_t rule_mr_offset = 4;
- const uint8_t mirror_rule_mask = 0x0F;
-
- struct ixgbe_mirror_info *mr_info =
- (IXGBE_DEV_PRIVATE_TO_PFDATA(dev->data->dev_private));
- struct ixgbe_hw *hw =
- IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- uint8_t mirror_type = 0;
-
- if (ixgbe_vt_check(hw) < 0)
- return -ENOTSUP;
-
- if (rule_id >= IXGBE_MAX_MIRROR_RULES)
- return -EINVAL;
-
- if (IXGBE_INVALID_MIRROR_TYPE(mirror_conf->rule_type)) {
- PMD_DRV_LOG(ERR, "unsupported mirror type 0x%x.",
- mirror_conf->rule_type);
- return -EINVAL;
- }
-
- if (mirror_conf->rule_type & ETH_MIRROR_VLAN) {
- mirror_type |= IXGBE_MRCTL_VLME;
- /* Check if vlan id is valid and find conresponding VLAN ID
- * index in VLVF
- */
- for (i = 0; i < IXGBE_VLVF_ENTRIES; i++) {
- if (mirror_conf->vlan.vlan_mask & (1ULL << i)) {
- /* search vlan id related pool vlan filter
- * index
- */
- reg_index = ixgbe_find_vlvf_slot(
- hw,
- mirror_conf->vlan.vlan_id[i],
- false);
- if (reg_index < 0)
- return -EINVAL;
- vlvf = IXGBE_READ_REG(hw,
- IXGBE_VLVF(reg_index));
- if ((vlvf & IXGBE_VLVF_VIEN) &&
- ((vlvf & IXGBE_VLVF_VLANID_MASK) ==
- mirror_conf->vlan.vlan_id[i]))
- vlan_mask |= (1ULL << reg_index);
- else
- return -EINVAL;
- }
- }
-
- if (on) {
- mv_lsb = vlan_mask & 0xFFFFFFFF;
- mv_msb = vlan_mask >> vlan_mask_offset;
-
- mr_info->mr_conf[rule_id].vlan.vlan_mask =
- mirror_conf->vlan.vlan_mask;
- for (i = 0; i < ETH_VMDQ_MAX_VLAN_FILTERS; i++) {
- if (mirror_conf->vlan.vlan_mask & (1ULL << i))
- mr_info->mr_conf[rule_id].vlan.vlan_id[i] =
- mirror_conf->vlan.vlan_id[i];
- }
- } else {
- mv_lsb = 0;
- mv_msb = 0;
- mr_info->mr_conf[rule_id].vlan.vlan_mask = 0;
- for (i = 0; i < ETH_VMDQ_MAX_VLAN_FILTERS; i++)
- mr_info->mr_conf[rule_id].vlan.vlan_id[i] = 0;
- }
- }
-
- /**
- * if enable pool mirror, write related pool mask register,if disable
- * pool mirror, clear PFMRVM register
- */
- if (mirror_conf->rule_type & ETH_MIRROR_VIRTUAL_POOL_UP) {
- mirror_type |= IXGBE_MRCTL_VPME;
- if (on) {
- mp_lsb = mirror_conf->pool_mask & 0xFFFFFFFF;
- mp_msb = mirror_conf->pool_mask >> pool_mask_offset;
- mr_info->mr_conf[rule_id].pool_mask =
- mirror_conf->pool_mask;
-
- } else {
- mp_lsb = 0;
- mp_msb = 0;
- mr_info->mr_conf[rule_id].pool_mask = 0;
- }
- }
- if (mirror_conf->rule_type & ETH_MIRROR_UPLINK_PORT)
- mirror_type |= IXGBE_MRCTL_UPME;
- if (mirror_conf->rule_type & ETH_MIRROR_DOWNLINK_PORT)
- mirror_type |= IXGBE_MRCTL_DPME;
-
- /* read mirror control register and recalculate it */
- mr_ctl = IXGBE_READ_REG(hw, IXGBE_MRCTL(rule_id));
-
- if (on) {
- mr_ctl |= mirror_type;
- mr_ctl &= mirror_rule_mask;
- mr_ctl |= mirror_conf->dst_pool << dst_pool_offset;
- } else {
- mr_ctl &= ~(mirror_conf->rule_type & mirror_rule_mask);
- }
-
- mr_info->mr_conf[rule_id].rule_type = mirror_conf->rule_type;
- mr_info->mr_conf[rule_id].dst_pool = mirror_conf->dst_pool;
-
- /* write mirrror control register */
- IXGBE_WRITE_REG(hw, IXGBE_MRCTL(rule_id), mr_ctl);
-
- /* write pool mirrror control register */
- if (mirror_conf->rule_type & ETH_MIRROR_VIRTUAL_POOL_UP) {
- IXGBE_WRITE_REG(hw, IXGBE_VMRVM(rule_id), mp_lsb);
- IXGBE_WRITE_REG(hw, IXGBE_VMRVM(rule_id + rule_mr_offset),
- mp_msb);
- }
- /* write VLAN mirrror control register */
- if (mirror_conf->rule_type & ETH_MIRROR_VLAN) {
- IXGBE_WRITE_REG(hw, IXGBE_VMRVLAN(rule_id), mv_lsb);
- IXGBE_WRITE_REG(hw, IXGBE_VMRVLAN(rule_id + rule_mr_offset),
- mv_msb);
- }
-
- return 0;
-}
-
-static int
-ixgbe_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t rule_id)
-{
- int mr_ctl = 0;
- uint32_t lsb_val = 0;
- uint32_t msb_val = 0;
- const uint8_t rule_mr_offset = 4;
-
- struct ixgbe_hw *hw =
- IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct ixgbe_mirror_info *mr_info =
- (IXGBE_DEV_PRIVATE_TO_PFDATA(dev->data->dev_private));
-
- if (ixgbe_vt_check(hw) < 0)
- return -ENOTSUP;
-
- if (rule_id >= IXGBE_MAX_MIRROR_RULES)
- return -EINVAL;
-
- memset(&mr_info->mr_conf[rule_id], 0,
- sizeof(struct rte_eth_mirror_conf));
-
- /* clear PFVMCTL register */
- IXGBE_WRITE_REG(hw, IXGBE_MRCTL(rule_id), mr_ctl);
-
- /* clear pool mask register */
- IXGBE_WRITE_REG(hw, IXGBE_VMRVM(rule_id), lsb_val);
- IXGBE_WRITE_REG(hw, IXGBE_VMRVM(rule_id + rule_mr_offset), msb_val);
-
- /* clear vlan mask register */
- IXGBE_WRITE_REG(hw, IXGBE_VMRVLAN(rule_id), lsb_val);
- IXGBE_WRITE_REG(hw, IXGBE_VMRVLAN(rule_id + rule_mr_offset), msb_val);
-
- return 0;
-}
-