]> git.proxmox.com Git - pve-kernel-jessie.git/blame - bnx2x-allow-adding-VLANs-while-interface-is-down.patch
update to Ubuntu 4.4.0-58-79
[pve-kernel-jessie.git] / bnx2x-allow-adding-VLANs-while-interface-is-down.patch
CommitLineData
6460db5f
FG
1From a02cc9d3cc9f98905df214d4a57e5918473260ea Mon Sep 17 00:00:00 2001
2From: Michal Schmidt <mschmidt@redhat.com>
3Date: Fri, 3 Jun 2016 15:32:18 +0200
4Subject: [PATCH] bnx2x: allow adding VLANs while interface is down
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9Since implementing VLAN filtering in commit 05cc5a39ddb74
10("bnx2x: add vlan filtering offload") bnx2x refuses to add a VLAN while
11the interface is down:
12
13 # ip link add link enp3s0f0 enp3s0f0_10 type vlan id 10
14 RTNETLINK answers: Bad address
15
16and in dmesg (with bnx2x.debug=0x20):
17 bnx2x: [bnx2x_vlan_rx_add_vid:12941(enp3s0f0)]Ignoring VLAN
18 configuration the interface is down
19
20Other drivers have no problem with this.
21Fix 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
28 fallback off.
29 - Use the same code for reconfiguring VLANs during NIC load.
30
31Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
32Acked-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
33Signed-off-by: David S. Miller <davem@davemloft.net>
34Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
35---
36 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 151 ++++++++++-------------
37 1 file changed, 62 insertions(+), 89 deletions(-)
38
39diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
40index 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)
44 return rc;
45 }
46
47-int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp)
48+static int bnx2x_vlan_configure_vid_list(struct bnx2x *bp)
49 {
50 struct bnx2x_vlan_entry *vlan;
51 int rc = 0;
52
53- if (!bp->vlan_cnt) {
54- DP(NETIF_MSG_IFUP, "No need to re-configure vlan filters\n");
55- return 0;
56- }
57-
58+ /* Configure all non-configured entries */
59 list_for_each_entry(vlan, &bp->vlan_reg, link) {
60- /* Prepare for cleanup in case of errors */
61- if (rc) {
62- vlan->hw = false;
63- continue;
64- }
65-
66- if (!vlan->hw)
67+ if (vlan->hw)
68 continue;
69
70- DP(NETIF_MSG_IFUP, "Re-configuring vlan 0x%04x\n", vlan->vid);
71+ if (bp->vlan_cnt >= bp->vlan_credit)
72+ return -ENOBUFS;
73
74 rc = __bnx2x_vlan_configure_vid(bp, vlan->vid, true);
75 if (rc) {
76- BNX2X_ERR("Unable to configure VLAN %d\n", vlan->vid);
77- vlan->hw = false;
78- rc = -EINVAL;
79- continue;
80+ BNX2X_ERR("Unable to config VLAN %d\n", vlan->vid);
81+ return rc;
82 }
83+
84+ DP(NETIF_MSG_IFUP, "HW configured for VLAN %d\n", vlan->vid);
85+ vlan->hw = true;
86+ bp->vlan_cnt++;
87 }
88
89- return rc;
90+ return 0;
91+}
92+
93+static void bnx2x_vlan_configure(struct bnx2x *bp, bool set_rx_mode)
94+{
95+ bool need_accept_any_vlan;
96+
97+ need_accept_any_vlan = !!bnx2x_vlan_configure_vid_list(bp);
98+
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");
103+ if (set_rx_mode) {
104+ if (IS_PF(bp))
105+ bnx2x_set_rx_mode_inner(bp);
106+ else
107+ bnx2x_vfpf_storm_rx_mode(bp);
108+ }
109+ }
110+}
111+
112+int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp)
113+{
114+ struct bnx2x_vlan_entry *vlan;
115+
116+ /* The hw forgot all entries after reload */
117+ list_for_each_entry(vlan, &bp->vlan_reg, link)
118+ vlan->hw = false;
119+ bp->vlan_cnt = 0;
120+
121+ /* Don't set rx mode here. Our caller will do it. */
122+ bnx2x_vlan_configure(bp, false);
123+
124+ return 0;
125 }
126
127 static int bnx2x_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
128 {
129 struct bnx2x *bp = netdev_priv(dev);
130 struct bnx2x_vlan_entry *vlan;
131- bool hw = false;
132- int rc = 0;
133-
134- if (!netif_running(bp->dev)) {
135- DP(NETIF_MSG_IFUP,
136- "Ignoring VLAN configuration the interface is down\n");
137- return -EFAULT;
138- }
139
140 DP(NETIF_MSG_IFUP, "Adding VLAN %d\n", vid);
141
142@@ -12948,93 +12967,47 @@ static int bnx2x_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
143 if (!vlan)
144 return -ENOMEM;
145
146- bp->vlan_cnt++;
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;
150- if (IS_PF(bp))
151- bnx2x_set_rx_mode_inner(bp);
152- else
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);
156- hw = true;
157- }
158-
159 vlan->vid = vid;
160- vlan->hw = hw;
161+ vlan->hw = false;
162+ list_add_tail(&vlan->link, &bp->vlan_reg);
163
164- if (!rc) {
165- list_add(&vlan->link, &bp->vlan_reg);
166- } else {
167- bp->vlan_cnt--;
168- kfree(vlan);
169- }
170-
171- DP(NETIF_MSG_IFUP, "Adding VLAN result %d\n", rc);
172+ if (netif_running(dev))
173+ bnx2x_vlan_configure(bp, true);
174
175- return rc;
176+ return 0;
177 }
178
179 static int bnx2x_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
180 {
181 struct bnx2x *bp = netdev_priv(dev);
182 struct bnx2x_vlan_entry *vlan;
183+ bool found = false;
184 int rc = 0;
185
186- if (!netif_running(bp->dev)) {
187- DP(NETIF_MSG_IFUP,
188- "Ignoring VLAN configuration the interface is down\n");
189- return -EFAULT;
190- }
191-
192 DP(NETIF_MSG_IFUP, "Removing VLAN %d\n", vid);
193
194- if (!bp->vlan_cnt) {
195- BNX2X_ERR("Unable to kill VLAN %d\n", vid);
196- return -EINVAL;
197- }
198-
199 list_for_each_entry(vlan, &bp->vlan_reg, link)
200- if (vlan->vid == vid)
201+ if (vlan->vid == vid) {
202+ found = true;
203 break;
204+ }
205
206- if (vlan->vid != vid) {
207+ if (!found) {
208 BNX2X_ERR("Unable to kill VLAN %d - not found\n", vid);
209 return -EINVAL;
210 }
211
212- if (vlan->hw)
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);
216+ bp->vlan_cnt--;
217+ }
218
219 list_del(&vlan->link);
220 kfree(vlan);
221
222- bp->vlan_cnt--;
223-
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) {
227- if (vlan->hw)
228- continue;
229-
230- rc = __bnx2x_vlan_configure_vid(bp, vlan->vid, true);
231- if (rc) {
232- BNX2X_ERR("Unable to config VLAN %d\n",
233- vlan->vid);
234- continue;
235- }
236- DP(NETIF_MSG_IFUP, "HW configured for VLAN %d\n",
237- vlan->vid);
238- vlan->hw = true;
239- }
240- DP(NETIF_MSG_IFUP, "Accept all VLAN Removed\n");
241- bp->accept_any_vlan = false;
242- if (IS_PF(bp))
243- bnx2x_set_rx_mode_inner(bp);
244- else
245- bnx2x_vfpf_storm_rx_mode(bp);
246- }
247+ if (netif_running(dev))
248+ bnx2x_vlan_configure(bp, true);
249
250 DP(NETIF_MSG_IFUP, "Removing VLAN result %d\n", rc);
251
252--
2532.1.4
254