* [PATCH 2/4] mac80211: Remove unused 'len' variable
From: Kirtika Ruchandani @ 2016-11-24 4:45 UTC (permalink / raw)
To: Johannes Berg
Cc: Arnd Bergmann, netdev, linux-wireless, Marek Kwaczynski,
David Spinadel, Alexander Bondar, Michal Kazior
In-Reply-To: <cover.1479962513.git.kirtika@chromium.org>
Commit 633e27132625 (mac80211: split sched scan IEs) introduced the
len variable to keep track of the return value of
ieee80211_build_preq_ies() but did not use it. Compiling with W=1
gives the following warning, fix it.
net/mac80211/scan.c: In function ‘__ieee80211_request_sched_scan_start’:
net/mac80211/scan.c:1123:9: warning: variable ‘len’ set but not used [-Wunused-but-set-variable]
This is a harmless warning and is only being fixed to reduce the noise
with W=1 in the kernel.
Fixes: 633e27132625 ("mac80211: split sched scan IEs")
Cc: David Spinadel <david.spinadel@intel.com>
Cc: Alexander Bondar <alexander.bondar@intel.com>
Cc: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Kirtika Ruchandani <kirtika@chromium.org>
---
net/mac80211/scan.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 23d8ac8..faab3c4 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -1120,7 +1120,6 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
u32 rate_masks[NUM_NL80211_BANDS] = {};
u8 bands_used = 0;
u8 *ie;
- size_t len;
iebufsz = local->scan_ies_len + req->ie_len;
@@ -1145,10 +1144,9 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
ieee80211_prepare_scan_chandef(&chandef, req->scan_width);
- len = ieee80211_build_preq_ies(local, ie, num_bands * iebufsz,
- &sched_scan_ies, req->ie,
- req->ie_len, bands_used,
- rate_masks, &chandef);
+ ieee80211_build_preq_ies(local, ie, num_bands * iebufsz,
+ &sched_scan_ies, req->ie,
+ req->ie_len, bands_used, rate_masks, &chandef);
ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies);
if (ret == 0) {
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH 1/4] mac80211: Removed unused 'i' variable
From: Kirtika Ruchandani @ 2016-11-24 4:45 UTC (permalink / raw)
To: Johannes Berg
Cc: Arnd Bergmann, netdev, linux-wireless, Marek Kwaczynski,
David Spinadel, Alexander Bondar, Michal Kazior
In-Reply-To: <cover.1479962513.git.kirtika@chromium.org>
Commit 5bcae31d9 (mac80211: implement multi-vif in-place reservations)
introduced ieee80211_vif_use_reserved_switch() with a counter variable
'i' that is set but not used. Compiling with W=1 gives the following
warning, fix it.
net/mac80211/chan.c: In function ‘ieee80211_vif_use_reserved_switch’:
net/mac80211/chan.c:1273:6: warning: variable ‘i’ set but not used [-Wunused-but-set-variable]
This is a harmless warning, and is only being fixed to reduce the
noise obtained with W=1 in the kernel.
Fixes: 5bcae31d9 ("mac80211: implement multi-vif in-place reservations")
Cc: Michal Kazior <michal.kazior@tieto.com>
Cc: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Kirtika Ruchandani <kirtika@chromium.org>
---
net/mac80211/chan.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index e75cbf6..7550fd2 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -1270,7 +1270,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
struct ieee80211_sub_if_data *sdata, *sdata_tmp;
struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx;
struct ieee80211_chanctx *new_ctx = NULL;
- int i, err, n_assigned, n_reserved, n_ready;
+ int err, n_assigned, n_reserved, n_ready;
int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0;
lockdep_assert_held(&local->mtx);
@@ -1391,8 +1391,6 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
* Update all structures, values and pointers to point to new channel
* context(s).
*/
-
- i = 0;
list_for_each_entry(ctx, &local->chanctx_list, list) {
if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
continue;
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH 0/4] Fix -Wunused-but-set-variable in net/mac80211/
From: Kirtika Ruchandani @ 2016-11-24 4:45 UTC (permalink / raw)
To: Johannes Berg
Cc: Arnd Bergmann, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, Marek Kwaczynski,
David Spinadel, Alexander Bondar, Michal Kazior
This patchset is part of the effort led by Arnd Bergmann to clean up
warnings in the kernel. This and following patchsets will focus on
"-Wunused-but-set-variable" as it among the noisier ones. These were
found compiling with W=1.
Kirtika Ruchandani (4):
mac80211: Removed unused 'i' variable
mac80211: Remove unused 'len' variable
mac80211: Removed unused 'struct ieee80211_supported_band*' variable
mac80211: Remove unused 'beaconint_us' variable
net/mac80211/chan.c | 4 +---
net/mac80211/mlme.c | 4 ----
net/mac80211/scan.c | 8 +++-----
net/mac80211/vht.c | 4 ----
4 files changed, 4 insertions(+), 16 deletions(-)
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply
* linux-next: manual merge of the staging tree with the net-next tree
From: Stephen Rothwell @ 2016-11-24 3:42 UTC (permalink / raw)
To: Greg KH, David Miller, Networking
Cc: linux-next, linux-kernel, Jarod Wilson, Erik Arfvidson,
David Kershner
Hi Greg,
Today's linux-next merge of the staging tree got a conflict in:
drivers/staging/unisys/include/iochannel.h
between commit:
d0c2c9973ecd ("net: use core MTU range checking in virt drivers")
from the net-next tree and commit:
b18f9c676f93 ("staging: unisys: include: fix pound defines")
from the staging tree.
I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging. You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.
--
Cheers,
Stephen Rothwell
diff --cc drivers/staging/unisys/include/iochannel.h
index 9081b3f8779c,c43da782f37e..000000000000
--- a/drivers/staging/unisys/include/iochannel.h
+++ b/drivers/staging/unisys/include/iochannel.h
@@@ -113,10 -117,12 +117,10 @@@ enum net_types
};
- #define ETH_MIN_DATA_SIZE 46 /* minimum eth data size */
- #define ETH_MIN_PACKET_SIZE (ETH_HLEN + ETH_MIN_DATA_SIZE)
-#define ETH_HEADER_SIZE 14 /* size of ethernet header */
-
+ #define ETH_MIN_DATA_SIZE 46 /* minimum eth data size */
-#define ETH_MIN_PACKET_SIZE (ETH_HEADER_SIZE + ETH_MIN_DATA_SIZE)
++#define ETH_MIN_PACKET_SIZE (ETH_HLEN + ETH_MIN_DATA_SIZE)
- #define VISOR_ETH_MAX_MTU 16384 /* maximum data size */
-#define ETH_MAX_MTU 16384 /* maximum data size */
++#define VISOR_ETH_MAX_MTU 16384 /* maximum data size */
#ifndef MAX_MACADDR_LEN
#define MAX_MACADDR_LEN 6 /* number of bytes in MAC address */
@@@ -286,9 -304,9 +302,9 @@@ struct net_pkt_xmt
int len; /* full length of data in the packet */
int num_frags; /* number of fragments in frags containing data */
struct phys_info frags[MAX_PHYS_INFO]; /* physical page information */
- char ethhdr[ETH_HEADER_SIZE]; /* the ethernet header */
+ char ethhdr[ETH_HLEN]; /* the ethernet header */
struct {
- /* these are needed for csum at uisnic end */
+ /* These are needed for csum at uisnic end */
u8 valid; /* 1 = struct is valid - else ignore */
u8 hrawoffv; /* 1 = hwrafoff is valid */
u8 nhrawoffv; /* 1 = nhwrafoff is valid */
@@@ -321,29 -341,41 +339,41 @@@ struct net_pkt_xmtdone
*/
#define RCVPOST_BUF_SIZE 4032
#define MAX_NET_RCV_CHAIN \
- ((ETH_MAX_MTU + ETH_HEADER_SIZE + RCVPOST_BUF_SIZE - 1) \
+ ((VISOR_ETH_MAX_MTU + ETH_HLEN + RCVPOST_BUF_SIZE - 1) \
/ RCVPOST_BUF_SIZE)
+ /*
+ * rcv buf size must be large enough to include ethernet data len + ethernet
+ * header len - we are choosing 2K because it is guaranteed to be describable.
+ */
struct net_pkt_rcvpost {
- /* rcv buf size must be large enough to include ethernet data len +
- * ethernet header len - we are choosing 2K because it is guaranteed
- * to be describable
- */
- struct phys_info frag; /* physical page information for the */
- /* single fragment 2K rcv buf */
- u64 unique_num;
- /* unique_num ensure that receive posts are returned to */
- /* the Adapter which we sent them originally. */
+ /* Physical page information for the single fragment 2K rcv buf */
+ struct phys_info frag;
+
+ /*
+ * Ensures that receive posts are returned to the adapter which we sent
+ * them from originally.
+ */
+ u64 unique_num;
+
} __packed;
+ /*
+ * The number of rcvbuf that can be chained is based on max mtu and size of each
+ * rcvbuf.
+ */
struct net_pkt_rcv {
- /* the number of receive buffers that can be chained */
- /* is based on max mtu and size of each rcv buf */
- u32 rcv_done_len; /* length of received data */
- u8 numrcvbufs; /* number of receive buffers that contain the */
- /* incoming data; guest end MUST chain these together. */
- void *rcvbuf[MAX_NET_RCV_CHAIN]; /* list of chained rcvbufs */
- /* each entry is a receive buffer provided by NET_RCV_POST. */
+ u32 rcv_done_len; /* length of received data */
+
+ /*
+ * numrcvbufs: contain the incoming data; guest side MUST chain these
+ * together.
+ */
+ u8 numrcvbufs;
+
+ void *rcvbuf[MAX_NET_RCV_CHAIN]; /* list of chained rcvbufs */
+
+ /* Each entry is a receive buffer provided by NET_RCV_POST. */
/* NOTE: first rcvbuf in the chain will also be provided in net.buf. */
u64 unique_num;
u32 rcvs_dropped_delta;
^ permalink raw reply
* RE: [PATCH net 1/2] r8152: fix the sw rx checksum is unavailable
From: Hayes Wang @ 2016-11-24 3:24 UTC (permalink / raw)
To: Mark Lord, netdev@vger.kernel.org
Cc: nic_swsd, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org
In-Reply-To: <95fa9f67-3af6-6749-0e2b-c95406486f7d@pobox.com>
Mark Lord [mailto:mlord@pobox.com]
> Sent: Thursday, November 24, 2016 3:30 AM
[...]
> Worth repeating: other dongles we have tried, eg. those using the asix driver,
> do not cause us any troubles here. Only the r8152 dongles do.
I couldn't tell you why you would see the problem. I have tested the
RTL8152 on raspberry pi platform with iperf more than 17 hours. And
I don't see any invalid rx descriptor. I don't think it really is the
issue about our hw.
Best Regards,
Hayes
^ permalink raw reply
* [scr265482] ip_tunnel.c
From: Liyang Yu (于立洋1) @ 2016-11-24 2:47 UTC (permalink / raw)
To: security@kernel.org, netdev@vger.kernel.org; +Cc: cve-request@mitre.org
In-Reply-To: <860a2905e7f7467f864e13839eb05222@imshyb02.MITRE.ORG>
Hi:
I found that the GRE tunnel in same case can cause integer overflow in ip_tunnel.c:397
Cause of the problem:
When tpi->seq less than tunnel->i_seqno, the packet will be droped.
How to recurrence problem
1. Create an tunnel use kernel GRE module.
2. Use the tunnel to send packets for awile.
3.Reboot one site of the tunnel.
4. Communication interrupted
if (tunnel->parms.i_flags&TUNNEL_SEQ) {
if (!(tpi->flags&TUNNEL_SEQ) ||
(tunnel->i_seqno && (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0)) { /**Here is the trouble code* /
tunnel->dev->stats.rx_fifo_errors++;
tunnel->dev->stats.rx_errors++;
goto drop;
}
tunnel->i_seqno = ntohl(tpi->seq) + 1;
}
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
> Integer Overflow in ip_tunnel.c in Ubuntu Linux kernel GRE ALL kernel
> version allows attacker to Denial of Service via reboot one end of the
> tunnel
Could you please clarify whether this affects only Ubuntu, or potentially affects other Linux distributions? ip_tunnel.c is present in the Linux kernel in all distributions and is maintained at:
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/log/net/ipv4/ip_tunnel.c
You should provide your evidence of an integer overflow, such as source code or crash tracing.
If you are reporting an Ubuntu issue, please see:
https://wiki.ubuntu.com/SecurityTeam/FAQ#Contact
about how to file a Private Security bug in Launchpad.
If you are reporting an issue affecting the Linux kernel in general, please contact:
security@kernel.org
You can also include:
netdev@vger.kernel.org
if the report is public. If you need to subscribe, see:
http://vger.kernel.org/vger-lists.html#netdev
- --
CVE Assignment Team
M/S M300, 202 Burlington Road, Bedford, MA 01730 USA [ A PGP key is available for encrypted communications at
http://cve.mitre.org/cve/request_id.html ] -----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAEBCAAGBQJYNeETAAoJEHb/MwWLVhi26RcP/R38S6V0LFGPHOTFNjTapcnV
RPKycC/lOCGjQehDAUkhxxTwolJpJF3RWeI+KL/hOvxA+LP3B3YeYdoYnQyZ6SqI
8J+zz5vV5mCP3olKYynO4S32bBn8rZiwoWsFWPaC4ILmoQFTLZiDbH6ji3DrHewm
OwrTysyC1a7clOuIM3BaPl3Ra0qMHsgR2b16gYMEdi/B1Ya3oLY7MVLTB2AixA9F
BB/aQjFMICfchEF39uQslU3jJd+SPuayLvceiKIvqFqBt1D8Kt2rBamzMmI5MC3M
ZbVBNfXde1MxqlV2WjUzl8KFj2l1zG7IlH1rcRes+6ZI3VaJnbv9Jyi6oc9QzMQc
nFRg9sH/DzD3g40bh2zRBtLqkQeTxxkg3JvaFc2OC2MaxMiobQCso926d4pFxTmd
+x8wP7E/nKvd4+E09/bep/v0+mEOxfSDICNGO/7gBOU4wKZ6IyaNftfe5Q1zDaxv
M3vWI6VqTFx32wY7TE69AHIH7X7WvzsBi7BLj2RHGFg2hwS7n80A1t4BcdYjPdSh
feFxfVH5gGAaG3Bm4jJOCKe5+vRwuJGjnox2+vQvUrD9v+vx0z1D5ooO8Ms2MLnT
kKL7BKhcntcoLJ3TUI09I2HZBSh7R3homgFhgrpbDHd0YjaW6XgqHjAr8piKEToK
V6jChR0YzXTkTlw1jYlE
=z0ta
-----END PGP SIGNATURE-----
^ permalink raw reply
* Re: [PATCH net-next 1/1] ipv6: sr: add option to control lwtunnel support
From: Alexei Starovoitov @ 2016-11-24 2:31 UTC (permalink / raw)
To: David Lebrun
Cc: Roopa Prabhu, David Miller, netdev@vger.kernel.org,
Lorenzo Colitti, Eric Dumazet
In-Reply-To: <5835613D.8070104@uclouvain.be>
On Wed, Nov 23, 2016 at 10:28:29AM +0100, David Lebrun wrote:
> On 11/23/2016 08:34 AM, Roopa Prabhu wrote:
> > I can't seem to reproduce the problem you are seeing. still trying..
> > I don't have CONFIG_LWTUNNEL set nor any of the other SEG6 configs.
> > My CONFIG_IPV6 is on and compiled as a module. I have also tried disabling it.
> > If you can send me the config, I can try again. Looking back at the patches,
> > I do see a few things below ..but they may not fix your problem directly.
> >
> > Though I had none of the ipv6 segment routing configs turned on,
> > I do see the "Segment Routing with IPv6" msg at bootup.
> > Was looking at david's patches again, and a few things (I had missed seeing the last version):
> >
> > In my review comment I was hinting at CONFIG_IPV6_SEG6 to cover all of ipv6 segment routing,
> > including the lwtunnel bits.
> >
> > something like below:
> >
> > config IPV6_SEG6
> > bool "IPv6: Segment Routing Header encapsulation support"
> > depends on LWTUNNEL && IPV6
> >
> > DavidL, do you see a problem doing it this way ?. with this 'seg6.o' will be part of CONFIG_IPV6_SEG6 and not
> > get initialized unless it is enabled..which seems like the right thing to do.
>
> Can't reproduce the bug either, with CONFIG_IPV6=y, LWTUNNEL=n and all
> SEG6 disabled. Alexei, your .config and dmesg log could help.
I didn't save that .config and did bisect of the other bug that
messed up my .confg. Now I cannot reproduce it. Sorry for the noise.
Still weird though that ping prefers ipv6 address now.
$ ping localhost
PING localhost(localhost.localdomain (::1)) 56 data bytes
64 bytes from localhost.localdomain (::1): icmp_seq=1 ttl=64 time=0.043 ms
^ permalink raw reply
* [PATCH net 1/1] tipc: fix compatibility bug in link monitoring
From: Jon Maloy @ 2016-11-24 2:05 UTC (permalink / raw)
To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
commit 817298102b0b ("tipc: fix link priority propagation") introduced a
compatibility problem between TIPC versions newer than Linux 4.6 and
those older than Linux 4.4. In versions later than 4.4, link STATE
messages only contain a non-zero link priority value when the sender
wants the receiver to change its priority. This has the effect that the
receiver resets itself in order to apply the new priority. This works
well, and is consistent with the said commit.
However, in versions older than 4.4 a valid link priority is present in
all sent link STATE messages, leading to cyclic link establishment and
reset on the 4.6+ node.
We fix this by adding a test that the received value should not only
be valid, but also differ from the current value in order to cause the
receiving link endpoint to reset.
Reported-by: Amar Nv <amar.nv005@gmail.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/link.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 1055164..ecc12411 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1492,8 +1492,9 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL))
l->tolerance = peers_tol;
- if (peers_prio && in_range(peers_prio, TIPC_MIN_LINK_PRI,
- TIPC_MAX_LINK_PRI)) {
+ /* Update own prio if peer indicates a different value */
+ if ((peers_prio != l->priority) &&
+ in_range(peers_prio, 1, TIPC_MAX_LINK_PRI)) {
l->priority = peers_prio;
rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
}
--
2.7.4
------------------------------------------------------------------------------
^ permalink raw reply related
* [Patch net-next] net_sched: move the empty tp check from ->destroy() to ->delete()
From: Cong Wang @ 2016-11-24 1:58 UTC (permalink / raw)
To: netdev; +Cc: roid, jiri, Cong Wang, Daniel Borkmann, John Fastabend
Roi reported we could have a race condition where in ->classify() path
we dereference tp->root and meanwhile a parallel ->destroy() makes it
a NULL.
This is possible because ->destroy() could be called when deleting
a filter to check if we are the last one in tp, this tp is still
linked and visible at that time.
The root cause of this problem is the semantic of ->destroy(), it
does two things (for non-force case):
1) check if tp is empty
2) if tp is empty we could really destroy it
and its caller, if cares, needs to check its return value to see if
it is really destroyed. Therefore we can't unlink tp unless we know
it is empty.
As suggested by Daniel, we could actually move the test logic to ->delete()
so that we can safely unlink tp after ->delete() tells us the last one is
just deleted and before ->destroy().
What's more, even we unlink it before ->destroy(), it could still have
readers since we don't wait for a grace period here, we should not modify
tp->root in ->destroy() either.
Fixes: 1e052be69d04 ("net_sched: destroy proto tp when all filters are gone")
Reported-by: Roi Dayan <roid@mellanox.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
include/net/sch_generic.h | 6 ++--
net/sched/cls_api.c | 18 +++++++-----
net/sched/cls_basic.c | 11 +++-----
net/sched/cls_bpf.c | 11 +++-----
net/sched/cls_cgroup.c | 12 ++------
net/sched/cls_flow.c | 11 +++-----
net/sched/cls_flower.c | 10 ++-----
net/sched/cls_fw.c | 30 +++++++++++---------
net/sched/cls_matchall.c | 10 ++-----
net/sched/cls_route.c | 30 ++++++++++----------
net/sched/cls_rsvp.h | 34 +++++++++++------------
net/sched/cls_tcindex.c | 15 +++++-----
net/sched/cls_u32.c | 71 +++++++++++++++++++++++++++--------------------
net/sched/sch_api.c | 14 ++++------
14 files changed, 137 insertions(+), 146 deletions(-)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index e6aa0a2..27cd1bd 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -203,14 +203,14 @@ struct tcf_proto_ops {
const struct tcf_proto *,
struct tcf_result *);
int (*init)(struct tcf_proto*);
- bool (*destroy)(struct tcf_proto*, bool);
+ void (*destroy)(struct tcf_proto*);
unsigned long (*get)(struct tcf_proto*, u32 handle);
int (*change)(struct net *net, struct sk_buff *,
struct tcf_proto*, unsigned long,
u32 handle, struct nlattr **,
unsigned long *, bool);
- int (*delete)(struct tcf_proto*, unsigned long);
+ int (*delete)(struct tcf_proto*, unsigned long, bool*);
void (*walk)(struct tcf_proto*, struct tcf_walker *arg);
/* rtnetlink specific */
@@ -405,7 +405,7 @@ struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops, u32 parentid);
void __qdisc_calculate_pkt_len(struct sk_buff *skb,
const struct qdisc_size_table *stab);
-bool tcf_destroy(struct tcf_proto *tp, bool force);
+void tcf_destroy(struct tcf_proto *tp);
void tcf_destroy_chain(struct tcf_proto __rcu **fl);
int skb_do_redirect(struct sk_buff *);
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 8e93d4a..f159aeb 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -321,7 +321,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
tfilter_notify(net, skb, n, tp, fh,
RTM_DELTFILTER, false);
- tcf_destroy(tp, true);
+ tcf_destroy(tp);
err = 0;
goto errout;
}
@@ -331,25 +331,29 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
!(n->nlmsg_flags & NLM_F_CREATE))
goto errout;
} else {
+ bool last;
+
switch (n->nlmsg_type) {
case RTM_NEWTFILTER:
err = -EEXIST;
if (n->nlmsg_flags & NLM_F_EXCL) {
if (tp_created)
- tcf_destroy(tp, true);
+ tcf_destroy(tp);
goto errout;
}
break;
case RTM_DELTFILTER:
- err = tp->ops->delete(tp, fh);
+ err = tp->ops->delete(tp, fh, &last);
if (err == 0) {
- struct tcf_proto *next = rtnl_dereference(tp->next);
-
tfilter_notify(net, skb, n, tp,
t->tcm_handle,
RTM_DELTFILTER, false);
- if (tcf_destroy(tp, false))
+ if (last) {
+ struct tcf_proto *next = rtnl_dereference(tp->next);
+
RCU_INIT_POINTER(*back, next);
+ tcf_destroy(tp);
+ }
}
goto errout;
case RTM_GETTFILTER:
@@ -372,7 +376,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER, false);
} else {
if (tp_created)
- tcf_destroy(tp, true);
+ tcf_destroy(tp);
}
errout:
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index eb219b7..dd63230 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -96,31 +96,28 @@ static void basic_delete_filter(struct rcu_head *head)
kfree(f);
}
-static bool basic_destroy(struct tcf_proto *tp, bool force)
+static void basic_destroy(struct tcf_proto *tp)
{
struct basic_head *head = rtnl_dereference(tp->root);
struct basic_filter *f, *n;
- if (!force && !list_empty(&head->flist))
- return false;
-
list_for_each_entry_safe(f, n, &head->flist, link) {
list_del_rcu(&f->link);
tcf_unbind_filter(tp, &f->res);
call_rcu(&f->rcu, basic_delete_filter);
}
- RCU_INIT_POINTER(tp->root, NULL);
kfree_rcu(head, rcu);
- return true;
}
-static int basic_delete(struct tcf_proto *tp, unsigned long arg)
+static int basic_delete(struct tcf_proto *tp, unsigned long arg, bool *last)
{
+ struct basic_head *head = rtnl_dereference(tp->root);
struct basic_filter *f = (struct basic_filter *) arg;
list_del_rcu(&f->link);
tcf_unbind_filter(tp, &f->res);
call_rcu(&f->rcu, basic_delete_filter);
+ *last = list_empty(&head->flist);
return 0;
}
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index 52dc85a..770984c0 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -265,26 +265,25 @@ static void __cls_bpf_delete_prog(struct rcu_head *rcu)
cls_bpf_delete_prog(prog->tp, prog);
}
-static int cls_bpf_delete(struct tcf_proto *tp, unsigned long arg)
+static int cls_bpf_delete(struct tcf_proto *tp, unsigned long arg, bool *last)
{
struct cls_bpf_prog *prog = (struct cls_bpf_prog *) arg;
+ struct cls_bpf_head *head = rtnl_dereference(tp->root);
cls_bpf_stop_offload(tp, prog);
list_del_rcu(&prog->link);
tcf_unbind_filter(tp, &prog->res);
call_rcu(&prog->rcu, __cls_bpf_delete_prog);
+ *last = list_empty(&head->plist);
return 0;
}
-static bool cls_bpf_destroy(struct tcf_proto *tp, bool force)
+static void cls_bpf_destroy(struct tcf_proto *tp)
{
struct cls_bpf_head *head = rtnl_dereference(tp->root);
struct cls_bpf_prog *prog, *tmp;
- if (!force && !list_empty(&head->plist))
- return false;
-
list_for_each_entry_safe(prog, tmp, &head->plist, link) {
cls_bpf_stop_offload(tp, prog);
list_del_rcu(&prog->link);
@@ -292,9 +291,7 @@ static bool cls_bpf_destroy(struct tcf_proto *tp, bool force)
call_rcu(&prog->rcu, __cls_bpf_delete_prog);
}
- RCU_INIT_POINTER(tp->root, NULL);
kfree_rcu(head, rcu);
- return true;
}
static unsigned long cls_bpf_get(struct tcf_proto *tp, u32 handle)
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 85233c47..fa9405e 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -131,21 +131,15 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
return err;
}
-static bool cls_cgroup_destroy(struct tcf_proto *tp, bool force)
+static void cls_cgroup_destroy(struct tcf_proto *tp)
{
struct cls_cgroup_head *head = rtnl_dereference(tp->root);
- if (!force)
- return false;
-
- if (head) {
- RCU_INIT_POINTER(tp->root, NULL);
+ if (head)
call_rcu(&head->rcu, cls_cgroup_destroy_rcu);
- }
- return true;
}
-static int cls_cgroup_delete(struct tcf_proto *tp, unsigned long arg)
+static int cls_cgroup_delete(struct tcf_proto *tp, unsigned long arg, bool *last)
{
return -EOPNOTSUPP;
}
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index e396723..ea2be75 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -563,12 +563,14 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
return err;
}
-static int flow_delete(struct tcf_proto *tp, unsigned long arg)
+static int flow_delete(struct tcf_proto *tp, unsigned long arg, bool *last)
{
+ struct flow_head *head = rtnl_dereference(tp->root);
struct flow_filter *f = (struct flow_filter *)arg;
list_del_rcu(&f->list);
call_rcu(&f->rcu, flow_destroy_filter);
+ *last = list_empty(&head->filters);
return 0;
}
@@ -584,21 +586,16 @@ static int flow_init(struct tcf_proto *tp)
return 0;
}
-static bool flow_destroy(struct tcf_proto *tp, bool force)
+static void flow_destroy(struct tcf_proto *tp)
{
struct flow_head *head = rtnl_dereference(tp->root);
struct flow_filter *f, *next;
- if (!force && !list_empty(&head->filters))
- return false;
-
list_for_each_entry_safe(f, next, &head->filters, list) {
list_del_rcu(&f->list);
call_rcu(&f->rcu, flow_destroy_filter);
}
- RCU_INIT_POINTER(tp->root, NULL);
kfree_rcu(head, rcu);
- return true;
}
static unsigned long flow_get(struct tcf_proto *tp, u32 handle)
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index e8dd09a..495d63224 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -280,21 +280,16 @@ static void __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f)
call_rcu(&f->rcu, fl_destroy_filter);
}
-static bool fl_destroy(struct tcf_proto *tp, bool force)
+static void fl_destroy(struct tcf_proto *tp)
{
struct cls_fl_head *head = rtnl_dereference(tp->root);
struct cls_fl_filter *f, *next;
- if (!force && !list_empty(&head->filters))
- return false;
-
list_for_each_entry_safe(f, next, &head->filters, list)
__fl_delete(tp, f);
- RCU_INIT_POINTER(tp->root, NULL);
if (head->mask_assigned)
rhashtable_destroy(&head->ht);
kfree_rcu(head, rcu);
- return true;
}
static unsigned long fl_get(struct tcf_proto *tp, u32 handle)
@@ -777,7 +772,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
return err;
}
-static int fl_delete(struct tcf_proto *tp, unsigned long arg)
+static int fl_delete(struct tcf_proto *tp, unsigned long arg, bool *last)
{
struct cls_fl_head *head = rtnl_dereference(tp->root);
struct cls_fl_filter *f = (struct cls_fl_filter *) arg;
@@ -785,6 +780,7 @@ static int fl_delete(struct tcf_proto *tp, unsigned long arg)
rhashtable_remove_fast(&head->ht, &f->ht_node,
head->ht_params);
__fl_delete(tp, f);
+ *last = list_empty(&head->filters);
return 0;
}
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 9dc63d5..bc8ceb7 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -127,20 +127,14 @@ static void fw_delete_filter(struct rcu_head *head)
kfree(f);
}
-static bool fw_destroy(struct tcf_proto *tp, bool force)
+static void fw_destroy(struct tcf_proto *tp)
{
struct fw_head *head = rtnl_dereference(tp->root);
struct fw_filter *f;
int h;
if (head == NULL)
- return true;
-
- if (!force) {
- for (h = 0; h < HTSIZE; h++)
- if (rcu_access_pointer(head->ht[h]))
- return false;
- }
+ return;
for (h = 0; h < HTSIZE; h++) {
while ((f = rtnl_dereference(head->ht[h])) != NULL) {
@@ -150,17 +144,17 @@ static bool fw_destroy(struct tcf_proto *tp, bool force)
call_rcu(&f->rcu, fw_delete_filter);
}
}
- RCU_INIT_POINTER(tp->root, NULL);
kfree_rcu(head, rcu);
- return true;
}
-static int fw_delete(struct tcf_proto *tp, unsigned long arg)
+static int fw_delete(struct tcf_proto *tp, unsigned long arg, bool *last)
{
struct fw_head *head = rtnl_dereference(tp->root);
struct fw_filter *f = (struct fw_filter *)arg;
struct fw_filter __rcu **fp;
struct fw_filter *pfp;
+ int ret = -EINVAL;
+ int h;
if (head == NULL || f == NULL)
goto out;
@@ -173,11 +167,21 @@ static int fw_delete(struct tcf_proto *tp, unsigned long arg)
RCU_INIT_POINTER(*fp, rtnl_dereference(f->next));
tcf_unbind_filter(tp, &f->res);
call_rcu(&f->rcu, fw_delete_filter);
- return 0;
+ ret = 0;
+ break;
}
}
+
+ *last = true;
+ for (h = 0; h < HTSIZE; h++) {
+ if (rcu_access_pointer(head->ht[h])) {
+ *last = false;
+ break;
+ }
+ }
+
out:
- return -EINVAL;
+ return ret;
}
static const struct nla_policy fw_policy[TCA_FW_MAX + 1] = {
diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
index 25927b6..7d54805 100644
--- a/net/sched/cls_matchall.c
+++ b/net/sched/cls_matchall.c
@@ -99,24 +99,19 @@ static void mall_destroy_hw_filter(struct tcf_proto *tp,
&offload);
}
-static bool mall_destroy(struct tcf_proto *tp, bool force)
+static void mall_destroy(struct tcf_proto *tp)
{
struct cls_mall_head *head = rtnl_dereference(tp->root);
struct net_device *dev = tp->q->dev_queue->dev;
struct cls_mall_filter *f = head->filter;
- if (!force && f)
- return false;
-
if (f) {
if (tc_should_offload(dev, tp, f->flags))
mall_destroy_hw_filter(tp, f, (unsigned long) f);
call_rcu(&f->rcu, mall_destroy_filter);
}
- RCU_INIT_POINTER(tp->root, NULL);
kfree_rcu(head, rcu);
- return true;
}
static unsigned long mall_get(struct tcf_proto *tp, u32 handle)
@@ -225,7 +220,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
return err;
}
-static int mall_delete(struct tcf_proto *tp, unsigned long arg)
+static int mall_delete(struct tcf_proto *tp, unsigned long arg, bool *last)
{
struct cls_mall_head *head = rtnl_dereference(tp->root);
struct cls_mall_filter *f = (struct cls_mall_filter *) arg;
@@ -237,6 +232,7 @@ static int mall_delete(struct tcf_proto *tp, unsigned long arg)
RCU_INIT_POINTER(head->filter, NULL);
tcf_unbind_filter(tp, &f->res);
call_rcu(&f->rcu, mall_destroy_filter);
+ *last = true;
return 0;
}
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 455fc8f..1a38e41 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -276,20 +276,13 @@ static void route4_delete_filter(struct rcu_head *head)
kfree(f);
}
-static bool route4_destroy(struct tcf_proto *tp, bool force)
+static void route4_destroy(struct tcf_proto *tp)
{
struct route4_head *head = rtnl_dereference(tp->root);
int h1, h2;
if (head == NULL)
- return true;
-
- if (!force) {
- for (h1 = 0; h1 <= 256; h1++) {
- if (rcu_access_pointer(head->table[h1]))
- return false;
- }
- }
+ return;
for (h1 = 0; h1 <= 256; h1++) {
struct route4_bucket *b;
@@ -312,12 +305,10 @@ static bool route4_destroy(struct tcf_proto *tp, bool force)
kfree_rcu(b, rcu);
}
}
- RCU_INIT_POINTER(tp->root, NULL);
kfree_rcu(head, rcu);
- return true;
}
-static int route4_delete(struct tcf_proto *tp, unsigned long arg)
+static int route4_delete(struct tcf_proto *tp, unsigned long arg, bool *last)
{
struct route4_head *head = rtnl_dereference(tp->root);
struct route4_filter *f = (struct route4_filter *)arg;
@@ -325,7 +316,7 @@ static int route4_delete(struct tcf_proto *tp, unsigned long arg)
struct route4_filter *nf;
struct route4_bucket *b;
unsigned int h = 0;
- int i;
+ int i, h1;
if (!head || !f)
return -EINVAL;
@@ -356,16 +347,25 @@ static int route4_delete(struct tcf_proto *tp, unsigned long arg)
rt = rtnl_dereference(b->ht[i]);
if (rt)
- return 0;
+ goto out;
}
/* OK, session has no flows */
RCU_INIT_POINTER(head->table[to_hash(h)], NULL);
kfree_rcu(b, rcu);
+ break;
+ }
+ }
- return 0;
+out:
+ *last = true;
+ for (h1 = 0; h1 <= 256; h1++) {
+ if (rcu_access_pointer(head->table[h1])) {
+ *last = false;
+ break;
}
}
+
return 0;
}
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 4f05a19..e8ba81a 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -301,22 +301,13 @@ static void rsvp_delete_filter(struct tcf_proto *tp, struct rsvp_filter *f)
call_rcu(&f->rcu, rsvp_delete_filter_rcu);
}
-static bool rsvp_destroy(struct tcf_proto *tp, bool force)
+static void rsvp_destroy(struct tcf_proto *tp)
{
struct rsvp_head *data = rtnl_dereference(tp->root);
int h1, h2;
if (data == NULL)
- return true;
-
- if (!force) {
- for (h1 = 0; h1 < 256; h1++) {
- if (rcu_access_pointer(data->ht[h1]))
- return false;
- }
- }
-
- RCU_INIT_POINTER(tp->root, NULL);
+ return;
for (h1 = 0; h1 < 256; h1++) {
struct rsvp_session *s;
@@ -336,10 +327,9 @@ static bool rsvp_destroy(struct tcf_proto *tp, bool force)
}
}
kfree_rcu(data, rcu);
- return true;
}
-static int rsvp_delete(struct tcf_proto *tp, unsigned long arg)
+static int rsvp_delete(struct tcf_proto *tp, unsigned long arg, bool *last)
{
struct rsvp_head *head = rtnl_dereference(tp->root);
struct rsvp_filter *nfp, *f = (struct rsvp_filter *)arg;
@@ -347,7 +337,7 @@ static int rsvp_delete(struct tcf_proto *tp, unsigned long arg)
unsigned int h = f->handle;
struct rsvp_session __rcu **sp;
struct rsvp_session *nsp, *s = f->sess;
- int i;
+ int i, h1;
fp = &s->ht[(h >> 8) & 0xFF];
for (nfp = rtnl_dereference(*fp); nfp;
@@ -360,7 +350,7 @@ static int rsvp_delete(struct tcf_proto *tp, unsigned long arg)
for (i = 0; i <= 16; i++)
if (s->ht[i])
- return 0;
+ goto out;
/* OK, session has no flows */
sp = &head->ht[h & 0xFF];
@@ -369,13 +359,23 @@ static int rsvp_delete(struct tcf_proto *tp, unsigned long arg)
if (nsp == s) {
RCU_INIT_POINTER(*sp, s->next);
kfree_rcu(s, rcu);
- return 0;
+ goto out;
}
}
- return 0;
+ break;
}
}
+
+out:
+ *last = true;
+ for (h1 = 0; h1 < 256; h1++) {
+ if (rcu_access_pointer(head->ht[h1])) {
+ *last = false;
+ break;
+ }
+ }
+
return 0;
}
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 96144bd..9149a03 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -150,7 +150,7 @@ static void tcindex_destroy_fexts(struct rcu_head *head)
kfree(f);
}
-static int tcindex_delete(struct tcf_proto *tp, unsigned long arg)
+static int tcindex_delete(struct tcf_proto *tp, unsigned long arg, bool *last)
{
struct tcindex_data *p = rtnl_dereference(tp->root);
struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg;
@@ -186,6 +186,8 @@ static int tcindex_delete(struct tcf_proto *tp, unsigned long arg)
call_rcu(&f->rcu, tcindex_destroy_fexts);
else
call_rcu(&r->rcu, tcindex_destroy_rexts);
+
+ *last = false;
return 0;
}
@@ -193,7 +195,9 @@ static int tcindex_destroy_element(struct tcf_proto *tp,
unsigned long arg,
struct tcf_walker *walker)
{
- return tcindex_delete(tp, arg);
+ bool last;
+
+ return tcindex_delete(tp, arg, &last);
}
static void __tcindex_destroy(struct rcu_head *head)
@@ -529,23 +533,18 @@ static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker)
}
}
-static bool tcindex_destroy(struct tcf_proto *tp, bool force)
+static void tcindex_destroy(struct tcf_proto *tp)
{
struct tcindex_data *p = rtnl_dereference(tp->root);
struct tcf_walker walker;
- if (!force)
- return false;
-
pr_debug("tcindex_destroy(tp %p),p %p\n", tp, p);
walker.count = 0;
walker.skip = 0;
walker.fn = tcindex_destroy_element;
tcindex_walk(tp, &walker);
- RCU_INIT_POINTER(tp->root, NULL);
call_rcu(&p->rcu, __tcindex_destroy);
- return true;
}
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index ae83c3ae..787573b 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -582,37 +582,13 @@ static bool ht_empty(struct tc_u_hnode *ht)
return true;
}
-static bool u32_destroy(struct tcf_proto *tp, bool force)
+static void u32_destroy(struct tcf_proto *tp)
{
struct tc_u_common *tp_c = tp->data;
struct tc_u_hnode *root_ht = rtnl_dereference(tp->root);
WARN_ON(root_ht == NULL);
- if (!force) {
- if (root_ht) {
- if (root_ht->refcnt > 1)
- return false;
- if (root_ht->refcnt == 1) {
- if (!ht_empty(root_ht))
- return false;
- }
- }
-
- if (tp_c->refcnt > 1)
- return false;
-
- if (tp_c->refcnt == 1) {
- struct tc_u_hnode *ht;
-
- for (ht = rtnl_dereference(tp_c->hlist);
- ht;
- ht = rtnl_dereference(ht->next))
- if (!ht_empty(ht))
- return false;
- }
- }
-
if (root_ht && --root_ht->refcnt == 0)
u32_destroy_hnode(tp, root_ht);
@@ -637,20 +613,22 @@ static bool u32_destroy(struct tcf_proto *tp, bool force)
}
tp->data = NULL;
- return true;
}
-static int u32_delete(struct tcf_proto *tp, unsigned long arg)
+static int u32_delete(struct tcf_proto *tp, unsigned long arg, bool *last)
{
struct tc_u_hnode *ht = (struct tc_u_hnode *)arg;
struct tc_u_hnode *root_ht = rtnl_dereference(tp->root);
+ struct tc_u_common *tp_c = tp->data;
+ int ret = 0;
if (ht == NULL)
- return 0;
+ goto out;
if (TC_U32_KEY(ht->handle)) {
u32_remove_hw_knode(tp, ht->handle);
- return u32_delete_key(tp, (struct tc_u_knode *)ht);
+ ret = u32_delete_key(tp, (struct tc_u_knode *)ht);
+ goto out;
}
if (root_ht == ht)
@@ -663,7 +641,40 @@ static int u32_delete(struct tcf_proto *tp, unsigned long arg)
return -EBUSY;
}
- return 0;
+out:
+ *last = true;
+ if (root_ht) {
+ if (root_ht->refcnt > 1) {
+ *last = false;
+ goto ret;
+ }
+ if (root_ht->refcnt == 1) {
+ if (!ht_empty(root_ht)) {
+ *last = false;
+ goto ret;
+ }
+ }
+ }
+
+ if (tp_c->refcnt > 1) {
+ *last = false;
+ goto ret;
+ }
+
+ if (tp_c->refcnt == 1) {
+ struct tc_u_hnode *ht;
+
+ for (ht = rtnl_dereference(tp_c->hlist);
+ ht;
+ ht = rtnl_dereference(ht->next))
+ if (!ht_empty(ht)) {
+ *last = false;
+ break;
+ }
+ }
+
+ret:
+ return ret;
}
#define NR_U32_NODE (1<<12)
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index f337f1b..7fc48b3 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1899,15 +1899,11 @@ int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp,
}
EXPORT_SYMBOL(tc_classify);
-bool tcf_destroy(struct tcf_proto *tp, bool force)
+void tcf_destroy(struct tcf_proto *tp)
{
- if (tp->ops->destroy(tp, force)) {
- module_put(tp->ops->owner);
- kfree_rcu(tp, rcu);
- return true;
- }
-
- return false;
+ tp->ops->destroy(tp);
+ module_put(tp->ops->owner);
+ kfree_rcu(tp, rcu);
}
void tcf_destroy_chain(struct tcf_proto __rcu **fl)
@@ -1916,7 +1912,7 @@ void tcf_destroy_chain(struct tcf_proto __rcu **fl)
while ((tp = rtnl_dereference(*fl)) != NULL) {
RCU_INIT_POINTER(*fl, tp->next);
- tcf_destroy(tp, true);
+ tcf_destroy(tp);
}
}
EXPORT_SYMBOL(tcf_destroy_chain);
--
2.1.0
^ permalink raw reply related
* Re: [RFC net-next 1/3] net: bridge: Allow bridge master device to configure switch CPU port
From: Toshiaki Makita @ 2016-11-24 1:49 UTC (permalink / raw)
To: Vivien Didelot, Florian Fainelli, netdev
Cc: idosch, andrew, bridge, jiri, davem
In-Reply-To: <87h96zzfe6.fsf@ketchup.i-did-not-set--mail-host-address--so-tickle-me>
On 2016/11/23 0:46, Vivien Didelot wrote:
> Hi Florian,
>
> Florian Fainelli <f.fainelli@gmail.com> writes:
>
>> bridge vlan add vid 2 dev br0 self
>> -> CPU port gets programmed
>> bridge vlan add vid 2 dev port0
>> -> port0 (switch port 0) gets programmed
>
> Although this is not specific to this patch, I'd like to point out that
> this seems not to be the behavior bridge expects.
>
> The bridge manpage says:
>
> bridge vlan add - add a new vlan filter entry
> ...
>
> self the vlan is configured on the specified physical device.
> Required if the device is the bridge device.
>
> master the vlan is configured on the software bridge (default).
>
> So if I'm not mistaken, the switch chip must be programmed only when the
> bridge command is called with the "self" attribute. Without it, only
> software configuration must be made, like what happens when the driver
> returns -EOPNOTSUPP.
>
> Currently, both commands below program the hardware:
>
> # bridge vlan add vid 2 dev port0 [master]
> # bridge vlan add vid 2 dev port0 [master] self
Actually this is intended behavior, which keeps backward compatibility.
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=7f1095394918c7058ff81c96c3bab3a897e97a9d
Thanks,
Toshiaki Makita
^ permalink raw reply
* Re: [PATCH net] net/mlx4_en: Free netdev resources under state lock
From: David Miller @ 2016-11-24 1:28 UTC (permalink / raw)
To: tariqt; +Cc: netdev, eranbe, saeedm, sagi, bblanco
In-Reply-To: <1479824439-27353-1-git-send-email-tariqt@mellanox.com>
From: Tariq Toukan <tariqt@mellanox.com>
Date: Tue, 22 Nov 2016 16:20:39 +0200
> Make sure mlx4_en_free_resources is called under the netdev state lock.
> This is needed since RCU dereference of XDP prog should be protected.
>
> Fixes: 326fe02d1ed6 ("net/mlx4_en: protect ring->xdp_prog with rcu_read_lock")
> Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
> Reported-by: Sagi Grimberg <sagi@grimberg.me>
Applied.
^ permalink raw reply
* Re: [Patch net] net: revert "net: l2tp: Treat NET_XMIT_CN as success in l2tp_eth_dev_xmit"
From: David Miller @ 2016-11-24 1:28 UTC (permalink / raw)
To: xiyou.wangcong; +Cc: netdev, gfree.wind
In-Reply-To: <1479799483-18332-1-git-send-email-xiyou.wangcong@gmail.com>
From: Cong Wang <xiyou.wangcong@gmail.com>
Date: Mon, 21 Nov 2016 23:24:43 -0800
> This reverts commit 7c6ae610a1f0, because l2tp_xmit_skb() never
> returns NET_XMIT_CN, it ignores the return value of l2tp_xmit_core().
>
> Cc: Gao Feng <gfree.wind@gmail.com>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Applied.
^ permalink raw reply
* Re: [net] rtnetlink: fix the wrong minimal dump size getting from rtnl_calcit()
From: David Miller @ 2016-11-24 1:27 UTC (permalink / raw)
To: zhangshengju; +Cc: netdev, roopa
In-Reply-To: <1479795268-11801-1-git-send-email-zhangshengju@cmss.chinamobile.com>
From: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
Date: Tue, 22 Nov 2016 14:14:28 +0800
> For RT netlink, calcit() function should return the minimal size for
> netlink dump message. This will make sure that dump message for every
> network device can be stored.
>
> Currently, rtnl_calcit() function doesn't account the size of header of
> netlink message, this patch will fix it.
>
> Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
Applied.
^ permalink raw reply
* Re: [PATCH] bnxt_en: Fix a VXLAN vs GENEVE issue
From: David Miller @ 2016-11-24 1:27 UTC (permalink / raw)
To: christophe.jaillet
Cc: michael.chan, prashant.sreedharan, netdev, kernel-janitors
In-Reply-To: <20161122051440.9748-1-christophe.jaillet@wanadoo.fr>
From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Date: Tue, 22 Nov 2016 06:14:40 +0100
> Knowing that:
> #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN (0x1UL << 0)
> #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE (0x5UL << 0)
> and that 'bnxt_hwrm_tunnel_dst_port_alloc()' is only called with one of
> these 2 constants, the TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_GENEVE can not
> trigger.
>
> Replace the bit test that overlap by an equality test, just as in
> 'bnxt_hwrm_tunnel_dst_port_free()' above.
>
> Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Applied.
^ permalink raw reply
* Re: [PATCH] netdevice.h: fix kernel-doc warning
From: David Miller @ 2016-11-24 1:27 UTC (permalink / raw)
To: rdunlap; +Cc: netdev
In-Reply-To: <89f2d6da-89e1-1962-9f6f-e81dece8a101@infradead.org>
From: Randy Dunlap <rdunlap@infradead.org>
Date: Mon, 21 Nov 2016 18:28:36 -0800
> From: Randy Dunlap <rdunlap@infradead.org>
>
> Fix kernel-doc warning in <linux/netdevice.h> (missing ':'):
>
> ..//include/linux/netdevice.h:1904: warning: No description found for parameter 'prio_tc_map[TC_BITMASK + 1]'
>
> Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Applied.
^ permalink raw reply
* Re: [PATCH net 1/1] driver: macvlan: Check if need rollback multicast setting in macvlan_open
From: David Miller @ 2016-11-24 1:26 UTC (permalink / raw)
To: fgao; +Cc: kaber, netdev, gfree.wind
In-Reply-To: <1479779676-10417-1-git-send-email-fgao@ikuai8.com>
From: fgao@ikuai8.com
Date: Tue, 22 Nov 2016 09:54:36 +0800
> From: Gao Feng <fgao@ikuai8.com>
>
> When dev_set_promiscuity failed in macvlan_open, it always invokes
> dev_set_allmulti without checking if necessary.
> Now check the IFF_ALLMULTI flag firstly before rollback the multicast
> setting in the error handler.
>
> Signed-off-by: Gao Feng <fgao@ikuai8.com>
Applied.
^ permalink raw reply
* Re: [PATCH] net: phy: micrel: fix KSZ8041FTL supported value
From: David Miller @ 2016-11-24 1:26 UTC (permalink / raw)
To: yesipov; +Cc: netdev, linux-kernel
In-Reply-To: <1479747211-22394-1-git-send-email-yesipov@gmail.com>
From: Kirill Esipov <yesipov@gmail.com>
Date: Mon, 21 Nov 2016 19:53:31 +0300
> Fix setting of SUPPORTED_FIBRE bit as it was not present in features
> of KSZ8041.
>
> Signed-off-by: Kirill Esipov <yesipov@gmail.com>
Applied.
^ permalink raw reply
* Mrs. Grace Ibrahim
From: mrsgraceibrahim @ 2016-11-24 0:31 UTC (permalink / raw)
I am Mrs Mrs Grace Ibrahim, i have a pending project of fulfillment to
put in your hand, i will need your support to make this dream come
through, could you let me know your interest to enable me give you
further information, and I hereby advice that you send the below
mentioned information
I decided to while/donate the sum of £ 4.7 million Euros to you for
the good work of God, and also to help the motherless and less
privilege and also for assistance of the widows. At the moment I
cannot take any telephone calls right now due to the fact that my
relatives (that have squandered the funds agave them for this purpose
before) are around me and my health status also. I have adjusted my
while and my lawyer is aware.
I have willed those properties to you by quoting my personal file
routing and account information. And I have also notified the bank
that I am willing that properties to you for a good, effective and
prudent work. I know I don't know you but I have been directed to do
this by God.ok Please contact this woman for more details you might
not get me on line in time contact this email if you need more ok.
Email: mrsgraceibrahim1978@gmail.com
Your full name.........................
Your private telephone number..........
Your passport or identity card.........
Your country....................... ...
Your occupation........................
Thank you as i wait your reply.
Yours faithful friend,
Mrs. Grace Ibrahim
^ permalink raw reply
* Re: [RFC 02/10] IB/hfi-vnic: Virtual Network Interface Controller (VNIC) Bus driver
From: Vishwanathapura, Niranjana @ 2016-11-24 0:08 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: ira.weiny, Doug Ledford, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, Dennis Dalessandro
In-Reply-To: <20161123004932.GA13598-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
On Tue, Nov 22, 2016 at 05:49:32PM -0700, Jason Gunthorpe wrote:
>> > > We could add a custom Interface between HFI1 driver and hfi_vnic drivers
>> > > without involving a bus.
>> >
>> > hfi is already registering on the infiniband class, just use that.
>>
>> I don't understand what you mean here?
>
>Get the struct ib_device for the hfi and then do something to get hfi
>specific function calls.
>
>Or work it backwards with a _register function..
>
OK, thanks for your feedback.
We can make the hfi_vnic module as an ib client (which it is) like other ULPs,
and do not have an in-built or custom bus for binding.
Then the hfi_vnic ULP by some mechanism will identify the device as hfi1 device
and will only serve that device.
In order to pass the hfi function pointers to the hfi_vnic ULP, I can,
a) Have hfi_vnic ULP define an interface API for hfi1 driver to call to
register its callback (as you pointed). Unfortunately there will be a module
dependency here.
Or,
b) Add a new member ‘struct vnic_ops’ either to the ib_device structure or
ib_port_immutable structure. As it is hfi1 specific, only hfi1 driver will set
it. No module dependency here.
And will move the hfi_vnic module under ‘drivers/infiniband/ulp/hfi_vnic’.
All these will remove undue complexity and fit the driver in current design
framework as per your suggestion.
Let me know your comments.
Niranjana
>
>Jason
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* random thoughts on optmizing network namespace exit.
From: Eric W. Biederman @ 2016-11-23 23:52 UTC (permalink / raw)
To: Andrei Vagin; +Cc: netdev
Fundamentally if we want things to get better we have to remove
unnecessary serialization. It is entirely too easy to sleep when
cleaning up a networking subsystem and create long hold times on
net_mutex for no particular reasons.
What probably makes sense to do is to add the concept of a
non-serialized pernet_operation. And then work through the networking
stack converting all of the pernet_operations. That should allow
network namespace exits to overlap while they clean up, and it should
allow the net_mutex to be dropped at the same point we drop rtnl_lock
in cleanup_net.
It might be a touch tricky during the transition period to take
advantage of an early drop of net_mutex, but that is where I would
start.
Once net_mutex is no longer used to serialize initialization/cleanup
methods for a network namespace. We can look at other bottlenecks.
Eric
^ permalink raw reply
* Re: net/arp: ARP cache aging failed.
From: Eric Dumazet @ 2016-11-23 23:49 UTC (permalink / raw)
To: Hannes Frederic Sowa; +Cc: Julian Anastasov, yuehaibing, davem, netdev
In-Reply-To: <250d3a88-45ad-891f-389a-997f39d7bdad@stressinduktion.org>
On Wed, 2016-11-23 at 15:37 +0100, Hannes Frederic Sowa wrote:
> Irregardless about the question if bonding should keep the MAC address
> alive, a MAC address can certainly change below a TCP connection.
Of course ;)
>
> dst_entry is 1:n to neigh_entry and as such we can end up confirming an
> aging neighbor while sending a reply with dst->pending_confirm set while
> the confirming packet actually came from a different neighbor.
>
> I agree with Julian, pending_confirm became useless in this way.
Let's kill it then ;)
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH] igb: use igb_adapter->io_addr instead of e1000_hw->hw_addr
From: Brown, Aaron F @ 2016-11-23 23:48 UTC (permalink / raw)
To: Cao jin, linux-kernel@vger.kernel.org, netdev@vger.kernel.org
Cc: izumi.taku@jp.fujitsu.com, intel-wired-lan@lists.osuosl.org
In-Reply-To: <1478588780-24480-1-git-send-email-caoj.fnst@cn.fujitsu.com>
> From: Intel-wired-lan [intel-wired-lan-bounces@lists.osuosl.org] on behalf of Cao jin [caoj.fnst@cn.fujitsu.com]
> Sent: Monday, November 07, 2016 11:06 PM
To> : linux-kernel@vger.kernel.org; netdev@vger.kernel.org
> Cc: izumi.taku@jp.fujitsu.com; intel-wired-lan@lists.osuosl.org
> Subject: [Intel-wired-lan] [PATCH] igb: use igb_adapter->io_addr instead of e1000_hw->hw_addr
>
> When running as guest, under certain condition, it will oops as following.
> writel() in igb_configure_tx_ring() results in oops, because hw->hw_addr
> is NULL. While other register access won't oops kernel because they use
> wr32/rd32 which have a defense against NULL pointer.
>
> [ 141.225449] pcieport 0000:00:1c.0: AER: Multiple Uncorrected (Fatal)
> error received: id=0101
> [ 141.225523] igb 0000:01:00.1: PCIe Bus Error:
> severity=Uncorrected (Fatal), type=Unaccessible,
> id=0101(Unregistered Agent ID)
> [ 141.299442] igb 0000:01:00.1: broadcast error_detected message
> [ 141.300539] igb 0000:01:00.0 enp1s0f0: PCIe link lost, device now
> detached
> [ 141.351019] igb 0000:01:00.1 enp1s0f1: PCIe link lost, device now
> detached
> [ 143.465904] pcieport 0000:00:1c.0: Root Port link has been reset
> [ 143.465994] igb 0000:01:00.1: broadcast slot_reset message
> [ 143.466039] igb 0000:01:00.0: enabling device (0000 -> 0002)
> [ 144.389078] igb 0000:01:00.1: enabling device (0000 -> 0002)
> [ 145.312078] igb 0000:01:00.1: broadcast resume message
> [ 145.322211] BUG: unable to handle kernel paging request at
> 0000000000003818
> [ 145.361275] IP: [<ffffffffa02fd38d>]
> igb_configure_tx_ring+0x14d/0x280 [igb]
> [ 145.400048] PGD 0
> [ 145.438007] Oops: 0002 [#1] SMP
>
> A similiar issue & solution could be found at:
> http://patchwork.ozlabs.org/patch/689592/
>
> Signed-off-by: Cao jin <caoj.fnst@cn.fujitsu.com>
> ---
> drivers/net/ethernet/intel/igb/igb_main.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
^ permalink raw reply
* [[PATCH net-next RFC] 1/4] net: dsa: mv88e6xxx: Implement mv88e6390 tag remap
From: Andrew Lunn @ 2016-11-23 23:43 UTC (permalink / raw)
To: Vivien Didelot; +Cc: netdev, Andrew Lunn
In-Reply-To: <1479944598-20372-1-git-send-email-andrew@lunn.ch>
The mv88e6390 does not have the two registers to set the frame
priority map. Instead it has an indirection registers for setting a
number of different priority maps. Refactor the old code into an
function, implement the mv88e6390 version, and use an op to call the
right one.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx/chip.c | 37 +++++++++++++++--------
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 10 ++++++
drivers/net/dsa/mv88e6xxx/port.c | 57 +++++++++++++++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/port.h | 2 ++
4 files changed, 93 insertions(+), 13 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index bada6465af59..880e40288038 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2617,20 +2617,10 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
if (err)
return err;
}
+ }
- /* Tag Remap: use an identity 802.1p prio -> switch
- * prio mapping.
- */
- err = mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_0123,
- 0x3210);
- if (err)
- return err;
-
- /* Tag Remap 2: use an identity 802.1p prio -> switch
- * prio mapping.
- */
- err = mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_4567,
- 0x7654);
+ if (chip->info->ops->tag_remap) {
+ err = chip->info->ops->tag_remap(chip, port);
if (err)
return err;
}
@@ -3193,6 +3183,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6095_ops = {
@@ -3221,6 +3212,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6131_ops = {
@@ -3249,6 +3241,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6165_ops = {
@@ -3263,6 +3256,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6171_ops = {
@@ -3278,6 +3272,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6172_ops = {
@@ -3295,6 +3290,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6175_ops = {
@@ -3310,6 +3306,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6176_ops = {
@@ -3327,6 +3324,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6185_ops = {
@@ -3357,6 +3355,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .tag_remap = mv88e6390_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6190x_ops = {
@@ -3373,6 +3372,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .tag_remap = mv88e6390_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6191_ops = {
@@ -3389,6 +3389,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .tag_remap = mv88e6390_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6240_ops = {
@@ -3406,6 +3407,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6290_ops = {
@@ -3422,6 +3424,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .tag_remap = mv88e6390_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6320_ops = {
@@ -3438,6 +3441,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6320_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6321_ops = {
@@ -3454,6 +3458,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6320_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6350_ops = {
@@ -3469,6 +3474,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6351_ops = {
@@ -3484,6 +3490,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6352_ops = {
@@ -3501,6 +3508,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .tag_remap = mv88e6095_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6390_ops = {
@@ -3517,6 +3525,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .tag_remap = mv88e6390_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6390x_ops = {
@@ -3533,6 +3542,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .tag_remap = mv88e6390_tag_remap,
};
static const struct mv88e6xxx_ops mv88e6391_ops = {
@@ -3549,6 +3559,7 @@ static const struct mv88e6xxx_ops mv88e6391_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .tag_remap = mv88e6390_tag_remap,
};
static const struct mv88e6xxx_info mv88e6xxx_table[] = {
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
index 9298faa5878b..241025e0aec7 100644
--- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
@@ -171,6 +171,15 @@
#define PORT_OUT_FILTERED 0x13
#define PORT_TAG_REGMAP_0123 0x18
#define PORT_TAG_REGMAP_4567 0x19
+#define PORT_PRIO_MAP_TABLE 0x18 /* 6390 */
+#define PORT_PRIO_MAP_TABLE_UPDATE BIT(15)
+#define PORT_PRIO_MAP_TABLE_INGRESS_PCP (0x0 << 12)
+#define PORT_PRIO_MAP_TABLE_EGRESS_GREEN_PCP (0x1 << 12)
+#define PORT_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP (0x2 << 12)
+#define PORT_PRIO_MAP_TABLE_EGRESS_AVB_PCP (0x3 << 12)
+#define PORT_PRIO_MAP_TABLE_EGRESS_GREEN_DSCP (0x5 << 12)
+#define PORT_PRIO_MAP_TABLE_EGRESS_YELLOW_DSCP (0x6 << 12)
+#define PORT_PRIO_MAP_TABLE_EGRESS_AVB_DSCP (0x7 << 12)
#define GLOBAL_STATUS 0x00
#define GLOBAL_STATUS_PPU_STATE BIT(15) /* 6351 and 6171 */
@@ -813,6 +822,7 @@ struct mv88e6xxx_ops {
void (*stats_get_strings)(struct mv88e6xxx_chip *chip, uint8_t *data);
void (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port,
uint64_t *data);
+ int (*tag_remap)(struct mv88e6xxx_chip *chip, int port);
};
#define STATS_TYPE_PORT BIT(0)
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index af4772d86086..b7fab70f6cd7 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -496,3 +496,60 @@ int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
return 0;
}
+
+int mv88e6095_tag_remap(struct mv88e6xxx_chip *chip, int port)
+{
+ int err;
+
+ /* Tag Remap: use an identity 802.1p prio -> switch prio
+ * mapping.
+ */
+ err = mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_0123, 0x3210);
+ if (err)
+ return err;
+
+ /* Tag Remap 2: use an identity 802.1p prio -> switch
+ * prio mapping.
+ */
+ return mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_4567, 0x7654);
+}
+
+int mv88e6390_tag_remap(struct mv88e6xxx_chip *chip, int port)
+{
+ int err, reg, i;
+
+ for (i = 0; i <= 7; i++) {
+ reg = i | (i << 4) |
+ PORT_PRIO_MAP_TABLE_INGRESS_PCP |
+ PORT_PRIO_MAP_TABLE_UPDATE;
+ err = mv88e6xxx_port_write(chip, port, PORT_PRIO_MAP_TABLE,
+ reg);
+ if (err)
+ return err;
+
+ reg = i | PORT_PRIO_MAP_TABLE_EGRESS_GREEN_PCP |
+ PORT_PRIO_MAP_TABLE_UPDATE;
+ err = mv88e6xxx_port_write(chip, port, PORT_PRIO_MAP_TABLE,
+ reg);
+ if (err)
+ return err;
+
+ reg = i |
+ PORT_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP |
+ PORT_PRIO_MAP_TABLE_UPDATE;
+ err = mv88e6xxx_port_write(chip, port, PORT_PRIO_MAP_TABLE,
+ reg);
+ if (err)
+ return err;
+
+ reg = i |
+ PORT_PRIO_MAP_TABLE_EGRESS_AVB_PCP |
+ PORT_PRIO_MAP_TABLE_UPDATE;
+ err = mv88e6xxx_port_write(chip, port, PORT_PRIO_MAP_TABLE,
+ reg);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index 499129c1489c..99a04cf3d1d6 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -48,5 +48,7 @@ int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid);
int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
u16 mode);
+int mv88e6095_tag_remap(struct mv88e6xxx_chip *chip, int port);
+int mv88e6390_tag_remap(struct mv88e6xxx_chip *chip, int port);
#endif /* _MV88E6XXX_PORT_H */
--
2.10.2
^ permalink raw reply related
* [[PATCH net-next RFC] 2/4] net: dsa: mv88e6xxx: Monitor and Management tables
From: Andrew Lunn @ 2016-11-23 23:43 UTC (permalink / raw)
To: Vivien Didelot; +Cc: netdev, Andrew Lunn
In-Reply-To: <1479944598-20372-1-git-send-email-andrew@lunn.ch>
The mv88e6390 changes the monitor control register into the Monitor
and Management control, which is an indirection register to various
registers. Move the existing code into global1.c, and add new code for
the mv88e6390.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx/chip.c | 37 +++++++++++++++++------
drivers/net/dsa/mv88e6xxx/global1.c | 55 +++++++++++++++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/global1.h | 3 ++
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 7 +++++
4 files changed, 93 insertions(+), 9 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 880e40288038..a6fa3f81e11b 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2747,15 +2747,11 @@ static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip)
if (err)
return err;
- /* Configure the upstream port, and configure it as the port to which
- * ingress and egress and ARP monitor frames are to be sent.
- */
- reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
- upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
- upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT;
- err = mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
- if (err)
- return err;
+ if (chip->info->ops->monitor_ctrl) {
+ err = chip->info->ops->monitor_ctrl(chip, upstream_port);
+ if (err)
+ return err;
+ }
/* Disable remote management, and set the switch's DSA device number. */
err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL_2,
@@ -3184,6 +3180,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6095_ops = {
@@ -3198,6 +3195,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6123_ops = {
@@ -3213,6 +3211,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6131_ops = {
@@ -3227,6 +3226,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6161_ops = {
@@ -3242,6 +3242,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6165_ops = {
@@ -3257,6 +3258,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6171_ops = {
@@ -3273,6 +3275,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6172_ops = {
@@ -3291,6 +3294,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6175_ops = {
@@ -3307,6 +3311,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6176_ops = {
@@ -3325,6 +3330,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6185_ops = {
@@ -3339,6 +3345,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6190_ops = {
@@ -3356,6 +3363,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
.tag_remap = mv88e6390_tag_remap,
+ .monitor_ctrl = mv88e6390_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6190x_ops = {
@@ -3373,6 +3381,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
.tag_remap = mv88e6390_tag_remap,
+ .monitor_ctrl = mv88e6390_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6191_ops = {
@@ -3390,6 +3399,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
.tag_remap = mv88e6390_tag_remap,
+ .monitor_ctrl = mv88e6390_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6240_ops = {
@@ -3408,6 +3418,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6290_ops = {
@@ -3425,6 +3436,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
.tag_remap = mv88e6390_tag_remap,
+ .monitor_ctrl = mv88e6390_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6320_ops = {
@@ -3442,6 +3454,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6320_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6321_ops = {
@@ -3459,6 +3472,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6320_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6350_ops = {
@@ -3475,6 +3489,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6351_ops = {
@@ -3491,6 +3506,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6352_ops = {
@@ -3509,6 +3525,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
.tag_remap = mv88e6095_tag_remap,
+ .monitor_ctrl = mv88e6095_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6390_ops = {
@@ -3526,6 +3543,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
.tag_remap = mv88e6390_tag_remap,
+ .monitor_ctrl = mv88e6390_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6390x_ops = {
@@ -3543,6 +3561,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
.tag_remap = mv88e6390_tag_remap,
+ .monitor_ctrl = mv88e6390_monitor_ctrl,
};
static const struct mv88e6xxx_ops mv88e6391_ops = {
diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c
index 5fcf23dbf04b..ea4421e1d15c 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.c
+++ b/drivers/net/dsa/mv88e6xxx/global1.c
@@ -33,6 +33,60 @@ int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
return mv88e6xxx_wait(chip, chip->info->global1_addr, reg, mask);
}
+/* Offset 0x1a: Monitor Control */
+
+int mv88e6095_monitor_ctrl(struct mv88e6xxx_chip *chip, int upstream_port)
+{
+ u16 reg;
+
+ reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
+ upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
+ upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT;
+
+ return mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
+}
+
+int mv88e6390_monitor_ctrl(struct mv88e6xxx_chip *chip, int upstream_port)
+{
+ u16 reg;
+ int err;
+
+ /* Trap destination */
+ reg = GLOBAL_MONITOR_CONTROL_UPDATE |
+ GLOBAL_MONITOR_CONTROL_CPU_DEST |
+ upstream_port;
+ err = mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
+ if (err)
+ return err;
+
+ /* 01:c2:80:00:00:00:00-01:c2:80:00:00:00:07 are Management */
+ reg = GLOBAL_MONITOR_CONTROL_UPDATE |
+ GLOBAL_MONITOR_CONTROL_0180C280000000XLO | 0xff;
+ err = mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
+ if (err)
+ return err;
+
+ /* 01:c2:80:00:00:00:08-01:c2:80:00:00:00:0f are Management */
+ reg = GLOBAL_MONITOR_CONTROL_UPDATE |
+ GLOBAL_MONITOR_CONTROL_0180C280000000XHI | 0xff;
+ err = mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
+ if (err)
+ return err;
+
+ /* 01:c2:80:00:00:00:20-01:c2:80:00:00:00:27 are Management */
+ reg = GLOBAL_MONITOR_CONTROL_UPDATE |
+ GLOBAL_MONITOR_CONTROL_0180C280000002XLO | 0xff;
+ err = mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
+ if (err)
+ return err;
+
+ /* 01:c2:80:00:00:00:28-01:c2:80:00:00:00:2f are Management */
+ reg = GLOBAL_MONITOR_CONTROL_UPDATE |
+ GLOBAL_MONITOR_CONTROL_0180C280000002XHI | 0xff;
+
+ return mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
+}
+
/* Offset 0x1c: Global Control 2 */
int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip)
@@ -125,3 +179,4 @@ void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip *chip, int stat, u32 *val)
*val = value | reg;
}
+
diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
index df3794cdbfb9..4d8e5ddd8d8c 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.h
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
@@ -25,5 +25,8 @@ int mv88e6320_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port);
int mv88e6390_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port);
int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip);
void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip *chip, int stat, u32 *val);
+int mv88e6095_monitor_ctrl(struct mv88e6xxx_chip *chip, int upstream_port);
+int mv88e6390_monitor_ctrl(struct mv88e6xxx_chip *chip, int upstream_port);
+
#endif /* _MV88E6XXX_GLOBAL1_H */
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
index 241025e0aec7..6698ec1d22b5 100644
--- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
@@ -289,6 +289,12 @@
#define GLOBAL_MONITOR_CONTROL_ARP_SHIFT 4
#define GLOBAL_MONITOR_CONTROL_MIRROR_SHIFT 0
#define GLOBAL_MONITOR_CONTROL_ARP_DISABLED (0xf0)
+#define GLOBAL_MONITOR_CONTROL_UPDATE BIT(15)
+#define GLOBAL_MONITOR_CONTROL_0180C280000000XLO (0x00 << 8)
+#define GLOBAL_MONITOR_CONTROL_0180C280000000XHI (0x01 << 8)
+#define GLOBAL_MONITOR_CONTROL_0180C280000002XLO (0x02 << 8)
+#define GLOBAL_MONITOR_CONTROL_0180C280000002XHI (0x03 << 8)
+#define GLOBAL_MONITOR_CONTROL_CPU_DEST (0x30 << 8)
#define GLOBAL_CONTROL_2 0x1c
#define GLOBAL_CONTROL_2_NO_CASCADE 0xe000
#define GLOBAL_CONTROL_2_MULTIPLE_CASCADE 0xf000
@@ -823,6 +829,7 @@ struct mv88e6xxx_ops {
void (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port,
uint64_t *data);
int (*tag_remap)(struct mv88e6xxx_chip *chip, int port);
+ int (*monitor_ctrl)(struct mv88e6xxx_chip *chip, int upstream_port);
};
#define STATS_TYPE_PORT BIT(0)
--
2.10.2
^ permalink raw reply related
* [[PATCH net-next RFC] 0/4] MV88E6390 batch two
From: Andrew Lunn @ 2016-11-23 23:43 UTC (permalink / raw)
To: Vivien Didelot; +Cc: netdev, Andrew Lunn
RFC only. Not for committing. They will conflict with the mv88e6097
support.
This is the second batch of patches adding support for the
MV88e6390. They are not sufficient to make it work properly.
The mv88e6390 has a much expanded set of priority maps. Refactor the
existing code, and implement basic support for the new device.
Similarly, the monitor control register has been reworked.
The mv88e6390 has something odd in its EDSA tagging implementation,
which means it is not possible to use it. So we need to use DSA
tagging. This is the first device with EDSA support where we need to
use DSA, and the code does not support this. So two patches refactor
the existing code. The two different register definitions are
separated out, and using DSA on an EDSA capable device is added.
Andrew Lunn (4):
net: dsa: mv88e6xxx: Implement mv88e6390 tag remap
net: dsa: mv88e6xxx: Monitor and Management tables
net: dsa: mv88e6xxx: Move the tagging protocol into info
net: dsa: mv88e6xxx: Refactor CPU and DSA port setup
drivers/net/dsa/mv88e6xxx/chip.c | 195 +++++++++++++++++++++-------------
drivers/net/dsa/mv88e6xxx/global1.c | 55 ++++++++++
drivers/net/dsa/mv88e6xxx/global1.h | 3 +
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 40 ++++---
drivers/net/dsa/mv88e6xxx/port.c | 132 +++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/port.h | 7 ++
6 files changed, 348 insertions(+), 84 deletions(-)
--
2.10.2
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox