diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 245 |
1 files changed, 95 insertions, 150 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index c5fe915870ad..97e892511666 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -59,9 +59,6 @@ #include <linux/semaphore.h> #include <linux/stringify.h> #include <linux/vmalloc.h> -#if IS_ENABLED(CONFIG_BNX2X_GENEVE) -#include <net/geneve.h> -#endif #include "bnx2x.h" #include "bnx2x_init.h" #include "bnx2x_init_ops.h" @@ -10076,7 +10073,6 @@ static void bnx2x_parity_recover(struct bnx2x *bp) } } -#if defined(CONFIG_BNX2X_VXLAN) || IS_ENABLED(CONFIG_BNX2X_GENEVE) static int bnx2x_udp_port_update(struct bnx2x *bp) { struct bnx2x_func_switch_update_params *switch_update_params; @@ -10177,47 +10173,42 @@ static void __bnx2x_del_udp_port(struct bnx2x *bp, u16 port, DP(BNX2X_MSG_SP, "Deleted UDP tunnel [%d] port %d\n", type, port); } -#endif - -#ifdef CONFIG_BNX2X_VXLAN -static void bnx2x_add_vxlan_port(struct net_device *netdev, - sa_family_t sa_family, __be16 port) -{ - struct bnx2x *bp = netdev_priv(netdev); - u16 t_port = ntohs(port); - - __bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN); -} - -static void bnx2x_del_vxlan_port(struct net_device *netdev, - sa_family_t sa_family, __be16 port) -{ - struct bnx2x *bp = netdev_priv(netdev); - u16 t_port = ntohs(port); - - __bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN); -} -#endif -#if IS_ENABLED(CONFIG_BNX2X_GENEVE) -static void bnx2x_add_geneve_port(struct net_device *netdev, - sa_family_t sa_family, __be16 port) +static void bnx2x_udp_tunnel_add(struct net_device *netdev, + struct udp_tunnel_info *ti) { struct bnx2x *bp = netdev_priv(netdev); - u16 t_port = ntohs(port); + u16 t_port = ntohs(ti->port); - __bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE); + switch (ti->type) { + case UDP_TUNNEL_TYPE_VXLAN: + __bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN); + break; + case UDP_TUNNEL_TYPE_GENEVE: + __bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE); + break; + default: + break; + } } -static void bnx2x_del_geneve_port(struct net_device *netdev, - sa_family_t sa_family, __be16 port) +static void bnx2x_udp_tunnel_del(struct net_device *netdev, + struct udp_tunnel_info *ti) { struct bnx2x *bp = netdev_priv(netdev); - u16 t_port = ntohs(port); + u16 t_port = ntohs(ti->port); - __bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE); + switch (ti->type) { + case UDP_TUNNEL_TYPE_VXLAN: + __bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN); + break; + case UDP_TUNNEL_TYPE_GENEVE: + __bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE); + break; + default: + break; + } } -#endif static int bnx2x_close(struct net_device *dev); @@ -10325,7 +10316,6 @@ sp_rtnl_not_reset: &bp->sp_rtnl_state)) bnx2x_update_mng_version(bp); -#if defined(CONFIG_BNX2X_VXLAN) || IS_ENABLED(CONFIG_BNX2X_GENEVE) if (test_and_clear_bit(BNX2X_SP_RTNL_CHANGE_UDP_PORT, &bp->sp_rtnl_state)) { if (bnx2x_udp_port_update(bp)) { @@ -10335,20 +10325,14 @@ sp_rtnl_not_reset: BNX2X_UDP_PORT_MAX); } else { /* Since we don't store additional port information, - * if no port is configured for any feature ask for + * if no ports are configured for any feature ask for * information about currently configured ports. */ -#ifdef CONFIG_BNX2X_VXLAN - if (!bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].count) - vxlan_get_rx_port(bp->dev); -#endif -#if IS_ENABLED(CONFIG_BNX2X_GENEVE) - if (!bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].count) - geneve_get_rx_port(bp->dev); -#endif + if (!bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].count && + !bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].count) + udp_tunnel_get_rx_info(bp->dev); } } -#endif /* work which needs rtnl lock not-taken (as it takes the lock itself and * can be called from other contexts as well) @@ -12551,14 +12535,8 @@ static int bnx2x_open(struct net_device *dev) if (rc) return rc; -#ifdef CONFIG_BNX2X_VXLAN - if (IS_PF(bp)) - vxlan_get_rx_port(dev); -#endif -#if IS_ENABLED(CONFIG_BNX2X_GENEVE) if (IS_PF(bp)) - geneve_get_rx_port(dev); -#endif + udp_tunnel_get_rx_info(dev); return 0; } @@ -12895,52 +12873,71 @@ static int __bnx2x_vlan_configure_vid(struct bnx2x *bp, u16 vid, bool add) return rc; } -int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp) +static int bnx2x_vlan_configure_vid_list(struct bnx2x *bp) { struct bnx2x_vlan_entry *vlan; int rc = 0; - if (!bp->vlan_cnt) { - DP(NETIF_MSG_IFUP, "No need to re-configure vlan filters\n"); - return 0; - } - + /* Configure all non-configured entries */ list_for_each_entry(vlan, &bp->vlan_reg, link) { - /* Prepare for cleanup in case of errors */ - if (rc) { - vlan->hw = false; - continue; - } - - if (!vlan->hw) + if (vlan->hw) continue; - DP(NETIF_MSG_IFUP, "Re-configuring vlan 0x%04x\n", vlan->vid); + if (bp->vlan_cnt >= bp->vlan_credit) + return -ENOBUFS; rc = __bnx2x_vlan_configure_vid(bp, vlan->vid, true); if (rc) { - BNX2X_ERR("Unable to configure VLAN %d\n", vlan->vid); - vlan->hw = false; - rc = -EINVAL; - continue; + BNX2X_ERR("Unable to config VLAN %d\n", vlan->vid); + return rc; } + + DP(NETIF_MSG_IFUP, "HW configured for VLAN %d\n", vlan->vid); + vlan->hw = true; + bp->vlan_cnt++; } - return rc; + return 0; +} + +static void bnx2x_vlan_configure(struct bnx2x *bp, bool set_rx_mode) +{ + bool need_accept_any_vlan; + + need_accept_any_vlan = !!bnx2x_vlan_configure_vid_list(bp); + + if (bp->accept_any_vlan != need_accept_any_vlan) { + bp->accept_any_vlan = need_accept_any_vlan; + DP(NETIF_MSG_IFUP, "Accept all VLAN %s\n", + bp->accept_any_vlan ? "raised" : "cleared"); + if (set_rx_mode) { + if (IS_PF(bp)) + bnx2x_set_rx_mode_inner(bp); + else + bnx2x_vfpf_storm_rx_mode(bp); + } + } +} + +int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp) +{ + struct bnx2x_vlan_entry *vlan; + + /* The hw forgot all entries after reload */ + list_for_each_entry(vlan, &bp->vlan_reg, link) + vlan->hw = false; + bp->vlan_cnt = 0; + + /* Don't set rx mode here. Our caller will do it. */ + bnx2x_vlan_configure(bp, false); + + return 0; } static int bnx2x_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) { struct bnx2x *bp = netdev_priv(dev); struct bnx2x_vlan_entry *vlan; - bool hw = false; - int rc = 0; - - if (!netif_running(bp->dev)) { - DP(NETIF_MSG_IFUP, - "Ignoring VLAN configuration the interface is down\n"); - return -EFAULT; - } DP(NETIF_MSG_IFUP, "Adding VLAN %d\n", vid); @@ -12948,93 +12945,47 @@ static int bnx2x_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) if (!vlan) return -ENOMEM; - bp->vlan_cnt++; - if (bp->vlan_cnt > bp->vlan_credit && !bp->accept_any_vlan) { - DP(NETIF_MSG_IFUP, "Accept all VLAN raised\n"); - bp->accept_any_vlan = true; - if (IS_PF(bp)) - bnx2x_set_rx_mode_inner(bp); - else - bnx2x_vfpf_storm_rx_mode(bp); - } else if (bp->vlan_cnt <= bp->vlan_credit) { - rc = __bnx2x_vlan_configure_vid(bp, vid, true); - hw = true; - } - vlan->vid = vid; - vlan->hw = hw; - - if (!rc) { - list_add(&vlan->link, &bp->vlan_reg); - } else { - bp->vlan_cnt--; - kfree(vlan); - } + vlan->hw = false; + list_add_tail(&vlan->link, &bp->vlan_reg); - DP(NETIF_MSG_IFUP, "Adding VLAN result %d\n", rc); + if (netif_running(dev)) + bnx2x_vlan_configure(bp, true); - return rc; + return 0; } static int bnx2x_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid) { struct bnx2x *bp = netdev_priv(dev); struct bnx2x_vlan_entry *vlan; + bool found = false; int rc = 0; - if (!netif_running(bp->dev)) { - DP(NETIF_MSG_IFUP, - "Ignoring VLAN configuration the interface is down\n"); - return -EFAULT; - } - DP(NETIF_MSG_IFUP, "Removing VLAN %d\n", vid); - if (!bp->vlan_cnt) { - BNX2X_ERR("Unable to kill VLAN %d\n", vid); - return -EINVAL; - } - list_for_each_entry(vlan, &bp->vlan_reg, link) - if (vlan->vid == vid) + if (vlan->vid == vid) { + found = true; break; + } - if (vlan->vid != vid) { + if (!found) { BNX2X_ERR("Unable to kill VLAN %d - not found\n", vid); return -EINVAL; } - if (vlan->hw) + if (netif_running(dev) && vlan->hw) { rc = __bnx2x_vlan_configure_vid(bp, vid, false); + DP(NETIF_MSG_IFUP, "HW deconfigured for VLAN %d\n", vid); + bp->vlan_cnt--; + } list_del(&vlan->link); kfree(vlan); - bp->vlan_cnt--; - - if (bp->vlan_cnt <= bp->vlan_credit && bp->accept_any_vlan) { - /* Configure all non-configured entries */ - list_for_each_entry(vlan, &bp->vlan_reg, link) { - if (vlan->hw) - continue; - - rc = __bnx2x_vlan_configure_vid(bp, vlan->vid, true); - if (rc) { - BNX2X_ERR("Unable to config VLAN %d\n", - vlan->vid); - continue; - } - DP(NETIF_MSG_IFUP, "HW configured for VLAN %d\n", - vlan->vid); - vlan->hw = true; - } - DP(NETIF_MSG_IFUP, "Accept all VLAN Removed\n"); - bp->accept_any_vlan = false; - if (IS_PF(bp)) - bnx2x_set_rx_mode_inner(bp); - else - bnx2x_vfpf_storm_rx_mode(bp); - } + if (netif_running(dev)) + bnx2x_vlan_configure(bp, true); DP(NETIF_MSG_IFUP, "Removing VLAN result %d\n", rc); @@ -13072,14 +13023,8 @@ static const struct net_device_ops bnx2x_netdev_ops = { .ndo_get_phys_port_id = bnx2x_get_phys_port_id, .ndo_set_vf_link_state = bnx2x_set_vf_link_state, .ndo_features_check = bnx2x_features_check, -#ifdef CONFIG_BNX2X_VXLAN - .ndo_add_vxlan_port = bnx2x_add_vxlan_port, - .ndo_del_vxlan_port = bnx2x_del_vxlan_port, -#endif -#if IS_ENABLED(CONFIG_BNX2X_GENEVE) - .ndo_add_geneve_port = bnx2x_add_geneve_port, - .ndo_del_geneve_port = bnx2x_del_geneve_port, -#endif + .ndo_udp_tunnel_add = bnx2x_udp_tunnel_add, + .ndo_udp_tunnel_del = bnx2x_udp_tunnel_del, }; static int bnx2x_set_coherency_mask(struct bnx2x *bp) |