Commit 390889a4 authored by Amritha Nambiar's avatar Amritha Nambiar Committed by Tony Nguyen
Browse files

ice: Support drop action



Currently the drop action is supported only in switchdev mode.
Add support for offloading receive filters with action drop
in ADQ/non-ADQ modes. This is in addition to other actions
such as forwarding to a VSI (ADQ) or a queue (ADQ/non-ADQ).

Also renamed 'ch_vsi' to 'dest_vsi' as it is valid for multiple
actions such as forward to vsi/queue which may/may not create a
channel vsi.

Reviewed-by: default avatarSridhar Samudrala <sridhar.samudrala@intel.com>
Signed-off-by: default avatarAmritha Nambiar <amritha.nambiar@intel.com>
Tested-by: default avatarBharathi Sreenivas <bharathi.sreenivas@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 7d8d7754
Loading
Loading
Loading
Loading
+30 −20
Original line number Diff line number Diff line
@@ -792,7 +792,7 @@ static struct ice_vsi *
ice_tc_forward_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *tc_fltr)
{
	struct ice_rx_ring *ring = NULL;
	struct ice_vsi *ch_vsi = NULL;
	struct ice_vsi *dest_vsi = NULL;
	struct ice_pf *pf = vsi->back;
	struct device *dev;
	u32 tc_class;
@@ -810,7 +810,7 @@ ice_tc_forward_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *tc_fltr)
			return ERR_PTR(-EOPNOTSUPP);
		}
		/* Locate ADQ VSI depending on hw_tc number */
		ch_vsi = vsi->tc_map_vsi[tc_class];
		dest_vsi = vsi->tc_map_vsi[tc_class];
		break;
	case ICE_FWD_TO_Q:
		/* Locate the Rx queue */
@@ -824,7 +824,7 @@ ice_tc_forward_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *tc_fltr)
		/* Determine destination VSI even though the action is
		 * FWD_TO_QUEUE, because QUEUE is associated with VSI
		 */
		ch_vsi = tc_fltr->dest_vsi;
		dest_vsi = tc_fltr->dest_vsi;
		break;
	default:
		dev_err(dev,
@@ -832,13 +832,13 @@ ice_tc_forward_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *tc_fltr)
			tc_fltr->action.fltr_act);
		return ERR_PTR(-EINVAL);
	}
	/* Must have valid ch_vsi (it could be main VSI or ADQ VSI) */
	if (!ch_vsi) {
	/* Must have valid dest_vsi (it could be main VSI or ADQ VSI) */
	if (!dest_vsi) {
		dev_err(dev,
			"Unable to add filter because specified destination VSI doesn't exist\n");
		return ERR_PTR(-EINVAL);
	}
	return ch_vsi;
	return dest_vsi;
}

/**
@@ -860,7 +860,7 @@ ice_add_tc_flower_adv_fltr(struct ice_vsi *vsi,
	struct ice_pf *pf = vsi->back;
	struct ice_hw *hw = &pf->hw;
	u32 flags = tc_fltr->flags;
	struct ice_vsi *ch_vsi;
	struct ice_vsi *dest_vsi;
	struct device *dev;
	u16 lkups_cnt = 0;
	u16 l4_proto = 0;
@@ -883,9 +883,11 @@ ice_add_tc_flower_adv_fltr(struct ice_vsi *vsi,
	}

	/* validate forwarding action VSI and queue */
	ch_vsi = ice_tc_forward_action(vsi, tc_fltr);
	if (IS_ERR(ch_vsi))
		return PTR_ERR(ch_vsi);
	if (ice_is_forward_action(tc_fltr->action.fltr_act)) {
		dest_vsi = ice_tc_forward_action(vsi, tc_fltr);
		if (IS_ERR(dest_vsi))
			return PTR_ERR(dest_vsi);
	}

	lkups_cnt = ice_tc_count_lkups(flags, headers, tc_fltr);
	list = kcalloc(lkups_cnt, sizeof(*list), GFP_ATOMIC);
