aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ice/ice_switch.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_switch.c')
-rw-r--r--drivers/net/ethernet/intel/ice/ice_switch.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c
index 8271fd651725..99cf527d2b1a 100644
--- a/drivers/net/ethernet/intel/ice/ice_switch.c
+++ b/drivers/net/ethernet/intel/ice/ice_switch.c
@@ -2137,6 +2137,38 @@ out:
2137} 2137}
2138 2138
2139/** 2139/**
2140 * ice_find_ucast_rule_entry - Search for a unicast MAC filter rule entry
2141 * @hw: pointer to the hardware structure
2142 * @recp_id: lookup type for which the specified rule needs to be searched
2143 * @f_info: rule information
2144 *
2145 * Helper function to search for a unicast rule entry - this is to be used
2146 * to remove unicast MAC filter that is not shared with other VSIs on the
2147 * PF switch.
2148 *
2149 * Returns pointer to entry storing the rule if found
2150 */
2151static struct ice_fltr_mgmt_list_entry *
2152ice_find_ucast_rule_entry(struct ice_hw *hw, u8 recp_id,
2153 struct ice_fltr_info *f_info)
2154{
2155 struct ice_switch_info *sw = hw->switch_info;
2156 struct ice_fltr_mgmt_list_entry *list_itr;
2157 struct list_head *list_head;
2158
2159 list_head = &sw->recp_list[recp_id].filt_rules;
2160 list_for_each_entry(list_itr, list_head, list_entry) {
2161 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
2162 sizeof(f_info->l_data)) &&
2163 f_info->fwd_id.hw_vsi_id ==
2164 list_itr->fltr_info.fwd_id.hw_vsi_id &&
2165 f_info->flag == list_itr->fltr_info.flag)
2166 return list_itr;
2167 }
2168 return NULL;
2169}
2170
2171/**
2140 * ice_remove_mac - remove a MAC address based filter rule 2172 * ice_remove_mac - remove a MAC address based filter rule
2141 * @hw: pointer to the hardware structure 2173 * @hw: pointer to the hardware structure
2142 * @m_list: list of MAC addresses and forwarding information 2174 * @m_list: list of MAC addresses and forwarding information
@@ -2153,15 +2185,39 @@ enum ice_status
2153ice_remove_mac(struct ice_hw *hw, struct list_head *m_list) 2185ice_remove_mac(struct ice_hw *hw, struct list_head *m_list)
2154{ 2186{
2155 struct ice_fltr_list_entry *list_itr, *tmp; 2187 struct ice_fltr_list_entry *list_itr, *tmp;
2188 struct mutex *rule_lock; /* Lock to protect filter rule list */
2156 2189
2157 if (!m_list) 2190 if (!m_list)
2158 return ICE_ERR_PARAM; 2191 return ICE_ERR_PARAM;
2159 2192
2193 rule_lock = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
2160 list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) { 2194 list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) {
2161 enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type; 2195 enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
2196 u8 *add = &list_itr->fltr_info.l_data.mac.mac_addr[0];
2197 u16 vsi_handle;
2162 2198
2163 if (l_type != ICE_SW_LKUP_MAC) 2199 if (l_type != ICE_SW_LKUP_MAC)
2164 return ICE_ERR_PARAM; 2200 return ICE_ERR_PARAM;
2201
2202 vsi_handle = list_itr->fltr_info.vsi_handle;
2203 if (!ice_is_vsi_valid(hw, vsi_handle))
2204 return ICE_ERR_PARAM;
2205
2206 list_itr->fltr_info.fwd_id.hw_vsi_id =
2207 ice_get_hw_vsi_num(hw, vsi_handle);
2208 if (is_unicast_ether_addr(add) && !hw->ucast_shared) {
2209 /* Don't remove the unicast address that belongs to
2210 * another VSI on the switch, since it is not being
2211 * shared...
2212 */
2213 mutex_lock(rule_lock);
2214 if (!ice_find_ucast_rule_entry(hw, ICE_SW_LKUP_MAC,
2215 &list_itr->fltr_info)) {
2216 mutex_unlock(rule_lock);
2217 return ICE_ERR_DOES_NOT_EXIST;
2218 }
2219 mutex_unlock(rule_lock);
2220 }
2165 list_itr->status = ice_remove_rule_internal(hw, 2221 list_itr->status = ice_remove_rule_internal(hw,
2166 ICE_SW_LKUP_MAC, 2222 ICE_SW_LKUP_MAC,
2167 list_itr); 2223 list_itr);