diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_switch.c')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_switch.c | 56 |
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 | */ | ||
2151 | static struct ice_fltr_mgmt_list_entry * | ||
2152 | ice_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 | |||
2153 | ice_remove_mac(struct ice_hw *hw, struct list_head *m_list) | 2185 | ice_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); |