diff options
author | Akeem G Abodunrin <akeem.g.abodunrin@intel.com> | 2019-02-26 19:35:14 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2019-03-22 11:19:17 -0400 |
commit | 5eda8afd6bcc89d4e4aa5d56b5f54276f63158ae (patch) | |
tree | 44a9e13481cd5aa025b5f576a09f93fa943bb9fa /drivers/net/ethernet/intel/ice/ice_main.c | |
parent | e1ca65a3cceacc94dd9cde388016422ca2e15a54 (diff) |
ice: Add support for PF/VF promiscuous mode
Implement support for VF promiscuous mode, MAC/VLAN/MAC_VLAN and PF
multicast MAC/VLAN/MAC_VLAN promiscuous mode.
Signed-off-by: Akeem G Abodunrin <akeem.g.abodunrin@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_main.c')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_main.c | 91 |
1 files changed, 80 insertions, 11 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 34712e38121e..879c1f176a17 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c | |||
@@ -168,6 +168,39 @@ static bool ice_vsi_fltr_changed(struct ice_vsi *vsi) | |||
168 | } | 168 | } |
169 | 169 | ||
170 | /** | 170 | /** |
171 | * ice_cfg_promisc - Enable or disable promiscuous mode for a given PF | ||
172 | * @vsi: the VSI being configured | ||
173 | * @promisc_m: mask of promiscuous config bits | ||
174 | * @set_promisc: enable or disable promisc flag request | ||
175 | * | ||
176 | */ | ||
177 | static int ice_cfg_promisc(struct ice_vsi *vsi, u8 promisc_m, bool set_promisc) | ||
178 | { | ||
179 | struct ice_hw *hw = &vsi->back->hw; | ||
180 | enum ice_status status = 0; | ||
181 | |||
182 | if (vsi->type != ICE_VSI_PF) | ||
183 | return 0; | ||
184 | |||
185 | if (vsi->vlan_ena) { | ||
186 | status = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_m, | ||
187 | set_promisc); | ||
188 | } else { | ||
189 | if (set_promisc) | ||
190 | status = ice_set_vsi_promisc(hw, vsi->idx, promisc_m, | ||
191 | 0); | ||
192 | else | ||
193 | status = ice_clear_vsi_promisc(hw, vsi->idx, promisc_m, | ||
194 | 0); | ||
195 | } | ||
196 | |||
197 | if (status) | ||
198 | return -EIO; | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | /** | ||
171 | * ice_vsi_sync_fltr - Update the VSI filter list to the HW | 204 | * ice_vsi_sync_fltr - Update the VSI filter list to the HW |
172 | * @vsi: ptr to the VSI | 205 | * @vsi: ptr to the VSI |
173 | * | 206 | * |
@@ -182,6 +215,7 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi) | |||
182 | struct ice_hw *hw = &pf->hw; | 215 | struct ice_hw *hw = &pf->hw; |
183 | enum ice_status status = 0; | 216 | enum ice_status status = 0; |
184 | u32 changed_flags = 0; | 217 | u32 changed_flags = 0; |
218 | u8 promisc_m; | ||
185 | int err = 0; | 219 | int err = 0; |
186 | 220 | ||
187 | if (!vsi->netdev) | 221 | if (!vsi->netdev) |
@@ -245,8 +279,35 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi) | |||
245 | } | 279 | } |
246 | } | 280 | } |
247 | /* check for changes in promiscuous modes */ | 281 | /* check for changes in promiscuous modes */ |
248 | if (changed_flags & IFF_ALLMULTI) | 282 | if (changed_flags & IFF_ALLMULTI) { |
249 | netdev_warn(netdev, "Unsupported configuration\n"); | 283 | if (vsi->current_netdev_flags & IFF_ALLMULTI) { |
284 | if (vsi->vlan_ena) | ||
285 | promisc_m = ICE_MCAST_VLAN_PROMISC_BITS; | ||
286 | else | ||
287 | promisc_m = ICE_MCAST_PROMISC_BITS; | ||
288 | |||
289 | err = ice_cfg_promisc(vsi, promisc_m, true); | ||
290 | if (err) { | ||
291 | netdev_err(netdev, "Error setting Multicast promiscuous mode on VSI %i\n", | ||
292 | vsi->vsi_num); | ||
293 | vsi->current_netdev_flags &= ~IFF_ALLMULTI; | ||
294 | goto out_promisc; | ||
295 | } | ||
296 | } else if (!(vsi->current_netdev_flags & IFF_ALLMULTI)) { | ||
297 | if (vsi->vlan_ena) | ||
298 | promisc_m = ICE_MCAST_VLAN_PROMISC_BITS; | ||
299 | else | ||
300 | promisc_m = ICE_MCAST_PROMISC_BITS; | ||
301 | |||
302 | err = ice_cfg_promisc(vsi, promisc_m, false); | ||
303 | if (err) { | ||
304 | netdev_err(netdev, "Error clearing Multicast promiscuous mode on VSI %i\n", | ||
305 | vsi->vsi_num); | ||
306 | vsi->current_netdev_flags |= IFF_ALLMULTI; | ||
307 | goto out_promisc; | ||
308 | } | ||
309 | } | ||
310 | } | ||
250 | 311 | ||
251 | if (((changed_flags & IFF_PROMISC) || promisc_forced_on) || | 312 | if (((changed_flags & IFF_PROMISC) || promisc_forced_on) || |
252 | test_bit(ICE_VSI_FLAG_PROMISC_CHANGED, vsi->flags)) { | 313 | test_bit(ICE_VSI_FLAG_PROMISC_CHANGED, vsi->flags)) { |
@@ -1665,6 +1726,7 @@ ice_vlan_rx_add_vid(struct net_device *netdev, __always_unused __be16 proto, | |||
1665 | { | 1726 | { |
1666 | struct ice_netdev_priv *np = netdev_priv(netdev); | 1727 | struct ice_netdev_priv *np = netdev_priv(netdev); |
1667 | struct ice_vsi *vsi = np->vsi; | 1728 | struct ice_vsi *vsi = np->vsi; |
1729 | int ret; | ||
1668 | 1730 | ||
1669 | if (vid >= VLAN_N_VID) { | 1731 | if (vid >= VLAN_N_VID) { |
1670 | netdev_err(netdev, "VLAN id requested %d is out of range %d\n", | 1732 | netdev_err(netdev, "VLAN id requested %d is out of range %d\n", |
@@ -1677,8 +1739,7 @@ ice_vlan_rx_add_vid(struct net_device *netdev, __always_unused __be16 proto, | |||
1677 | 1739 | ||
1678 | /* Enable VLAN pruning when VLAN 0 is added */ | 1740 | /* Enable VLAN pruning when VLAN 0 is added */ |
1679 | if (unlikely(!vid)) { | 1741 | if (unlikely(!vid)) { |
1680 | int ret = ice_cfg_vlan_pruning(vsi, true); | 1742 | ret = ice_cfg_vlan_pruning(vsi, true, false); |
1681 | |||
1682 | if (ret) | 1743 | if (ret) |
1683 | return ret; | 1744 | return ret; |
1684 | } | 1745 | } |
@@ -1687,7 +1748,13 @@ ice_vlan_rx_add_vid(struct net_device *netdev, __always_unused __be16 proto, | |||
1687 | * needed to continue allowing all untagged packets since VLAN prune | 1748 | * needed to continue allowing all untagged packets since VLAN prune |
1688 | * list is applied to all packets by the switch | 1749 | * list is applied to all packets by the switch |
1689 | */ | 1750 | */ |
1690 | return ice_vsi_add_vlan(vsi, vid); | 1751 | ret = ice_vsi_add_vlan(vsi, vid); |
1752 | if (!ret) { | ||
1753 | vsi->vlan_ena = true; | ||
1754 | set_bit(ICE_VSI_FLAG_VLAN_FLTR_CHANGED, vsi->flags); | ||
1755 | } | ||
1756 | |||
1757 | return ret; | ||
1691 | } | 1758 | } |
1692 | 1759 | ||
1693 | /** | 1760 | /** |
@@ -1704,7 +1771,7 @@ ice_vlan_rx_kill_vid(struct net_device *netdev, __always_unused __be16 proto, | |||
1704 | { | 1771 | { |
1705 | struct ice_netdev_priv *np = netdev_priv(netdev); | 1772 | struct ice_netdev_priv *np = netdev_priv(netdev); |
1706 | struct ice_vsi *vsi = np->vsi; | 1773 | struct ice_vsi *vsi = np->vsi; |
1707 | int status; | 1774 | int ret; |
1708 | 1775 | ||
1709 | if (vsi->info.pvid) | 1776 | if (vsi->info.pvid) |
1710 | return -EINVAL; | 1777 | return -EINVAL; |
@@ -1712,15 +1779,17 @@ ice_vlan_rx_kill_vid(struct net_device *netdev, __always_unused __be16 proto, | |||
1712 | /* Make sure ice_vsi_kill_vlan is successful before updating VLAN | 1779 | /* Make sure ice_vsi_kill_vlan is successful before updating VLAN |
1713 | * information | 1780 | * information |
1714 | */ | 1781 | */ |
1715 | status = ice_vsi_kill_vlan(vsi, vid); | 1782 | ret = ice_vsi_kill_vlan(vsi, vid); |
1716 | if (status) | 1783 | if (ret) |
1717 | return status; | 1784 | return ret; |
1718 | 1785 | ||
1719 | /* Disable VLAN pruning when VLAN 0 is removed */ | 1786 | /* Disable VLAN pruning when VLAN 0 is removed */ |
1720 | if (unlikely(!vid)) | 1787 | if (unlikely(!vid)) |
1721 | status = ice_cfg_vlan_pruning(vsi, false); | 1788 | ret = ice_cfg_vlan_pruning(vsi, false, false); |
1722 | 1789 | ||
1723 | return status; | 1790 | vsi->vlan_ena = false; |
1791 | set_bit(ICE_VSI_FLAG_VLAN_FLTR_CHANGED, vsi->flags); | ||
1792 | return ret; | ||
1724 | } | 1793 | } |
1725 | 1794 | ||
1726 | /** | 1795 | /** |