1 From a02cc9d3cc9f98905df214d4a57e5918473260ea Mon Sep 17 00:00:00 2001
2 From: Michal Schmidt <mschmidt@redhat.com>
3 Date: Fri, 3 Jun 2016 15:32:18 +0200
4 Subject: [PATCH] bnx2x: allow adding VLANs while interface is down
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
9 Since implementing VLAN filtering in commit 05cc5a39ddb74
10 ("bnx2x: add vlan filtering offload") bnx2x refuses to add a VLAN while
11 the interface is down:
13 # ip link add link enp3s0f0 enp3s0f0_10 type vlan id 10
14 RTNETLINK answers: Bad address
16 and in dmesg (with bnx2x.debug=0x20):
17 bnx2x: [bnx2x_vlan_rx_add_vid:12941(enp3s0f0)]Ignoring VLAN
18 configuration the interface is down
20 Other drivers have no problem with this.
21 Fix this peculiar behavior in the following way:
22 - Accept requests to add/kill VID regardless of the device state.
23 Maintain the requested list of VIDs in the bp->vlan_reg list.
24 - If the device is up, try to configure the VID list into the hardware.
25 If we run out of VLAN credits or encounter a failure configuring an
26 entry, fall back to accepting all VLANs.
27 If we successfully configure all entries from the list, turn the
29 - Use the same code for reconfiguring VLANs during NIC load.
31 Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
32 Acked-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
33 Signed-off-by: David S. Miller <davem@davemloft.net>
34 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
36 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 151 ++++++++++-------------
37 1 file changed, 62 insertions(+), 89 deletions(-)
39 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
40 index c5fe9158..a59d55e 100644
41 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
42 +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
43 @@ -12895,52 +12895,71 @@ static int __bnx2x_vlan_configure_vid(struct bnx2x *bp, u16 vid, bool add)
47 -int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp)
48 +static int bnx2x_vlan_configure_vid_list(struct bnx2x *bp)
50 struct bnx2x_vlan_entry *vlan;
53 - if (!bp->vlan_cnt) {
54 - DP(NETIF_MSG_IFUP, "No need to re-configure vlan filters\n");
58 + /* Configure all non-configured entries */
59 list_for_each_entry(vlan, &bp->vlan_reg, link) {
60 - /* Prepare for cleanup in case of errors */
70 - DP(NETIF_MSG_IFUP, "Re-configuring vlan 0x%04x\n", vlan->vid);
71 + if (bp->vlan_cnt >= bp->vlan_credit)
74 rc = __bnx2x_vlan_configure_vid(bp, vlan->vid, true);
76 - BNX2X_ERR("Unable to configure VLAN %d\n", vlan->vid);
80 + BNX2X_ERR("Unable to config VLAN %d\n", vlan->vid);
84 + DP(NETIF_MSG_IFUP, "HW configured for VLAN %d\n", vlan->vid);
93 +static void bnx2x_vlan_configure(struct bnx2x *bp, bool set_rx_mode)
95 + bool need_accept_any_vlan;
97 + need_accept_any_vlan = !!bnx2x_vlan_configure_vid_list(bp);
99 + if (bp->accept_any_vlan != need_accept_any_vlan) {
100 + bp->accept_any_vlan = need_accept_any_vlan;
101 + DP(NETIF_MSG_IFUP, "Accept all VLAN %s\n",
102 + bp->accept_any_vlan ? "raised" : "cleared");
105 + bnx2x_set_rx_mode_inner(bp);
107 + bnx2x_vfpf_storm_rx_mode(bp);
112 +int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp)
114 + struct bnx2x_vlan_entry *vlan;
116 + /* The hw forgot all entries after reload */
117 + list_for_each_entry(vlan, &bp->vlan_reg, link)
121 + /* Don't set rx mode here. Our caller will do it. */
122 + bnx2x_vlan_configure(bp, false);
127 static int bnx2x_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
129 struct bnx2x *bp = netdev_priv(dev);
130 struct bnx2x_vlan_entry *vlan;
134 - if (!netif_running(bp->dev)) {
136 - "Ignoring VLAN configuration the interface is down\n");
140 DP(NETIF_MSG_IFUP, "Adding VLAN %d\n", vid);
142 @@ -12948,93 +12967,47 @@ static int bnx2x_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
147 - if (bp->vlan_cnt > bp->vlan_credit && !bp->accept_any_vlan) {
148 - DP(NETIF_MSG_IFUP, "Accept all VLAN raised\n");
149 - bp->accept_any_vlan = true;
151 - bnx2x_set_rx_mode_inner(bp);
153 - bnx2x_vfpf_storm_rx_mode(bp);
154 - } else if (bp->vlan_cnt <= bp->vlan_credit) {
155 - rc = __bnx2x_vlan_configure_vid(bp, vid, true);
162 + list_add_tail(&vlan->link, &bp->vlan_reg);
165 - list_add(&vlan->link, &bp->vlan_reg);
171 - DP(NETIF_MSG_IFUP, "Adding VLAN result %d\n", rc);
172 + if (netif_running(dev))
173 + bnx2x_vlan_configure(bp, true);
179 static int bnx2x_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
181 struct bnx2x *bp = netdev_priv(dev);
182 struct bnx2x_vlan_entry *vlan;
183 + bool found = false;
186 - if (!netif_running(bp->dev)) {
188 - "Ignoring VLAN configuration the interface is down\n");
192 DP(NETIF_MSG_IFUP, "Removing VLAN %d\n", vid);
194 - if (!bp->vlan_cnt) {
195 - BNX2X_ERR("Unable to kill VLAN %d\n", vid);
199 list_for_each_entry(vlan, &bp->vlan_reg, link)
200 - if (vlan->vid == vid)
201 + if (vlan->vid == vid) {
206 - if (vlan->vid != vid) {
208 BNX2X_ERR("Unable to kill VLAN %d - not found\n", vid);
213 + if (netif_running(dev) && vlan->hw) {
214 rc = __bnx2x_vlan_configure_vid(bp, vid, false);
215 + DP(NETIF_MSG_IFUP, "HW deconfigured for VLAN %d\n", vid);
219 list_del(&vlan->link);
224 - if (bp->vlan_cnt <= bp->vlan_credit && bp->accept_any_vlan) {
225 - /* Configure all non-configured entries */
226 - list_for_each_entry(vlan, &bp->vlan_reg, link) {
230 - rc = __bnx2x_vlan_configure_vid(bp, vlan->vid, true);
232 - BNX2X_ERR("Unable to config VLAN %d\n",
236 - DP(NETIF_MSG_IFUP, "HW configured for VLAN %d\n",
240 - DP(NETIF_MSG_IFUP, "Accept all VLAN Removed\n");
241 - bp->accept_any_vlan = false;
243 - bnx2x_set_rx_mode_inner(bp);
245 - bnx2x_vfpf_storm_rx_mode(bp);
247 + if (netif_running(dev))
248 + bnx2x_vlan_configure(bp, true);
250 DP(NETIF_MSG_IFUP, "Removing VLAN result %d\n", rc);