aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c151
1 files changed, 62 insertions, 89 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index c5fe915870ad..a59d55e25d5f 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -12895,52 +12895,71 @@ static int __bnx2x_vlan_configure_vid(struct bnx2x *bp, u16 vid, bool add)
12895 return rc; 12895 return rc;
12896} 12896}
12897 12897
12898int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp) 12898static int bnx2x_vlan_configure_vid_list(struct bnx2x *bp)
12899{ 12899{
12900 struct bnx2x_vlan_entry *vlan; 12900 struct bnx2x_vlan_entry *vlan;
12901 int rc = 0; 12901 int rc = 0;
12902 12902
12903 if (!bp->vlan_cnt) { 12903 /* Configure all non-configured entries */
12904 DP(NETIF_MSG_IFUP, "No need to re-configure vlan filters\n");
12905 return 0;
12906 }
12907
12908 list_for_each_entry(vlan, &bp->vlan_reg, link) { 12904 list_for_each_entry(vlan, &bp->vlan_reg, link) {
12909 /* Prepare for cleanup in case of errors */ 12905 if (vlan->hw)
12910 if (rc) {
12911 vlan->hw = false;
12912 continue;
12913 }
12914
12915 if (!vlan->hw)
12916 continue; 12906 continue;
12917 12907
12918 DP(NETIF_MSG_IFUP, "Re-configuring vlan 0x%04x\n", vlan->vid); 12908 if (bp->vlan_cnt >= bp->vlan_credit)
12909 return -ENOBUFS;
12919 12910
12920 rc = __bnx2x_vlan_configure_vid(bp, vlan->vid, true); 12911 rc = __bnx2x_vlan_configure_vid(bp, vlan->vid, true);
12921 if (rc) { 12912 if (rc) {
12922 BNX2X_ERR("Unable to configure VLAN %d\n", vlan->vid); 12913 BNX2X_ERR("Unable to config VLAN %d\n", vlan->vid);
12923 vlan->hw = false; 12914 return rc;
12924 rc = -EINVAL;
12925 continue;
12926 } 12915 }
12916
12917 DP(NETIF_MSG_IFUP, "HW configured for VLAN %d\n", vlan->vid);
12918 vlan->hw = true;
12919 bp->vlan_cnt++;
12927 } 12920 }
12928 12921
12929 return rc; 12922 return 0;
12923}
12924
12925static void bnx2x_vlan_configure(struct bnx2x *bp, bool set_rx_mode)
12926{
12927 bool need_accept_any_vlan;
12928
12929 need_accept_any_vlan = !!bnx2x_vlan_configure_vid_list(bp);
12930
12931 if (bp->accept_any_vlan != need_accept_any_vlan) {
12932 bp->accept_any_vlan = need_accept_any_vlan;
12933 DP(NETIF_MSG_IFUP, "Accept all VLAN %s\n",
12934 bp->accept_any_vlan ? "raised" : "cleared");
12935 if (set_rx_mode) {
12936 if (IS_PF(bp))
12937 bnx2x_set_rx_mode_inner(bp);
12938 else
12939 bnx2x_vfpf_storm_rx_mode(bp);
12940 }
12941 }
12942}
12943
12944int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp)
12945{
12946 struct bnx2x_vlan_entry *vlan;
12947
12948 /* The hw forgot all entries after reload */
12949 list_for_each_entry(vlan, &bp->vlan_reg, link)
12950 vlan->hw = false;
12951 bp->vlan_cnt = 0;
12952
12953 /* Don't set rx mode here. Our caller will do it. */
12954 bnx2x_vlan_configure(bp, false);
12955
12956 return 0;
12930} 12957}
12931 12958
12932static int bnx2x_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) 12959static int bnx2x_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
12933{ 12960{
12934 struct bnx2x *bp = netdev_priv(dev); 12961 struct bnx2x *bp = netdev_priv(dev);
12935 struct bnx2x_vlan_entry *vlan; 12962 struct bnx2x_vlan_entry *vlan;
12936 bool hw = false;
12937 int rc = 0;
12938
12939 if (!netif_running(bp->dev)) {
12940 DP(NETIF_MSG_IFUP,
12941 "Ignoring VLAN configuration the interface is down\n");
12942 return -EFAULT;
12943 }
12944 12963
12945 DP(NETIF_MSG_IFUP, "Adding VLAN %d\n", vid); 12964 DP(NETIF_MSG_IFUP, "Adding VLAN %d\n", vid);
12946 12965
@@ -12948,93 +12967,47 @@ static int bnx2x_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
12948 if (!vlan) 12967 if (!vlan)
12949 return -ENOMEM; 12968 return -ENOMEM;
12950 12969
12951 bp->vlan_cnt++;
12952 if (bp->vlan_cnt > bp->vlan_credit && !bp->accept_any_vlan) {
12953 DP(NETIF_MSG_IFUP, "Accept all VLAN raised\n");
12954 bp->accept_any_vlan = true;
12955 if (IS_PF(bp))
12956 bnx2x_set_rx_mode_inner(bp);
12957 else
12958 bnx2x_vfpf_storm_rx_mode(bp);
12959 } else if (bp->vlan_cnt <= bp->vlan_credit) {
12960 rc = __bnx2x_vlan_configure_vid(bp, vid, true);
12961 hw = true;
12962 }
12963
12964 vlan->vid = vid; 12970 vlan->vid = vid;
12965 vlan->hw = hw; 12971 vlan->hw = false;
12972 list_add_tail(&vlan->link, &bp->vlan_reg);
12966 12973
12967 if (!rc) { 12974 if (netif_running(dev))
12968 list_add(&vlan->link, &bp->vlan_reg); 12975 bnx2x_vlan_configure(bp, true);
12969 } else {
12970 bp->vlan_cnt--;
12971 kfree(vlan);
12972 }
12973
12974 DP(NETIF_MSG_IFUP, "Adding VLAN result %d\n", rc);
12975 12976
12976 return rc; 12977 return 0;
12977} 12978}
12978 12979
12979static int bnx2x_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid) 12980static int bnx2x_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
12980{ 12981{
12981 struct bnx2x *bp = netdev_priv(dev); 12982 struct bnx2x *bp = netdev_priv(dev);
12982 struct bnx2x_vlan_entry *vlan; 12983 struct bnx2x_vlan_entry *vlan;
12984 bool found = false;
12983 int rc = 0; 12985 int rc = 0;
12984 12986
12985 if (!netif_running(bp->dev)) {
12986 DP(NETIF_MSG_IFUP,
12987 "Ignoring VLAN configuration the interface is down\n");
12988 return -EFAULT;
12989 }
12990
12991 DP(NETIF_MSG_IFUP, "Removing VLAN %d\n", vid); 12987 DP(NETIF_MSG_IFUP, "Removing VLAN %d\n", vid);
12992 12988
12993 if (!bp->vlan_cnt) {
12994 BNX2X_ERR("Unable to kill VLAN %d\n", vid);
12995 return -EINVAL;
12996 }
12997
12998 list_for_each_entry(vlan, &bp->vlan_reg, link) 12989 list_for_each_entry(vlan, &bp->vlan_reg, link)
12999 if (vlan->vid == vid) 12990 if (vlan->vid == vid) {
12991 found = true;
13000 break; 12992 break;
12993 }
13001 12994
13002 if (vlan->vid != vid) { 12995 if (!found) {
13003 BNX2X_ERR("Unable to kill VLAN %d - not found\n", vid); 12996 BNX2X_ERR("Unable to kill VLAN %d - not found\n", vid);
13004 return -EINVAL; 12997 return -EINVAL;
13005 } 12998 }
13006 12999
13007 if (vlan->hw) 13000 if (netif_running(dev) && vlan->hw) {
13008 rc = __bnx2x_vlan_configure_vid(bp, vid, false); 13001 rc = __bnx2x_vlan_configure_vid(bp, vid, false);
13002 DP(NETIF_MSG_IFUP, "HW deconfigured for VLAN %d\n", vid);
13003 bp->vlan_cnt--;
13004 }
13009 13005
13010 list_del(&vlan->link); 13006 list_del(&vlan->link);
13011 kfree(vlan); 13007 kfree(vlan);
13012 13008
13013 bp->vlan_cnt--; 13009 if (netif_running(dev))
13014 13010 bnx2x_vlan_configure(bp, true);
13015 if (bp->vlan_cnt <= bp->vlan_credit && bp->accept_any_vlan) {
13016 /* Configure all non-configured entries */
13017 list_for_each_entry(vlan, &bp->vlan_reg, link) {
13018 if (vlan->hw)
13019 continue;
13020
13021 rc = __bnx2x_vlan_configure_vid(bp, vlan->vid, true);
13022 if (rc) {
13023 BNX2X_ERR("Unable to config VLAN %d\n",
13024 vlan->vid);
13025 continue;
13026 }
13027 DP(NETIF_MSG_IFUP, "HW configured for VLAN %d\n",
13028 vlan->vid);
13029 vlan->hw = true;
13030 }
13031 DP(NETIF_MSG_IFUP, "Accept all VLAN Removed\n");
13032 bp->accept_any_vlan = false;
13033 if (IS_PF(bp))
13034 bnx2x_set_rx_mode_inner(bp);
13035 else
13036 bnx2x_vfpf_storm_rx_mode(bp);
13037 }
13038 13011
13039 DP(NETIF_MSG_IFUP, "Removing VLAN result %d\n", rc); 13012 DP(NETIF_MSG_IFUP, "Removing VLAN result %d\n", rc);
13040 13013