@@ -904,7 +906,7 @@ ice_add_tc_flower_adv_fltr(struct ice_vsi *vsi,

	switch (tc_fltr->action.fltr_act) {
	case ICE_FWD_TO_VSI:
		rule_info.sw_act.vsi_handle = ch_vsi->idx;
		rule_info.sw_act.vsi_handle = dest_vsi->idx;
		rule_info.priority = ICE_SWITCH_FLTR_PRIO_VSI;
		rule_info.sw_act.src = hw->pf_id;
		rule_info.rx = true;
@@ -915,7 +917,7 @@ ice_add_tc_flower_adv_fltr(struct ice_vsi *vsi,
	case ICE_FWD_TO_Q:
		/* HW queue number in global space */
		rule_info.sw_act.fwd_id.q_id = tc_fltr->action.fwd.q.hw_queue;
		rule_info.sw_act.vsi_handle = ch_vsi->idx;
		rule_info.sw_act.vsi_handle = dest_vsi->idx;
		rule_info.priority = ICE_SWITCH_FLTR_PRIO_QUEUE;
		rule_info.sw_act.src = hw->pf_id;
		rule_info.rx = true;
@@ -923,14 +925,15 @@ ice_add_tc_flower_adv_fltr(struct ice_vsi *vsi,
			tc_fltr->action.fwd.q.queue,
			tc_fltr->action.fwd.q.hw_queue, lkups_cnt);
		break;
	default:
		rule_info.sw_act.flag |= ICE_FLTR_TX;
		/* In case of Tx (LOOKUP_TX), src needs to be src VSI */
		rule_info.sw_act.src = vsi->idx;
		/* 'Rx' is false, direction of rule(LOOKUPTRX) */
		rule_info.rx = false;
	case ICE_DROP_PACKET:
		rule_info.sw_act.flag |= ICE_FLTR_RX;
		rule_info.sw_act.src = hw->pf_id;
		rule_info.rx = true;
		rule_info.priority = ICE_SWITCH_FLTR_PRIO_VSI;
		break;
	default:
		ret = -EOPNOTSUPP;
		goto exit;
	}

	ret = ice_add_adv_rule(hw, list, lkups_cnt, &rule_info, &rule_added);
@@ -953,11 +956,11 @@ ice_add_tc_flower_adv_fltr(struct ice_vsi *vsi,
	tc_fltr->dest_vsi_handle = rule_added.vsi_handle;
	if (tc_fltr->action.fltr_act == ICE_FWD_TO_VSI ||
	    tc_fltr->action.fltr_act == ICE_FWD_TO_Q) {
		tc_fltr->dest_vsi = ch_vsi;
		tc_fltr->dest_vsi = dest_vsi;
		/* keep track of advanced switch filter for
		 * destination VSI
		 */
		ch_vsi->num_chnl_fltr++;
		dest_vsi->num_chnl_fltr++;

		/* keeps track of channel filters for PF VSI */
		if (vsi->type == ICE_VSI_PF &&
@@ -978,6 +981,10 @@ ice_add_tc_flower_adv_fltr(struct ice_vsi *vsi,
			tc_fltr->action.fwd.q.hw_queue, rule_added.rid,
			rule_added.rule_id);
		break;
	case ICE_DROP_PACKET:
		dev_dbg(dev, "added switch rule (lkups_cnt %u, flags 0x%x), action is drop, rid %u, rule_id %u\n",
			lkups_cnt, flags, rule_added.rid, rule_added.rule_id);
		break;
	default:
		break;
	}
@@ -1712,6 +1719,9 @@ ice_tc_parse_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr,
	case FLOW_ACTION_RX_QUEUE_MAPPING:
		/* forward to queue */
		return ice_tc_forward_to_queue(vsi, fltr, act);
	case FLOW_ACTION_DROP:
		fltr->action.fltr_act = ICE_DROP_PACKET;
		return 0;
	default:
		NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported TC action");
		return -EOPNOTSUPP;
+10 −0
Original line number Diff line number Diff line
@@ -211,4 +211,14 @@ ice_del_cls_flower(struct ice_vsi *vsi, struct flow_cls_offload *cls_flower);
void ice_replay_tc_fltrs(struct ice_pf *pf);
bool ice_is_tunnel_supported(struct net_device *dev);

static inline bool ice_is_forward_action(enum ice_sw_fwd_act_type fltr_act)
{
	switch (fltr_act) {
	case ICE_FWD_TO_VSI:
	case ICE_FWD_TO_Q:
		return true;
	default:
		return false;
	}
}
#endif /* _ICE_TC_LIB_H_ */