Commit bd676b29 authored by Michal Swiatkowski's avatar Michal Swiatkowski Committed by Tony Nguyen

ice: allow changing lan_en and lb_en on dflt rules

There is no way to change default lan_en and lb_en flags while
adding new rule. Add function that allows changing these flags
on ICE_SW_LKUP_DFLT recipe and any rule id.

lan_en allows packet to go outside if rule is matched. Clearing
this bit will block packet from sending it outside.

lb_en allows packet to be forwarded to other VSI. Clearing
this bit will block packet from forwarding it to other VSI.
Signed-off-by: default avatarMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Tested-by: default avatarSandeep Penigalapati <sandeep.penigalapati@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent ff5411ef
...@@ -395,3 +395,83 @@ enum ice_status ice_fltr_remove_eth(struct ice_vsi *vsi, u16 ethertype, ...@@ -395,3 +395,83 @@ enum ice_status ice_fltr_remove_eth(struct ice_vsi *vsi, u16 ethertype,
return ice_fltr_prepare_eth(vsi, ethertype, flag, action, return ice_fltr_prepare_eth(vsi, ethertype, flag, action,
ice_fltr_remove_eth_list); ice_fltr_remove_eth_list);
} }
/**
* ice_fltr_update_rule_flags - update lan_en/lb_en flags
* @hw: pointer to hw
* @rule_id: id of rule being updated
* @recipe_id: recipe id of rule
* @act: current action field
* @type: Rx or Tx
* @src: source VSI
* @new_flags: combinations of lb_en and lan_en
*/
static enum ice_status
ice_fltr_update_rule_flags(struct ice_hw *hw, u16 rule_id, u16 recipe_id,
u32 act, u16 type, u16 src, u32 new_flags)
{
struct ice_aqc_sw_rules_elem *s_rule;
enum ice_status err;
u32 flags_mask;
s_rule = kzalloc(ICE_SW_RULE_RX_TX_NO_HDR_SIZE, GFP_KERNEL);
if (!s_rule)
return ICE_ERR_NO_MEMORY;
flags_mask = ICE_SINGLE_ACT_LB_ENABLE | ICE_SINGLE_ACT_LAN_ENABLE;
act &= ~flags_mask;
act |= (flags_mask & new_flags);
s_rule->pdata.lkup_tx_rx.recipe_id = cpu_to_le16(recipe_id);
s_rule->pdata.lkup_tx_rx.index = cpu_to_le16(rule_id);
s_rule->pdata.lkup_tx_rx.act = cpu_to_le32(act);
if (type & ICE_FLTR_RX) {
s_rule->pdata.lkup_tx_rx.src =
cpu_to_le16(hw->port_info->lport);
s_rule->type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);
} else {
s_rule->pdata.lkup_tx_rx.src = cpu_to_le16(src);
s_rule->type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
}
err = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_NO_HDR_SIZE, 1,
ice_aqc_opc_update_sw_rules, NULL);
kfree(s_rule);
return err;
}
/**
* ice_fltr_build_action - build action for rule
* @vsi_id: id of VSI which is use to build action
*/
static u32 ice_fltr_build_action(u16 vsi_id)
{
return ((vsi_id << ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M) |
ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
}
/**
* ice_fltr_update_flags_dflt_rule - update flags on default rule
* @vsi: pointer to VSI
* @rule_id: id of rule
* @direction: Tx or Rx
* @new_flags: flags to update
*
* Function updates flags on default rule with ICE_SW_LKUP_DFLT.
*
* Flags should be a combination of ICE_SINGLE_ACT_LB_ENABLE and
* ICE_SINGLE_ACT_LAN_ENABLE.
*/
enum ice_status
ice_fltr_update_flags_dflt_rule(struct ice_vsi *vsi, u16 rule_id, u8 direction,
u32 new_flags)
{
u32 action = ice_fltr_build_action(vsi->vsi_num);
struct ice_hw *hw = &vsi->back->hw;
return ice_fltr_update_rule_flags(hw, rule_id, ICE_SW_LKUP_DFLT, action,
direction, vsi->vsi_num, new_flags);
}
...@@ -36,4 +36,11 @@ enum ice_status ...@@ -36,4 +36,11 @@ enum ice_status
ice_fltr_remove_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag, ice_fltr_remove_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
enum ice_sw_fwd_act_type action); enum ice_sw_fwd_act_type action);
void ice_fltr_remove_all(struct ice_vsi *vsi); void ice_fltr_remove_all(struct ice_vsi *vsi);
enum ice_status
ice_fltr_update_flags(struct ice_vsi *vsi, u16 rule_id, u16 recipe_id,
u32 new_flags);
enum ice_status
ice_fltr_update_flags_dflt_rule(struct ice_vsi *vsi, u16 rule_id, u8 direction,
u32 new_flags);
#endif #endif
...@@ -518,7 +518,7 @@ ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id, ...@@ -518,7 +518,7 @@ ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
* *
* Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware
*/ */
static enum ice_status enum ice_status
ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz, ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd) u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd)
{ {
......
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
#define ICE_VSI_INVAL_ID 0xffff #define ICE_VSI_INVAL_ID 0xffff
#define ICE_INVAL_Q_HANDLE 0xFFFF #define ICE_INVAL_Q_HANDLE 0xFFFF
#define ICE_SW_RULE_RX_TX_NO_HDR_SIZE \
(offsetof(struct ice_aqc_sw_rules_elem, pdata.lkup_tx_rx.hdr))
/* VSI context structure for add/get/update/free operations */ /* VSI context structure for add/get/update/free operations */
struct ice_vsi_ctx { struct ice_vsi_ctx {
u16 vsi_num; u16 vsi_num;
...@@ -251,4 +254,7 @@ u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle); ...@@ -251,4 +254,7 @@ u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle);
enum ice_status ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle); enum ice_status ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle);
void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw); void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw);
enum ice_status
ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd);
#endif /* _ICE_SWITCH_H_ */ #endif /* _ICE_SWITCH_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment