Merge branch 'ice-fixups'
Tony Nguyen says: ==================== ice-fixups This series handles a handful of cleanups for the ice driver. Ivan fixed a problem on the VSI during a release, fixing a MAC address setting, and a broken IFF_ALLMULTI handling. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
4298a62ff8
4 changed files with 128 additions and 40 deletions
|
|
@ -301,7 +301,6 @@ enum ice_vsi_state {
|
|||
ICE_VSI_NETDEV_REGISTERED,
|
||||
ICE_VSI_UMAC_FLTR_CHANGED,
|
||||
ICE_VSI_MMAC_FLTR_CHANGED,
|
||||
ICE_VSI_VLAN_FLTR_CHANGED,
|
||||
ICE_VSI_PROMISC_CHANGED,
|
||||
ICE_VSI_STATE_NBITS /* must be last */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -58,7 +58,16 @@ int
|
|||
ice_fltr_set_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi,
|
||||
u8 promisc_mask)
|
||||
{
|
||||
return ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, false);
|
||||
struct ice_pf *pf = hw->back;
|
||||
int result;
|
||||
|
||||
result = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, false);
|
||||
if (result)
|
||||
dev_err(ice_pf_to_dev(pf),
|
||||
"Error setting promisc mode on VSI %i (rc=%d)\n",
|
||||
vsi->vsi_num, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -73,7 +82,16 @@ int
|
|||
ice_fltr_clear_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi,
|
||||
u8 promisc_mask)
|
||||
{
|
||||
return ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, true);
|
||||
struct ice_pf *pf = hw->back;
|
||||
int result;
|
||||
|
||||
result = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, true);
|
||||
if (result)
|
||||
dev_err(ice_pf_to_dev(pf),
|
||||
"Error clearing promisc mode on VSI %i (rc=%d)\n",
|
||||
vsi->vsi_num, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -87,7 +105,16 @@ int
|
|||
ice_fltr_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
|
||||
u16 vid)
|
||||
{
|
||||
return ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
|
||||
struct ice_pf *pf = hw->back;
|
||||
int result;
|
||||
|
||||
result = ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
|
||||
if (result)
|
||||
dev_err(ice_pf_to_dev(pf),
|
||||
"Error clearing promisc mode on VSI %i for VID %u (rc=%d)\n",
|
||||
ice_get_hw_vsi_num(hw, vsi_handle), vid, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -101,7 +128,16 @@ int
|
|||
ice_fltr_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
|
||||
u16 vid)
|
||||
{
|
||||
return ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
|
||||
struct ice_pf *pf = hw->back;
|
||||
int result;
|
||||
|
||||
result = ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
|
||||
if (result)
|
||||
dev_err(ice_pf_to_dev(pf),
|
||||
"Error setting promisc mode on VSI %i for VID %u (rc=%d)\n",
|
||||
ice_get_hw_vsi_num(hw, vsi_handle), vid, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2983,6 +2983,8 @@ int ice_vsi_release(struct ice_vsi *vsi)
|
|||
}
|
||||
}
|
||||
|
||||
if (ice_is_vsi_dflt_vsi(pf->first_sw, vsi))
|
||||
ice_clear_dflt_vsi(pf->first_sw);
|
||||
ice_fltr_remove_all(vsi);
|
||||
ice_rm_vsi_lan_cfg(vsi->port_info, vsi->idx);
|
||||
err = ice_rm_vsi_rdma_cfg(vsi->port_info, vsi->idx);
|
||||
|
|
|
|||
|
|
@ -243,8 +243,7 @@ static int ice_add_mac_to_unsync_list(struct net_device *netdev, const u8 *addr)
|
|||
static bool ice_vsi_fltr_changed(struct ice_vsi *vsi)
|
||||
{
|
||||
return test_bit(ICE_VSI_UMAC_FLTR_CHANGED, vsi->state) ||
|
||||
test_bit(ICE_VSI_MMAC_FLTR_CHANGED, vsi->state) ||
|
||||
test_bit(ICE_VSI_VLAN_FLTR_CHANGED, vsi->state);
|
||||
test_bit(ICE_VSI_MMAC_FLTR_CHANGED, vsi->state);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -260,10 +259,15 @@ static int ice_set_promisc(struct ice_vsi *vsi, u8 promisc_m)
|
|||
if (vsi->type != ICE_VSI_PF)
|
||||
return 0;
|
||||
|
||||
if (ice_vsi_has_non_zero_vlans(vsi))
|
||||
status = ice_fltr_set_vlan_vsi_promisc(&vsi->back->hw, vsi, promisc_m);
|
||||
else
|
||||
status = ice_fltr_set_vsi_promisc(&vsi->back->hw, vsi->idx, promisc_m, 0);
|
||||
if (ice_vsi_has_non_zero_vlans(vsi)) {
|
||||
promisc_m |= (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX);
|
||||
status = ice_fltr_set_vlan_vsi_promisc(&vsi->back->hw, vsi,
|
||||
promisc_m);
|
||||
} else {
|
||||
status = ice_fltr_set_vsi_promisc(&vsi->back->hw, vsi->idx,
|
||||
promisc_m, 0);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -280,10 +284,15 @@ static int ice_clear_promisc(struct ice_vsi *vsi, u8 promisc_m)
|
|||
if (vsi->type != ICE_VSI_PF)
|
||||
return 0;
|
||||
|
||||
if (ice_vsi_has_non_zero_vlans(vsi))
|
||||
status = ice_fltr_clear_vlan_vsi_promisc(&vsi->back->hw, vsi, promisc_m);
|
||||
else
|
||||
status = ice_fltr_clear_vsi_promisc(&vsi->back->hw, vsi->idx, promisc_m, 0);
|
||||
if (ice_vsi_has_non_zero_vlans(vsi)) {
|
||||
promisc_m |= (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX);
|
||||
status = ice_fltr_clear_vlan_vsi_promisc(&vsi->back->hw, vsi,
|
||||
promisc_m);
|
||||
} else {
|
||||
status = ice_fltr_clear_vsi_promisc(&vsi->back->hw, vsi->idx,
|
||||
promisc_m, 0);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -302,7 +311,6 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi)
|
|||
struct ice_pf *pf = vsi->back;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
u32 changed_flags = 0;
|
||||
u8 promisc_m;
|
||||
int err;
|
||||
|
||||
if (!vsi->netdev)
|
||||
|
|
@ -320,7 +328,6 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi)
|
|||
if (ice_vsi_fltr_changed(vsi)) {
|
||||
clear_bit(ICE_VSI_UMAC_FLTR_CHANGED, vsi->state);
|
||||
clear_bit(ICE_VSI_MMAC_FLTR_CHANGED, vsi->state);
|
||||
clear_bit(ICE_VSI_VLAN_FLTR_CHANGED, vsi->state);
|
||||
|
||||
/* grab the netdev's addr_list_lock */
|
||||
netif_addr_lock_bh(netdev);
|
||||
|
|
@ -369,29 +376,15 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi)
|
|||
/* check for changes in promiscuous modes */
|
||||
if (changed_flags & IFF_ALLMULTI) {
|
||||
if (vsi->current_netdev_flags & IFF_ALLMULTI) {
|
||||
if (ice_vsi_has_non_zero_vlans(vsi))
|
||||
promisc_m = ICE_MCAST_VLAN_PROMISC_BITS;
|
||||
else
|
||||
promisc_m = ICE_MCAST_PROMISC_BITS;
|
||||
|
||||
err = ice_set_promisc(vsi, promisc_m);
|
||||
err = ice_set_promisc(vsi, ICE_MCAST_PROMISC_BITS);
|
||||
if (err) {
|
||||
netdev_err(netdev, "Error setting Multicast promiscuous mode on VSI %i\n",
|
||||
vsi->vsi_num);
|
||||
vsi->current_netdev_flags &= ~IFF_ALLMULTI;
|
||||
goto out_promisc;
|
||||
}
|
||||
} else {
|
||||
/* !(vsi->current_netdev_flags & IFF_ALLMULTI) */
|
||||
if (ice_vsi_has_non_zero_vlans(vsi))
|
||||
promisc_m = ICE_MCAST_VLAN_PROMISC_BITS;
|
||||
else
|
||||
promisc_m = ICE_MCAST_PROMISC_BITS;
|
||||
|
||||
err = ice_clear_promisc(vsi, promisc_m);
|
||||
err = ice_clear_promisc(vsi, ICE_MCAST_PROMISC_BITS);
|
||||
if (err) {
|
||||
netdev_err(netdev, "Error clearing Multicast promiscuous mode on VSI %i\n",
|
||||
vsi->vsi_num);
|
||||
vsi->current_netdev_flags |= IFF_ALLMULTI;
|
||||
goto out_promisc;
|
||||
}
|
||||
|
|
@ -3488,6 +3481,20 @@ ice_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
|
|||
if (!vid)
|
||||
return 0;
|
||||
|
||||
while (test_and_set_bit(ICE_CFG_BUSY, vsi->state))
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
/* Add multicast promisc rule for the VLAN ID to be added if
|
||||
* all-multicast is currently enabled.
|
||||
*/
|
||||
if (vsi->current_netdev_flags & IFF_ALLMULTI) {
|
||||
ret = ice_fltr_set_vsi_promisc(&vsi->back->hw, vsi->idx,
|
||||
ICE_MCAST_VLAN_PROMISC_BITS,
|
||||
vid);
|
||||
if (ret)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
|
||||
|
||||
/* Add a switch rule for this VLAN ID so its corresponding VLAN tagged
|
||||
|
|
@ -3495,8 +3502,23 @@ ice_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
|
|||
*/
|
||||
vlan = ICE_VLAN(be16_to_cpu(proto), vid, 0);
|
||||
ret = vlan_ops->add_vlan(vsi, &vlan);
|
||||
if (!ret)
|
||||
set_bit(ICE_VSI_VLAN_FLTR_CHANGED, vsi->state);
|
||||
if (ret)
|
||||
goto finish;
|
||||
|
||||
/* If all-multicast is currently enabled and this VLAN ID is only one
|
||||
* besides VLAN-0 we have to update look-up type of multicast promisc
|
||||
* rule for VLAN-0 from ICE_SW_LKUP_PROMISC to ICE_SW_LKUP_PROMISC_VLAN.
|
||||
*/
|
||||
if ((vsi->current_netdev_flags & IFF_ALLMULTI) &&
|
||||
ice_vsi_num_non_zero_vlans(vsi) == 1) {
|
||||
ice_fltr_clear_vsi_promisc(&vsi->back->hw, vsi->idx,
|
||||
ICE_MCAST_PROMISC_BITS, 0);
|
||||
ice_fltr_set_vsi_promisc(&vsi->back->hw, vsi->idx,
|
||||
ICE_MCAST_VLAN_PROMISC_BITS, 0);
|
||||
}
|
||||
|
||||
finish:
|
||||
clear_bit(ICE_CFG_BUSY, vsi->state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -3522,6 +3544,9 @@ ice_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
|
|||
if (!vid)
|
||||
return 0;
|
||||
|
||||
while (test_and_set_bit(ICE_CFG_BUSY, vsi->state))
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
|
||||
|
||||
/* Make sure VLAN delete is successful before updating VLAN
|
||||
|
|
@ -3530,10 +3555,33 @@ ice_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
|
|||
vlan = ICE_VLAN(be16_to_cpu(proto), vid, 0);
|
||||
ret = vlan_ops->del_vlan(vsi, &vlan);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto finish;
|
||||
|
||||
set_bit(ICE_VSI_VLAN_FLTR_CHANGED, vsi->state);
|
||||
return 0;
|
||||
/* Remove multicast promisc rule for the removed VLAN ID if
|
||||
* all-multicast is enabled.
|
||||
*/
|
||||
if (vsi->current_netdev_flags & IFF_ALLMULTI)
|
||||
ice_fltr_clear_vsi_promisc(&vsi->back->hw, vsi->idx,
|
||||
ICE_MCAST_VLAN_PROMISC_BITS, vid);
|
||||
|
||||
if (!ice_vsi_has_non_zero_vlans(vsi)) {
|
||||
/* Update look-up type of multicast promisc rule for VLAN 0
|
||||
* from ICE_SW_LKUP_PROMISC_VLAN to ICE_SW_LKUP_PROMISC when
|
||||
* all-multicast is enabled and VLAN 0 is the only VLAN rule.
|
||||
*/
|
||||
if (vsi->current_netdev_flags & IFF_ALLMULTI) {
|
||||
ice_fltr_clear_vsi_promisc(&vsi->back->hw, vsi->idx,
|
||||
ICE_MCAST_VLAN_PROMISC_BITS,
|
||||
0);
|
||||
ice_fltr_set_vsi_promisc(&vsi->back->hw, vsi->idx,
|
||||
ICE_MCAST_PROMISC_BITS, 0);
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
clear_bit(ICE_CFG_BUSY, vsi->state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -5475,16 +5523,19 @@ static int ice_set_mac_address(struct net_device *netdev, void *pi)
|
|||
|
||||
/* Add filter for new MAC. If filter exists, return success */
|
||||
err = ice_fltr_add_mac(vsi, mac, ICE_FWD_TO_VSI);
|
||||
if (err == -EEXIST)
|
||||
if (err == -EEXIST) {
|
||||
/* Although this MAC filter is already present in hardware it's
|
||||
* possible in some cases (e.g. bonding) that dev_addr was
|
||||
* modified outside of the driver and needs to be restored back
|
||||
* to this value.
|
||||
*/
|
||||
netdev_dbg(netdev, "filter for MAC %pM already exists\n", mac);
|
||||
else if (err)
|
||||
|
||||
return 0;
|
||||
} else if (err) {
|
||||
/* error if the new filter addition failed */
|
||||
err = -EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
err_update_filters:
|
||||
if (err) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue