* [net-next PATCH 1/5 v2] net: dsa: tag_rtl4_a: Implement Realtek 4 byte A tag
From: Linus Walleij @ 2020-06-17 8:31 UTC (permalink / raw)
To: Andrew Lunn, Vivien Didelot, Florian Fainelli
Cc: netdev, Linus Walleij, DENG Qingfang, Mauri Sandberg
This implements the known parts of the Realtek 4 byte
tag protocol version 0xA, as found in the RTL8366RB
DSA switch.
It is designated as protocol version 0xA as a
different Realtek 4 byte tag format with protocol
version 0x9 is known to exist in the Realtek RTL8306
chips.
The tag and switch chip lacks public documentation, so
the tag format has been reverse-engineered from
packet dumps. As only ingress traffic has been available
for analysis an egress tag has not been possible to
develop (even using educated guesses about bit fields)
so this is as far as it gets. It is not known if the
switch even supports egress tagging.
Excessive attempts to figure out the egress tag format
was made. When nothing else worked, I just tried all bit
combinations with 0xannp where a is protocol and p is
port. I looped through all values several times trying
to get a response from ping, without any positive
result.
Using just these ingress tags however, the switch
functionality is vastly improved and the packets find
their way into the destination port without any
tricky VLAN configuration. On the D-Link DIR-685 the
LAN ports now come up and respond to ping without
any command line configuration so this is a real
improvement for users.
Egress packets need to be restricted to the proper
target ports using VLAN, which the RTL8366RB DSA
switch driver already sets up.
Cc: DENG Qingfang <dqfext@gmail.com>
Cc: Mauri Sandberg <sandberg@mailfence.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Drop some netdev_dbg() calls that was just littering.
- Rebase on v5.8-rc1
---
include/net/dsa.h | 2 +
net/dsa/Kconfig | 7 +++
net/dsa/Makefile | 1 +
net/dsa/tag_rtl4_a.c | 131 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 141 insertions(+)
create mode 100644 net/dsa/tag_rtl4_a.c
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 50389772c597..2b37943f09a4 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -44,6 +44,7 @@ struct phylink_link_state;
#define DSA_TAG_PROTO_KSZ8795_VALUE 14
#define DSA_TAG_PROTO_OCELOT_VALUE 15
#define DSA_TAG_PROTO_AR9331_VALUE 16
+#define DSA_TAG_PROTO_RTL4_A_VALUE 17
enum dsa_tag_protocol {
DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
@@ -63,6 +64,7 @@ enum dsa_tag_protocol {
DSA_TAG_PROTO_KSZ8795 = DSA_TAG_PROTO_KSZ8795_VALUE,
DSA_TAG_PROTO_OCELOT = DSA_TAG_PROTO_OCELOT_VALUE,
DSA_TAG_PROTO_AR9331 = DSA_TAG_PROTO_AR9331_VALUE,
+ DSA_TAG_PROTO_RTL4_A = DSA_TAG_PROTO_RTL4_A_VALUE,
};
struct packet_type;
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index d5bc6ac599ef..1f9b9b11008c 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -86,6 +86,13 @@ config NET_DSA_TAG_KSZ
Say Y if you want to enable support for tagging frames for the
Microchip 8795/9477/9893 families of switches.
+config NET_DSA_TAG_RTL4_A
+ tristate "Tag driver for Realtek 4 byte protocol A tags"
+ help
+ Say Y or M if you want to enable support for tagging frames for the
+ Realtek switches with 4 byte protocol A tags, sich as found in
+ the Realtek RTL8366RB.
+
config NET_DSA_TAG_OCELOT
tristate "Tag driver for Ocelot family of switches"
select PACKING
diff --git a/net/dsa/Makefile b/net/dsa/Makefile
index 108486cfdeef..4f47b2025ff5 100644
--- a/net/dsa/Makefile
+++ b/net/dsa/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_NET_DSA_TAG_DSA) += tag_dsa.o
obj-$(CONFIG_NET_DSA_TAG_EDSA) += tag_edsa.o
obj-$(CONFIG_NET_DSA_TAG_GSWIP) += tag_gswip.o
obj-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz.o
+obj-$(CONFIG_NET_DSA_TAG_RTL4_A) += tag_rtl4_a.o
obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o
obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o
obj-$(CONFIG_NET_DSA_TAG_OCELOT) += tag_ocelot.o
diff --git a/net/dsa/tag_rtl4_a.c b/net/dsa/tag_rtl4_a.c
new file mode 100644
index 000000000000..df82249aa1a7
--- /dev/null
+++ b/net/dsa/tag_rtl4_a.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Handler for Realtek 4 byte DSA switch tags
+ * Currently only supports protocol "A" found in RTL8366RB
+ * Copyright (c) 2020 Linus Walleij <linus.walleij@linaro.org>
+ *
+ * This "proprietary tag" header looks like so:
+ *
+ * -------------------------------------------------
+ * | MAC DA | MAC SA | 0x8899 | 2 bytes tag | Type |
+ * -------------------------------------------------
+ *
+ * The 2 bytes tag form a 16 bit big endian word. The exact
+ * meaning has been guess from packet dumps from ingress
+ * frames, as no working egress traffic has been available
+ * we do not know the format of the egress tags or if they
+ * are even supported.
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/bits.h>
+
+#include "dsa_priv.h"
+
+#define RTL4_A_HDR_LEN 4
+#define RTL4_A_ETHERTYPE 0x8899
+#define RTL4_A_PROTOCOL_SHIFT 12
+/*
+ * 0x1 = Realtek Remote Control protocol (RRCP)
+ * 0x2/0x3 seems to be used for loopback testing
+ * 0x9 = RTL8306 DSA protocol
+ * 0xa = RTL8366RB DSA protocol
+ */
+#define RTL4_A_PROTOCOL_RTL8366RB 0xa
+
+static struct sk_buff *rtl4a_tag_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ /*
+ * Just let it pass thru, we don't know if it is possible
+ * to tag a frame with the 0x8899 ethertype and direct it
+ * to a specific port, all attempts at reverse-engineering have
+ * ended up with the frames getting dropped.
+ *
+ * The VLAN set-up needs to restrict the frames to the right port.
+ *
+ * If you have documentation on the tagging format for RTL8366RB
+ * (tag type A) then please contribute.
+ */
+ return skb;
+}
+
+static struct sk_buff *rtl4a_tag_rcv(struct sk_buff *skb,
+ struct net_device *dev,
+ struct packet_type *pt)
+{
+ u16 protport;
+ __be16 *p;
+ u16 etype;
+ u8 flags;
+ u8 *tag;
+ u8 prot;
+ u8 port;
+
+ if (unlikely(!pskb_may_pull(skb, RTL4_A_HDR_LEN)))
+ return NULL;
+
+ /* The RTL4 header has its own custom Ethertype 0x8899 and that
+ * starts right at the beginning of the packet, after the src
+ * ethernet addr. Apparantly skb->data always points 2 bytes in,
+ * behind the Ethertype.
+ */
+ tag = skb->data - 2;
+ p = (__be16 *)tag;
+ etype = ntohs(*p);
+ if (etype != RTL4_A_ETHERTYPE) {
+ /* Not custom, just pass through */
+ netdev_dbg(dev, "non-realtek ethertype 0x%04x\n", etype);
+ return skb;
+ }
+ p = (__be16 *)(tag + 2);
+ protport = ntohs(*p);
+ /* The 4 upper bits are the protocol */
+ prot = (protport >> RTL4_A_PROTOCOL_SHIFT) & 0x0f;
+ if (prot != RTL4_A_PROTOCOL_RTL8366RB) {
+ netdev_err(dev, "unknown realtek protocol 0x%01x\n", prot);
+ return NULL;
+ }
+ port = protport & 0xff;
+
+ /* Remove RTL4 tag and recalculate checksum */
+ skb_pull_rcsum(skb, RTL4_A_HDR_LEN);
+
+ /* Move ethernet DA and SA in front of the data */
+ memmove(skb->data - ETH_HLEN,
+ skb->data - ETH_HLEN - RTL4_A_HDR_LEN,
+ 2 * ETH_ALEN);
+
+ skb->dev = dsa_master_find_slave(dev, 0, port);
+ if (!skb->dev) {
+ netdev_dbg(dev, "could not find slave for port %d\n", port);
+ return NULL;
+ }
+
+ skb->offload_fwd_mark = 1;
+
+ return skb;
+}
+
+static int rtl4a_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto,
+ int *offset)
+{
+ *offset = RTL4_A_HDR_LEN;
+ /* Skip past the tag and fetch the encapsulated Ethertype */
+ *proto = ((__be16 *)skb->data)[1];
+
+ return 0;
+}
+
+static const struct dsa_device_ops rtl4a_netdev_ops = {
+ .name = "rtl4a",
+ .proto = DSA_TAG_PROTO_RTL4_A,
+ .xmit = rtl4a_tag_xmit,
+ .rcv = rtl4a_tag_rcv,
+ .flow_dissect = rtl4a_tag_flow_dissect,
+ .overhead = RTL4_A_HDR_LEN,
+};
+module_dsa_tag_driver(rtl4a_netdev_ops);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_RTL4_A);
--
2.26.2
^ permalink raw reply related
* net/dsa/microchip: correct placement of dt property phy-mode?
From: Helmut Grohne @ 2020-06-17 8:22 UTC (permalink / raw)
To: Woojung Huh, Microchip Linux Driver Support, Andrew Lunn,
Vivien Didelot, Florian Fainelli, netdev
Hi,
According to Documentation/devicetree/bindings/net/dsa/dsa.txt, the
phy-mode property should be specified on port nodes rather than the
enclosing switch node.
In drivers/net/dsa/microchip/ksz_common.c, ksz_switch_register parses
the phy-mode property from the switch node instead:
| int ksz_switch_register(struct ksz_device *dev,
| const struct ksz_dev_ops *ops)
| {
...
| /* Host port interface will be self detected, or specifically set in
| * device tree.
| */
| if (dev->dev->of_node) {
| ret = of_get_phy_mode(dev->dev->of_node, &interface);
| if (ret == 0)
| dev->interface = interface;
...
In drivers/net/dsa/microchip/ksz9477.c, this phy_interface_t is used to
configure the MAC ports:
| static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
| {
...
| switch (dev->interface) {
...
| }
| ksz_pwrite8(dev, port, REG_PORT_XMII_CTRL_1, data8);
KSZ9477 has two MAC interfaces (GMAC 6 -> RGMII/MII/RMII and GMAC 7 ->
SGMII). Now we're trying to configure the same interface mode for both
MACs here even though these MACs only support distinct interface modes.
This may not be problematic in practice as GMAC 7 ignores most of the
settings on the XMII Port Control 1 Register, but it still sounds wrong.
If nothing else, it makes the device tree unintuitive to use.
Is this placement of the phy-mode on the switch intentional?
If yes: I think this should be prominently documented in
Documentation/devicetree/bindings/net/dsa/ksz.txt.
If no: The microchip driver should follow the documented dsa convention
and place the phy-mode on the relevant port nodes.
If no: Do we have to support old device trees that have the phy-mode
property on the switch?
Helmut
^ permalink raw reply
* Re: [net-next PATCH 1/5] net: dsa: tag_rtl4_a: Implement Realtek 4 byte A tag
From: Linus Walleij @ 2020-06-17 8:06 UTC (permalink / raw)
To: Vladimir Oltean
Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, netdev,
DENG Qingfang, Mauri Sandberg
In-Reply-To: <CA+h21hqNq6Xk5bMBsB884GZdH9h4pALr7nkn8yG+a16cXqfJsg@mail.gmail.com>
On Thu, Jun 4, 2020 at 1:23 PM Vladimir Oltean <olteanv@gmail.com> wrote:
> In the code you pointed to, there is a potentially relevant comment:
>
> 1532//CPU tag: Realtek Ethertype==0x8899(2 bytes)+protocol==0x9(4
> MSB)+priority(2 bits)+reserved(4 bits)+portmask(6 LSB)
>
> https://svn.dd-wrt.com/browser/src/linux/universal/linux-3.2/drivers/net/ethernet/raeth/rb/rtl_multicast_snooping.c#L1527
> https://svn.dd-wrt.com/browser/src/linux/universal/linux-3.2/drivers/net/ethernet/raeth/rb/rtl_multicast_snooping.c#L5224
>
> This strongly indicates to me that the insertion tag is the same as
> the extraction tag.
This code is a problem because it is Realtek-development style.
This style seems to be that the hardware people write the drivers
using copy/paste from the previous ASIC and ship is as soon as
possible. Keep this in mind.
The above tag is using protocol 9 and is actually even documented
in a PDF I have for RTL8306. The problem is that the RTL8366RB
(I suspect also RTL8366S) uses protocol "a" (as in hex 10).
Which is of course necessarily different.
I have *really* tried to figure out how the bits in protocol a works
when transmissing from the CPU port to any switch port.
When nothing else worked, I just tried all bit combinations with
0xannp where a is protocol and p is port. I looped through all
values several times trying to get a response from ping.
So this is really how far I can get right now, even with brute
force.
> It is completely opaque to me why in patch "[net-next PATCH 2/5] net:
> dsa: rtl8366rb: Support the CPU DSA tag" you are _disabling_ the
> injection of these tags via RTL8368RB_CPU_INSTAG. I think it's natural
> that the switch drops these packets when CPU tag insertion is
> disabled.
This is another Realtek-ism where they managed to invert the
meaning of a bit.
Bit 15 in register 0x0061 (RTL8368RB_CPU_CTRL_REG) can
be set to 1 and then the special (custom) CPU tag 0x8899
protocol a will be DISABLED. This value Realtek calls
"RTL8368RB_CPU_INSTAG" which makes you think that
the tag will be inserted, it is named "instag" right? But that
is not how it works.
That bit needs to be set to 0 to insert the tag and 1 to disable
insertion of the tag.
For this reason the patch also renames this bit to
RTL8368RB_CPU_NO_TAG which is more to the point.
Yours,
Linus Walleij
^ permalink raw reply
* Re: linux-next: build failures after merge of the vfs tree
From: Stephen Rothwell @ 2020-06-17 8:06 UTC (permalink / raw)
To: Herbert Xu
Cc: Al Viro, Linux Next Mailing List, Linux Kernel Mailing List,
netdev
In-Reply-To: <20200617070316.GA30348@gondor.apana.org.au>
[-- Attachment #1: Type: text/plain, Size: 868 bytes --]
Hi Herbert,
On Wed, 17 Jun 2020 17:03:17 +1000 Herbert Xu <herbert@gondor.apana.org.au> wrote:
>
> On Wed, Jun 17, 2020 at 04:57:15PM +1000, Stephen Rothwell wrote:
> >
> > Presumably another include needed:
> >
> > arch/s390/lib/test_unwind.c:49:2: error: implicit declaration of function 'kmalloc' [-Werror=implicit-function-declaration]
> > arch/s390/lib/test_unwind.c:99:2: error: implicit declaration of function 'kfree' [-Werror=implicit-function-declaration]
>
> Hi Stephen:
>
> It's not clear how this file manages to include linux/uio.h but
arch/s390/lib/test_unwind.c
arch/s390/include/asm/unwind.h
include/linux/ftrace.h
include/linux/kallsyms.h
include/linux/module.h
include/linux/elf.h
arch/s390/include/asm/elf.h
include/linux/compat.h
include/linux/socket.h
include/linux/uio.h
:-(
--
Cheers,
Stephen Rothwell
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v4 0/3] mm, treewide: Rename kzfree() to kfree_sensitive()
From: Jo -l @ 2020-06-17 8:03 UTC (permalink / raw)
To: Matthew Wilcox
Cc: dsterba, Joe Perches, Waiman Long, Andrew Morton, David Howells,
Jarkko Sakkinen, James Morris, Serge E. Hallyn, Linus Torvalds,
David Rientjes, Michal Hocko, Johannes Weiner, Dan Carpenter,
Jason A. Donenfeld, linux-mm, keyrings, linux-kernel,
linux-crypto, linux-pm, linux-stm32, linux-amlogic,
linux-mediatek, linuxppc-dev, virtualization, netdev, linux-ppp,
wireguard, linux-wireless, devel, linux-scsi, target-devel,
linux-btrfs, linux-cifs, linux-fscrypt, ecryptfs, kasan-dev,
linux-bluetooth, linux-wpan, linux-sctp, linux-nfs,
tipc-discussion, linux-security-module, linux-integrity
In-Reply-To: <20200617003711.GD8681@bombadil.infradead.org>
Bonjour,
Désolé, aucune traduction possible,
En français pour comprendre!
Merci
slts
> Le 17 06 2020 à 02:37, Matthew Wilcox <willy@infradead.org> a écrit :
>
> On Wed, Jun 17, 2020 at 01:01:30AM +0200, David Sterba wrote:
>> On Tue, Jun 16, 2020 at 11:53:50AM -0700, Joe Perches wrote:
>>> On Mon, 2020-06-15 at 21:57 -0400, Waiman Long wrote:
>>>> v4:
>>>> - Break out the memzero_explicit() change as suggested by Dan Carpenter
>>>> so that it can be backported to stable.
>>>> - Drop the "crypto: Remove unnecessary memzero_explicit()" patch for
>>>> now as there can be a bit more discussion on what is best. It will be
>>>> introduced as a separate patch later on after this one is merged.
>>>
>>> To this larger audience and last week without reply:
>>> https://lore.kernel.org/lkml/573b3fbd5927c643920e1364230c296b23e7584d.camel@perches.com/
>>>
>>> Are there _any_ fastpath uses of kfree or vfree?
>>
>> I'd consider kfree performance critical for cases where it is called
>> under locks. If possible the kfree is moved outside of the critical
>> section, but we have rbtrees or lists that get deleted under locks and
>> restructuring the code to do eg. splice and free it outside of the lock
>> is not always possible.
>
> Not just performance critical, but correctness critical. Since kvfree()
> may allocate from the vmalloc allocator, I really think that kvfree()
> should assert that it's !in_atomic(). Otherwise we can get into trouble
> if we end up calling vfree() and have to take the mutex.
Jo-l
joel.voyer@gmail.com
^ permalink raw reply
* Re: linux-next: build failures after merge of the vfs tree
From: Herbert Xu @ 2020-06-17 7:38 UTC (permalink / raw)
To: Stephen Rothwell
Cc: Al Viro, Linux Next Mailing List, Linux Kernel Mailing List,
netdev
In-Reply-To: <20200617173102.2b91c32d@canb.auug.org.au>
On Wed, Jun 17, 2020 at 05:31:02PM +1000, Stephen Rothwell wrote:
> > >
> > > Presumably another include needed:
> > >
> > > arch/s390/lib/test_unwind.c:49:2: error: implicit declaration of function 'kmalloc' [-Werror=implicit-function-declaration]
> > > arch/s390/lib/test_unwind.c:99:2: error: implicit declaration of function 'kfree' [-Werror=implicit-function-declaration]
>
> And more (these are coming from other's builds):
>
> drivers/remoteproc/qcom_q6v5_mss.c:772:3: error: implicit declaration of function 'kfree' [-Werror,-Wimplicit-function-declaration]
> drivers/remoteproc/qcom_q6v5_mss.c:808:2: error: implicit declaration of function 'kfree' [-Werror,-Wimplicit-function-declaration]
> drivers/remoteproc/qcom_q6v5_mss.c:1195:2: error: implicit declaration of function 'kfree' [-Werror,-Wimplicit-function-declaration]
>
> They may have other causes as they are full linux-next builds (not just
> after the merge of the vfs tree), but the timing is suspicious.
OK, here's a patch for both of these together:
diff --git a/arch/s390/lib/test_unwind.c b/arch/s390/lib/test_unwind.c
index 32b7a30b2485..eb382ceaa116 100644
--- a/arch/s390/lib/test_unwind.c
+++ b/arch/s390/lib/test_unwind.c
@@ -9,6 +9,7 @@
#include <linux/kallsyms.h>
#include <linux/kthread.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/kprobes.h>
#include <linux/wait.h>
diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
index feb70283b6a2..903b2bb97e12 100644
--- a/drivers/remoteproc/qcom_q6v5_mss.c
+++ b/drivers/remoteproc/qcom_q6v5_mss.c
@@ -26,6 +26,7 @@
#include <linux/reset.h>
#include <linux/soc/qcom/mdt_loader.h>
#include <linux/iopoll.h>
+#include <linux/slab.h>
#include "remoteproc_internal.h"
#include "qcom_common.h"
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply related
* Re: linux-next: build failures after merge of the vfs tree
From: Stephen Rothwell @ 2020-06-17 7:31 UTC (permalink / raw)
To: Herbert Xu
Cc: Al Viro, Linux Next Mailing List, Linux Kernel Mailing List,
netdev
In-Reply-To: <20200617070316.GA30348@gondor.apana.org.au>
[-- Attachment #1: Type: text/plain, Size: 1117 bytes --]
Hi Herbert,
On Wed, 17 Jun 2020 17:03:17 +1000 Herbert Xu <herbert@gondor.apana.org.au> wrote:
>
> On Wed, Jun 17, 2020 at 04:57:15PM +1000, Stephen Rothwell wrote:
> >
> > Presumably another include needed:
> >
> > arch/s390/lib/test_unwind.c:49:2: error: implicit declaration of function 'kmalloc' [-Werror=implicit-function-declaration]
> > arch/s390/lib/test_unwind.c:99:2: error: implicit declaration of function 'kfree' [-Werror=implicit-function-declaration]
>
And more (these are coming from other's builds):
drivers/remoteproc/qcom_q6v5_mss.c:772:3: error: implicit declaration of function 'kfree' [-Werror,-Wimplicit-function-declaration]
drivers/remoteproc/qcom_q6v5_mss.c:808:2: error: implicit declaration of function 'kfree' [-Werror,-Wimplicit-function-declaration]
drivers/remoteproc/qcom_q6v5_mss.c:1195:2: error: implicit declaration of function 'kfree' [-Werror,-Wimplicit-function-declaration]
They may have other causes as they are full linux-next builds (not just
after the merge of the vfs tree), but the timing is suspicious.
--
Cheers,
Stephen Rothwell
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v4 0/3] mm, treewide: Rename kzfree() to kfree_sensitive()
From: Michal Hocko @ 2020-06-17 7:12 UTC (permalink / raw)
To: Matthew Wilcox
Cc: dsterba, Joe Perches, Waiman Long, Andrew Morton, David Howells,
Jarkko Sakkinen, James Morris, Serge E. Hallyn, Linus Torvalds,
David Rientjes, Johannes Weiner, Dan Carpenter,
Jason A . Donenfeld, linux-mm, keyrings, linux-kernel,
linux-crypto, linux-pm, linux-stm32, linux-amlogic,
linux-mediatek, linuxppc-dev, virtualization, netdev, linux-ppp,
wireguard, linux-wireless, devel, linux-scsi, target-devel,
linux-btrfs, linux-cifs, linux-fscrypt, ecryptfs, kasan-dev,
linux-bluetooth, linux-wpan, linux-sctp, linux-nfs,
tipc-discussion, linux-security-module, linux-integrity
In-Reply-To: <20200617003711.GD8681@bombadil.infradead.org>
On Tue 16-06-20 17:37:11, Matthew Wilcox wrote:
> On Wed, Jun 17, 2020 at 01:01:30AM +0200, David Sterba wrote:
> > On Tue, Jun 16, 2020 at 11:53:50AM -0700, Joe Perches wrote:
> > > On Mon, 2020-06-15 at 21:57 -0400, Waiman Long wrote:
> > > > v4:
> > > > - Break out the memzero_explicit() change as suggested by Dan Carpenter
> > > > so that it can be backported to stable.
> > > > - Drop the "crypto: Remove unnecessary memzero_explicit()" patch for
> > > > now as there can be a bit more discussion on what is best. It will be
> > > > introduced as a separate patch later on after this one is merged.
> > >
> > > To this larger audience and last week without reply:
> > > https://lore.kernel.org/lkml/573b3fbd5927c643920e1364230c296b23e7584d.camel@perches.com/
> > >
> > > Are there _any_ fastpath uses of kfree or vfree?
> >
> > I'd consider kfree performance critical for cases where it is called
> > under locks. If possible the kfree is moved outside of the critical
> > section, but we have rbtrees or lists that get deleted under locks and
> > restructuring the code to do eg. splice and free it outside of the lock
> > is not always possible.
>
> Not just performance critical, but correctness critical. Since kvfree()
> may allocate from the vmalloc allocator, I really think that kvfree()
> should assert that it's !in_atomic(). Otherwise we can get into trouble
> if we end up calling vfree() and have to take the mutex.
FWIW __vfree already checks for atomic context and put the work into a
deferred context. So this should be safe. It should be used as a last
resort, though.
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: linux-next: build failures after merge of the vfs tree
From: Herbert Xu @ 2020-06-17 7:03 UTC (permalink / raw)
To: Stephen Rothwell
Cc: Al Viro, Linux Next Mailing List, Linux Kernel Mailing List,
netdev
In-Reply-To: <20200617165715.577aa76d@canb.auug.org.au>
On Wed, Jun 17, 2020 at 04:57:15PM +1000, Stephen Rothwell wrote:
>
> Presumably another include needed:
>
> arch/s390/lib/test_unwind.c:49:2: error: implicit declaration of function 'kmalloc' [-Werror=implicit-function-declaration]
> arch/s390/lib/test_unwind.c:99:2: error: implicit declaration of function 'kfree' [-Werror=implicit-function-declaration]
Hi Stephen:
It's not clear how this file manages to include linux/uio.h but
here is a patch for it anyway:
diff --git a/arch/s390/lib/test_unwind.c b/arch/s390/lib/test_unwind.c
index 32b7a30b2485..eb382ceaa116 100644
--- a/arch/s390/lib/test_unwind.c
+++ b/arch/s390/lib/test_unwind.c
@@ -9,6 +9,7 @@
#include <linux/kallsyms.h>
#include <linux/kthread.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/kprobes.h>
#include <linux/wait.h>
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply related
* Re: linux-next: build failures after merge of the vfs tree
From: Stephen Rothwell @ 2020-06-17 6:57 UTC (permalink / raw)
To: Herbert Xu
Cc: Al Viro, Linux Next Mailing List, Linux Kernel Mailing List,
netdev
In-Reply-To: <20200616143807.GA1359@gondor.apana.org.au>
[-- Attachment #1: Type: text/plain, Size: 1064 bytes --]
Hi Herbert,
On Wed, 17 Jun 2020 00:38:07 +1000 Herbert Xu <herbert@gondor.apana.org.au> wrote:
>
> On Tue, Jun 16, 2020 at 04:38:49AM +0100, Al Viro wrote:
> >
> > Folded and pushed
>
> Thanks Al. Here's another one that I just got, could you add this
> one too?
>
> diff --git a/drivers/mtd/nand/raw/cadence-nand-controller.c b/drivers/mtd/nand/raw/cadence-nand-controller.c
> index c405722adfe1..c4f273e2fe78 100644
> --- a/drivers/mtd/nand/raw/cadence-nand-controller.c
> +++ b/drivers/mtd/nand/raw/cadence-nand-controller.c
> @@ -17,6 +17,7 @@
> #include <linux/mtd/rawnand.h>
> #include <linux/of_device.h>
> #include <linux/iopoll.h>
> +#include <linux/slab.h>
>
> /*
> * HPNFC can work in 3 modes:
Presumably another include needed:
arch/s390/lib/test_unwind.c:49:2: error: implicit declaration of function 'kmalloc' [-Werror=implicit-function-declaration]
arch/s390/lib/test_unwind.c:99:2: error: implicit declaration of function 'kfree' [-Werror=implicit-function-declaration]
--
Cheers,
Stephen Rothwell
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* [net-next v2] tipc: update a binding service via broadcast
From: Hoang Huu Le @ 2020-06-17 6:56 UTC (permalink / raw)
To: ying.xue, netdev; +Cc: jmaloy, maloy, kernel test robot
Currently, updating binding table (add service binding to
name table/withdraw a service binding) is being sent over replicast.
However, if we are scaling up clusters to > 100 nodes/containers this
method is less affection because of looping through nodes in a cluster one
by one.
It is worth to use broadcast to update a binding service. This way, the
binding table can be updated on all peer nodes in one shot.
Broadcast is used when all peer nodes, as indicated by a new capability
flag TIPC_NAMED_BCAST, support reception of this message type.
Four problems need to be considered when introducing this feature.
1) When establishing a link to a new peer node we still update this by a
unicast 'bulk' update. This may lead to race conditions, where a later
broadcast publication/withdrawal bypass the 'bulk', resulting in
disordered publications, or even that a withdrawal may arrive before the
corresponding publication. We solve this by adding an 'is_last_bulk' bit
in the last bulk messages so that it can be distinguished from all other
messages. Only when this message has arrived do we open up for reception
of broadcast publications/withdrawals.
2) When a first legacy node is added to the cluster all distribution
will switch over to use the legacy 'replicast' method, while the
opposite happens when the last legacy node leaves the cluster. This
entails another risk of message disordering that has to be handled. We
solve this by adding a sequence number to the broadcast/replicast
messages, so that disordering can be discovered and corrected. Note
however that we don't need to consider potential message loss or
duplication at this protocol level.
3) Bulk messages don't contain any sequence numbers, and will always
arrive in order. Hence we must exempt those from the sequence number
control and deliver them unconditionally. We solve this by adding a new
'is_bulk' bit in those messages so that they can be recognized.
4) Legacy messages, which don't contain any new bits or sequence
numbers, but neither can arrive out of order, also need to be exempt
from the initial synchronization and sequence number check, and
delivered unconditionally. Therefore, we add another 'is_not_legacy' bit
to all new messages so that those can be distinguished from legacy
messages and the latter delivered directly.
v1->v2:
- fix warning issue reported by kbuild test robot <lkp@intel.com>
- add santiy check to drop the publication message with a sequence
number that is lower than the agreed synch point
Signed-off-by: kernel test robot <lkp@intel.com>
Signed-off-by: Hoang Huu Le <hoang.h.le@dektech.com.au>
Acked-by: Jon Maloy <jmaloy@redhat.com>
---
net/tipc/bcast.c | 6 +--
net/tipc/bcast.h | 4 +-
net/tipc/link.c | 2 +-
net/tipc/msg.h | 40 +++++++++++++++
net/tipc/name_distr.c | 116 +++++++++++++++++++++++++++++++-----------
net/tipc/name_distr.h | 9 ++--
net/tipc/name_table.c | 9 +++-
net/tipc/name_table.h | 2 +
net/tipc/node.c | 29 ++++++++---
net/tipc/node.h | 8 +--
10 files changed, 177 insertions(+), 48 deletions(-)
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 383f87bc1061..940d176e0e87 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -250,8 +250,8 @@ static void tipc_bcast_select_xmit_method(struct net *net, int dests,
* Consumes the buffer chain.
* Returns 0 if success, otherwise errno: -EHOSTUNREACH,-EMSGSIZE
*/
-static int tipc_bcast_xmit(struct net *net, struct sk_buff_head *pkts,
- u16 *cong_link_cnt)
+int tipc_bcast_xmit(struct net *net, struct sk_buff_head *pkts,
+ u16 *cong_link_cnt)
{
struct tipc_link *l = tipc_bc_sndlink(net);
struct sk_buff_head xmitq;
@@ -752,7 +752,7 @@ void tipc_nlist_purge(struct tipc_nlist *nl)
nl->local = false;
}
-u32 tipc_bcast_get_broadcast_mode(struct net *net)
+u32 tipc_bcast_get_mode(struct net *net)
{
struct tipc_bc_base *bb = tipc_bc_base(net);
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 4240c95188b1..2d9352dc7b0e 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -90,6 +90,8 @@ void tipc_bcast_toggle_rcast(struct net *net, bool supp);
int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts,
struct tipc_mc_method *method, struct tipc_nlist *dests,
u16 *cong_link_cnt);
+int tipc_bcast_xmit(struct net *net, struct sk_buff_head *pkts,
+ u16 *cong_link_cnt);
int tipc_bcast_rcv(struct net *net, struct tipc_link *l, struct sk_buff *skb);
void tipc_bcast_ack_rcv(struct net *net, struct tipc_link *l,
struct tipc_msg *hdr);
@@ -101,7 +103,7 @@ int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg,
int tipc_nl_bc_link_set(struct net *net, struct nlattr *attrs[]);
int tipc_bclink_reset_stats(struct net *net, struct tipc_link *l);
-u32 tipc_bcast_get_broadcast_mode(struct net *net);
+u32 tipc_bcast_get_mode(struct net *net);
u32 tipc_bcast_get_broadcast_ratio(struct net *net);
void tipc_mcast_filter_msg(struct net *net, struct sk_buff_head *defq,
diff --git a/net/tipc/link.c b/net/tipc/link.c
index ee3b8d0576b8..eac89a3e22ce 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2745,7 +2745,7 @@ int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg,
void *hdr;
struct nlattr *attrs;
struct nlattr *prop;
- u32 bc_mode = tipc_bcast_get_broadcast_mode(net);
+ u32 bc_mode = tipc_bcast_get_mode(net);
u32 bc_ratio = tipc_bcast_get_broadcast_ratio(net);
if (!bcl)
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 58660d56bc83..65119e81ff0c 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -438,6 +438,36 @@ static inline void msg_set_errcode(struct tipc_msg *m, u32 err)
msg_set_bits(m, 1, 25, 0xf, err);
}
+static inline void msg_set_bulk(struct tipc_msg *m)
+{
+ msg_set_bits(m, 1, 28, 0x1, 1);
+}
+
+static inline u32 msg_is_bulk(struct tipc_msg *m)
+{
+ return msg_bits(m, 1, 28, 0x1);
+}
+
+static inline void msg_set_last_bulk(struct tipc_msg *m)
+{
+ msg_set_bits(m, 1, 27, 0x1, 1);
+}
+
+static inline u32 msg_is_last_bulk(struct tipc_msg *m)
+{
+ return msg_bits(m, 1, 27, 0x1);
+}
+
+static inline void msg_set_non_legacy(struct tipc_msg *m)
+{
+ msg_set_bits(m, 1, 26, 0x1, 1);
+}
+
+static inline u32 msg_is_legacy(struct tipc_msg *m)
+{
+ return !msg_bits(m, 1, 26, 0x1);
+}
+
static inline u32 msg_reroute_cnt(struct tipc_msg *m)
{
return msg_bits(m, 1, 21, 0xf);
@@ -567,6 +597,16 @@ static inline void msg_set_origport(struct tipc_msg *m, u32 p)
msg_set_word(m, 4, p);
}
+static inline u16 msg_named_seqno(struct tipc_msg *m)
+{
+ return msg_bits(m, 4, 0, 0xffff);
+}
+
+static inline void msg_set_named_seqno(struct tipc_msg *m, u16 n)
+{
+ msg_set_bits(m, 4, 0, 0xffff, n);
+}
+
static inline u32 msg_destport(struct tipc_msg *m)
{
return msg_word(m, 5);
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 5feaf3b67380..2f9c148f17e2 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -102,7 +102,8 @@ struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ)
pr_warn("Publication distribution failure\n");
return NULL;
}
-
+ msg_set_named_seqno(buf_msg(skb), nt->snd_nxt++);
+ msg_set_non_legacy(buf_msg(skb));
item = (struct distr_item *)msg_data(buf_msg(skb));
publ_to_item(item, publ);
return skb;
@@ -114,8 +115,8 @@ struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ)
struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ)
{
struct name_table *nt = tipc_name_table(net);
- struct sk_buff *buf;
struct distr_item *item;
+ struct sk_buff *skb;
write_lock_bh(&nt->cluster_scope_lock);
list_del(&publ->binding_node);
@@ -123,15 +124,16 @@ struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ)
if (publ->scope == TIPC_NODE_SCOPE)
return NULL;
- buf = named_prepare_buf(net, WITHDRAWAL, ITEM_SIZE, 0);
- if (!buf) {
+ skb = named_prepare_buf(net, WITHDRAWAL, ITEM_SIZE, 0);
+ if (!skb) {
pr_warn("Withdrawal distribution failure\n");
return NULL;
}
-
- item = (struct distr_item *)msg_data(buf_msg(buf));
+ msg_set_named_seqno(buf_msg(skb), nt->snd_nxt++);
+ msg_set_non_legacy(buf_msg(skb));
+ item = (struct distr_item *)msg_data(buf_msg(skb));
publ_to_item(item, publ);
- return buf;
+ return skb;
}
/**
@@ -141,7 +143,7 @@ struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ)
* @pls: linked list of publication items to be packed into buffer chain
*/
static void named_distribute(struct net *net, struct sk_buff_head *list,
- u32 dnode, struct list_head *pls)
+ u32 dnode, struct list_head *pls, u16 seqno)
{
struct publication *publ;
struct sk_buff *skb = NULL;
@@ -149,6 +151,7 @@ static void named_distribute(struct net *net, struct sk_buff_head *list,
u32 msg_dsz = ((tipc_node_get_mtu(net, dnode, 0, false) - INT_H_SIZE) /
ITEM_SIZE) * ITEM_SIZE;
u32 msg_rem = msg_dsz;
+ struct tipc_msg *hdr;
list_for_each_entry(publ, pls, binding_node) {
/* Prepare next buffer: */
@@ -159,8 +162,11 @@ static void named_distribute(struct net *net, struct sk_buff_head *list,
pr_warn("Bulk publication failure\n");
return;
}
- msg_set_bc_ack_invalid(buf_msg(skb), true);
- item = (struct distr_item *)msg_data(buf_msg(skb));
+ hdr = buf_msg(skb);
+ msg_set_bc_ack_invalid(hdr, true);
+ msg_set_bulk(hdr);
+ msg_set_non_legacy(hdr);
+ item = (struct distr_item *)msg_data(hdr);
}
/* Pack publication into message: */
@@ -176,24 +182,35 @@ static void named_distribute(struct net *net, struct sk_buff_head *list,
}
}
if (skb) {
- msg_set_size(buf_msg(skb), INT_H_SIZE + (msg_dsz - msg_rem));
+ hdr = buf_msg(skb);
+ msg_set_size(hdr, INT_H_SIZE + (msg_dsz - msg_rem));
skb_trim(skb, INT_H_SIZE + (msg_dsz - msg_rem));
__skb_queue_tail(list, skb);
}
+ hdr = buf_msg(skb_peek_tail(list));
+ msg_set_last_bulk(hdr);
+ msg_set_named_seqno(hdr, seqno);
}
/**
* tipc_named_node_up - tell specified node about all publications by this node
*/
-void tipc_named_node_up(struct net *net, u32 dnode)
+void tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities)
{
struct name_table *nt = tipc_name_table(net);
+ struct tipc_net *tn = tipc_net(net);
struct sk_buff_head head;
+ u16 seqno;
__skb_queue_head_init(&head);
+ spin_lock_bh(&tn->nametbl_lock);
+ if (!(capabilities & TIPC_NAMED_BCAST))
+ nt->rc_dests++;
+ seqno = nt->snd_nxt;
+ spin_unlock_bh(&tn->nametbl_lock);
read_lock_bh(&nt->cluster_scope_lock);
- named_distribute(net, &head, dnode, &nt->cluster_scope);
+ named_distribute(net, &head, dnode, &nt->cluster_scope, seqno);
tipc_node_xmit(net, &head, dnode, 0);
read_unlock_bh(&nt->cluster_scope_lock);
}
@@ -245,13 +262,21 @@ static void tipc_dist_queue_purge(struct net *net, u32 addr)
spin_unlock_bh(&tn->nametbl_lock);
}
-void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr)
+void tipc_publ_notify(struct net *net, struct list_head *nsub_list,
+ u32 addr, u16 capabilities)
{
+ struct name_table *nt = tipc_name_table(net);
+ struct tipc_net *tn = tipc_net(net);
+
struct publication *publ, *tmp;
list_for_each_entry_safe(publ, tmp, nsub_list, binding_node)
tipc_publ_purge(net, publ, addr);
tipc_dist_queue_purge(net, addr);
+ spin_lock_bh(&tn->nametbl_lock);
+ if (!(capabilities & TIPC_NAMED_BCAST))
+ nt->rc_dests--;
+ spin_unlock_bh(&tn->nametbl_lock);
}
/**
@@ -295,29 +320,62 @@ static bool tipc_update_nametbl(struct net *net, struct distr_item *i,
return false;
}
+static struct sk_buff *tipc_named_dequeue(struct sk_buff_head *namedq,
+ u16 *rcv_nxt, bool *open)
+{
+ struct sk_buff *skb, *tmp;
+ struct tipc_msg *hdr;
+ u16 seqno;
+
+ skb_queue_walk_safe(namedq, skb, tmp) {
+ skb_linearize(skb);
+ hdr = buf_msg(skb);
+ seqno = msg_named_seqno(hdr);
+ if (msg_is_last_bulk(hdr)) {
+ *rcv_nxt = seqno;
+ *open = true;
+ }
+
+ if (msg_is_bulk(hdr) || msg_is_legacy(hdr)) {
+ __skb_unlink(skb, namedq);
+ return skb;
+ }
+
+ if (*open && (*rcv_nxt == seqno)) {
+ (*rcv_nxt)++;
+ __skb_unlink(skb, namedq);
+ return skb;
+ }
+
+ if (less(seqno, *rcv_nxt)) {
+ __skb_unlink(skb, namedq);
+ kfree_skb(skb);
+ continue;
+ }
+ }
+ return NULL;
+}
+
/**
* tipc_named_rcv - process name table update messages sent by another node
*/
-void tipc_named_rcv(struct net *net, struct sk_buff_head *inputq)
+void tipc_named_rcv(struct net *net, struct sk_buff_head *namedq,
+ u16 *rcv_nxt, bool *open)
{
- struct tipc_net *tn = net_generic(net, tipc_net_id);
- struct tipc_msg *msg;
+ struct tipc_net *tn = tipc_net(net);
struct distr_item *item;
- uint count;
- u32 node;
+ struct tipc_msg *hdr;
struct sk_buff *skb;
- int mtype;
+ u32 count, node;
spin_lock_bh(&tn->nametbl_lock);
- for (skb = skb_dequeue(inputq); skb; skb = skb_dequeue(inputq)) {
- skb_linearize(skb);
- msg = buf_msg(skb);
- mtype = msg_type(msg);
- item = (struct distr_item *)msg_data(msg);
- count = msg_data_sz(msg) / ITEM_SIZE;
- node = msg_orignode(msg);
+ while ((skb = tipc_named_dequeue(namedq, rcv_nxt, open))) {
+ hdr = buf_msg(skb);
+ node = msg_orignode(hdr);
+ item = (struct distr_item *)msg_data(hdr);
+ count = msg_data_sz(hdr) / ITEM_SIZE;
while (count--) {
- tipc_update_nametbl(net, item, node, mtype);
+ tipc_update_nametbl(net, item, node, msg_type(hdr));
item++;
}
kfree_skb(skb);
@@ -345,6 +403,6 @@ void tipc_named_reinit(struct net *net)
publ->node = self;
list_for_each_entry_rcu(publ, &nt->cluster_scope, binding_node)
publ->node = self;
-
+ nt->rc_dests = 0;
spin_unlock_bh(&tn->nametbl_lock);
}
diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h
index 63fc73e0fa6c..092323158f06 100644
--- a/net/tipc/name_distr.h
+++ b/net/tipc/name_distr.h
@@ -67,11 +67,14 @@ struct distr_item {
__be32 key;
};
+void tipc_named_bcast(struct net *net, struct sk_buff *skb);
struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ);
struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ);
-void tipc_named_node_up(struct net *net, u32 dnode);
-void tipc_named_rcv(struct net *net, struct sk_buff_head *msg_queue);
+void tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities);
+void tipc_named_rcv(struct net *net, struct sk_buff_head *namedq,
+ u16 *rcv_nxt, bool *open);
void tipc_named_reinit(struct net *net);
-void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr);
+void tipc_publ_notify(struct net *net, struct list_head *nsub_list,
+ u32 addr, u16 capabilities);
#endif
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 359b2bc888cf..2ac33d32edc2 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -729,6 +729,7 @@ struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower,
struct tipc_net *tn = tipc_net(net);
struct publication *p = NULL;
struct sk_buff *skb = NULL;
+ u32 rc_dests;
spin_lock_bh(&tn->nametbl_lock);
@@ -743,12 +744,14 @@ struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower,
nt->local_publ_count++;
skb = tipc_named_publish(net, p);
}
+ rc_dests = nt->rc_dests;
exit:
spin_unlock_bh(&tn->nametbl_lock);
if (skb)
- tipc_node_broadcast(net, skb);
+ tipc_node_broadcast(net, skb, rc_dests);
return p;
+
}
/**
@@ -762,6 +765,7 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower,
u32 self = tipc_own_addr(net);
struct sk_buff *skb = NULL;
struct publication *p;
+ u32 rc_dests;
spin_lock_bh(&tn->nametbl_lock);
@@ -775,10 +779,11 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower,
pr_err("Failed to remove local publication {%u,%u,%u}/%u\n",
type, lower, upper, key);
}
+ rc_dests = nt->rc_dests;
spin_unlock_bh(&tn->nametbl_lock);
if (skb) {
- tipc_node_broadcast(net, skb);
+ tipc_node_broadcast(net, skb, rc_dests);
return 1;
}
return 0;
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index 728bc7016c38..8064e1986e2c 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -106,6 +106,8 @@ struct name_table {
struct list_head cluster_scope;
rwlock_t cluster_scope_lock;
u32 local_publ_count;
+ u32 rc_dests;
+ u32 snd_nxt;
};
int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index a4c2816c3746..030a51c4d1fa 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -75,6 +75,8 @@ struct tipc_bclink_entry {
struct sk_buff_head arrvq;
struct sk_buff_head inputq2;
struct sk_buff_head namedq;
+ u16 named_rcv_nxt;
+ bool named_open;
};
/**
@@ -396,10 +398,10 @@ static void tipc_node_write_unlock(struct tipc_node *n)
write_unlock_bh(&n->lock);
if (flags & TIPC_NOTIFY_NODE_DOWN)
- tipc_publ_notify(net, publ_list, addr);
+ tipc_publ_notify(net, publ_list, addr, n->capabilities);
if (flags & TIPC_NOTIFY_NODE_UP)
- tipc_named_node_up(net, addr);
+ tipc_named_node_up(net, addr, n->capabilities);
if (flags & TIPC_NOTIFY_LINK_UP) {
tipc_mon_peer_up(net, addr, bearer_id);
@@ -1483,6 +1485,7 @@ static void node_lost_contact(struct tipc_node *n,
/* Clean up broadcast state */
tipc_bcast_remove_peer(n->net, n->bc_entry.link);
+ __skb_queue_purge(&n->bc_entry.namedq);
/* Abort any ongoing link failover */
for (i = 0; i < MAX_BEARERS; i++) {
@@ -1729,12 +1732,23 @@ int tipc_node_distr_xmit(struct net *net, struct sk_buff_head *xmitq)
return 0;
}
-void tipc_node_broadcast(struct net *net, struct sk_buff *skb)
+void tipc_node_broadcast(struct net *net, struct sk_buff *skb, int rc_dests)
{
+ struct sk_buff_head xmitq;
struct sk_buff *txskb;
struct tipc_node *n;
+ u16 dummy;
u32 dst;
+ /* Use broadcast if all nodes support it */
+ if (!rc_dests && tipc_bcast_get_mode(net) != BCLINK_MODE_RCAST) {
+ __skb_queue_head_init(&xmitq);
+ __skb_queue_tail(&xmitq, skb);
+ tipc_bcast_xmit(net, &xmitq, &dummy);
+ return;
+ }
+
+ /* Otherwise use legacy replicast method */
rcu_read_lock();
list_for_each_entry_rcu(n, tipc_nodes(net), list) {
dst = n->addr;
@@ -1749,7 +1763,6 @@ void tipc_node_broadcast(struct net *net, struct sk_buff *skb)
tipc_node_xmit_skb(net, txskb, dst, 0);
}
rcu_read_unlock();
-
kfree_skb(skb);
}
@@ -1844,7 +1857,9 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id
/* Handle NAME_DISTRIBUTOR messages sent from 1.7 nodes */
if (!skb_queue_empty(&n->bc_entry.namedq))
- tipc_named_rcv(net, &n->bc_entry.namedq);
+ tipc_named_rcv(net, &n->bc_entry.namedq,
+ &n->bc_entry.named_rcv_nxt,
+ &n->bc_entry.named_open);
/* If reassembly or retransmission failure => reset all links to peer */
if (rc & TIPC_LINK_DOWN_EVT)
@@ -2114,7 +2129,9 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)
tipc_node_link_down(n, bearer_id, false);
if (unlikely(!skb_queue_empty(&n->bc_entry.namedq)))
- tipc_named_rcv(net, &n->bc_entry.namedq);
+ tipc_named_rcv(net, &n->bc_entry.namedq,
+ &n->bc_entry.named_rcv_nxt,
+ &n->bc_entry.named_open);
if (unlikely(!skb_queue_empty(&n->bc_entry.inputq1)))
tipc_node_mcast_rcv(n);
diff --git a/net/tipc/node.h b/net/tipc/node.h
index a6803b449a2c..9f6f13f1604f 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -55,7 +55,8 @@ enum {
TIPC_MCAST_RBCTL = (1 << 7),
TIPC_GAP_ACK_BLOCK = (1 << 8),
TIPC_TUNNEL_ENHANCED = (1 << 9),
- TIPC_NAGLE = (1 << 10)
+ TIPC_NAGLE = (1 << 10),
+ TIPC_NAMED_BCAST = (1 << 11)
};
#define TIPC_NODE_CAPABILITIES (TIPC_SYN_BIT | \
@@ -68,7 +69,8 @@ enum {
TIPC_MCAST_RBCTL | \
TIPC_GAP_ACK_BLOCK | \
TIPC_TUNNEL_ENHANCED | \
- TIPC_NAGLE)
+ TIPC_NAGLE | \
+ TIPC_NAMED_BCAST)
#define INVALID_BEARER_ID -1
@@ -101,7 +103,7 @@ int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest,
u32 selector);
void tipc_node_subscribe(struct net *net, struct list_head *subscr, u32 addr);
void tipc_node_unsubscribe(struct net *net, struct list_head *subscr, u32 addr);
-void tipc_node_broadcast(struct net *net, struct sk_buff *skb);
+void tipc_node_broadcast(struct net *net, struct sk_buff *skb, int rc_dests);
int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port);
void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port);
int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel, bool connected);
--
2.25.1
^ permalink raw reply related
* Re: [PATCH bpf 1/2] flow_dissector: reject invalid attach_flags
From: John Fastabend @ 2020-06-17 6:49 UTC (permalink / raw)
To: Alexei Starovoitov, Lorenz Bauer
Cc: Alexei Starovoitov, Daniel Borkmann, Jakub Sitnicki, kernel-team,
Network Development, bpf, LKML, John Fastabend
In-Reply-To: <CAADnVQLXEq5+ko_ojmuh1Oc84HiPrfLF-7Cdh1xwwm-PhoFwBQ@mail.gmail.com>
Alexei Starovoitov wrote:
> On Tue, Jun 16, 2020 at 1:30 AM Lorenz Bauer <lmb@cloudflare.com> wrote:
> >
> > On Tue, 16 Jun 2020 at 04:55, Alexei Starovoitov
> > <alexei.starovoitov@gmail.com> wrote:
> > >
> > > On Mon, Jun 15, 2020 at 7:43 AM Lorenz Bauer <lmb@cloudflare.com> wrote:
> > > >
> > > > On Fri, 12 Jun 2020 at 23:36, Alexei Starovoitov
> > > > <alexei.starovoitov@gmail.com> wrote:
> > > > >
> > > > > On Fri, Jun 12, 2020 at 9:02 AM Lorenz Bauer <lmb@cloudflare.com> wrote:
> > > > > >
> > > > > > Using BPF_PROG_ATTACH on a flow dissector program supports neither flags
> > > > > > nor target_fd but accepts any value. Return EINVAL if either are non-zero.
> > > > > >
> > > > > > Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>
> > > > > > Fixes: b27f7bb590ba ("flow_dissector: Move out netns_bpf prog callbacks")
> > > > > > ---
> > > > > > kernel/bpf/net_namespace.c | 3 +++
> > > > > > 1 file changed, 3 insertions(+)
> > > > > >
> > > > > > diff --git a/kernel/bpf/net_namespace.c b/kernel/bpf/net_namespace.c
> > > > > > index 78cf061f8179..56133e78ae4f 100644
> > > > > > --- a/kernel/bpf/net_namespace.c
> > > > > > +++ b/kernel/bpf/net_namespace.c
> > > > > > @@ -192,6 +192,9 @@ int netns_bpf_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog)
> > > > > > struct net *net;
> > > > > > int ret;
> > > > > >
> > > > > > + if (attr->attach_flags || attr->target_fd)
> > > > > > + return -EINVAL;
> > > > > > +
> > > > >
> > > > > In theory it makes sense, but how did you test it?
> > > >
> > > > Not properly it seems, sorry!
> > > >
> > > > > test_progs -t flow
> > > > > fails 5 tests.
> > > >
> > > > I spent today digging through this, and the issue is actually more annoying than
> > > > I thought. BPF_PROG_DETACH for sockmap and flow_dissector ignores
> > > > attach_bpf_fd. The cgroup and lirc2 attach point use this to make sure that the
> > > > program being detached is actually what user space expects. We actually have
> > > > tests that set attach_bpf_fd for these to attach points, which tells
> > > > me that this is
> > > > an easy mistake to make.
In sockmap case I didn't manage to think what multiple programs of the same type
on the same map would look like so we can just remove whatever program is there.
Is there a problem with this or is it that we just want the sanity check.
> > > >
> > > > Unfortunately I can't come up with a good fix that seems backportable:
> > > > - Making sockmap and flow_dissector have the same semantics as cgroup
> > > > and lirc2 requires a bunch of changes (probably a new function for sockmap)
> > >
> > > making flow dissector pass prog_fd as cg and lirc is certainly my preference.
> > > Especially since tests are passing fd user code is likely doing the same,
> > > so breakage is unlikely. Also it wasn't done that long ago, so
> > > we can backport far enough.
> > > It will remove cap_net_admin ugly check in bpf_prog_detach()
> > > which is the only exception now in cap model.
> >
> > SGTM. What about sockmap though? The code for that has been around for ages.
>
> you mean the second patch that enforces sock_map_get_from_fd doesn't
> use attach_flags?
> I think it didn't break anything, so enforcing is fine.
I'm ok with enforcing it.
>
> or the detach part that doesn't use prog_fd ?
> I'm not sure what's the best here.
> At least from cap perspective it's fine because map_fd is there.
>
> John, wdyt?
I think we can keep the current detach without the prog_fd as-is. And
then add logic so that if the prog_fd is included we check it?
^ permalink raw reply
* [PATCH net-next 5/5] cxgb4: add support to read serial flash
From: Vishal Kulkarni @ 2020-06-17 6:29 UTC (permalink / raw)
To: netdev, davem; +Cc: nirranjan, dt, Vishal Kulkarni
In-Reply-To: <20200617062907.26121-1-vishal@chelsio.com>
This patch adds support to dump flash memory via
ethtool --get-dump
Signed-off-by: Vishal Kulkarni <vishal@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cudbg_if.h | 3 +-
.../net/ethernet/chelsio/cxgb4/cudbg_lib.c | 38 +++++++++++++++++++
.../net/ethernet/chelsio/cxgb4/cudbg_lib.h | 4 +-
.../net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c | 14 +++++++
.../net/ethernet/chelsio/cxgb4/cxgb4_cudbg.h | 1 +
5 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_if.h b/drivers/net/ethernet/chelsio/cxgb4/cudbg_if.h
index fc3813050f0d..c84719e3ca08 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_if.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_if.h
@@ -70,7 +70,8 @@ enum cudbg_dbg_entity_type {
CUDBG_HMA_INDIRECT = 67,
CUDBG_HMA = 68,
CUDBG_QDESC = 70,
- CUDBG_MAX_ENTITY = 71,
+ CUDBG_FLASH = 71,
+ CUDBG_MAX_ENTITY = 72,
};
struct cudbg_init {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
index 7b9cd69f9844..a09790989584 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
@@ -3156,3 +3156,41 @@ int cudbg_collect_qdesc(struct cudbg_init *pdbg_init,
return rc;
}
+
+int cudbg_collect_flash(struct cudbg_init *pdbg_init,
+ struct cudbg_buffer *dbg_buff,
+ struct cudbg_error *cudbg_err)
+{
+ struct adapter *padap = pdbg_init->adap;
+ u32 count = padap->params.sf_size, n;
+ struct cudbg_buffer temp_buff = {0};
+ u32 addr, i;
+ int rc;
+
+ addr = FLASH_EXP_ROM_START;
+
+ for (i = 0; i < count; i += SF_PAGE_SIZE) {
+ n = min_t(u32, count - i, SF_PAGE_SIZE);
+
+ rc = cudbg_get_buff(pdbg_init, dbg_buff, n, &temp_buff);
+ if (rc) {
+ cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;
+ goto out;
+ }
+ rc = t4_read_flash(padap, addr, n, (u32 *)temp_buff.data, 0);
+ if (rc)
+ goto out;
+
+ addr += (n * 4);
+ rc = cudbg_write_and_release_buff(pdbg_init, &temp_buff,
+ dbg_buff);
+ if (rc) {
+ cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;
+ goto out;
+ }
+ }
+
+out:
+ return rc;
+}
+
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.h b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.h
index 10ee6ed1d932..0f488d52797b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.h
@@ -162,7 +162,9 @@ int cudbg_collect_hma_meminfo(struct cudbg_init *pdbg_init,
int cudbg_collect_qdesc(struct cudbg_init *pdbg_init,
struct cudbg_buffer *dbg_buff,
struct cudbg_error *cudbg_err);
-
+int cudbg_collect_flash(struct cudbg_init *pdbg_init,
+ struct cudbg_buffer *dbg_buff,
+ struct cudbg_error *cudbg_err);
struct cudbg_entity_hdr *cudbg_get_entity_hdr(void *outbuf, int i);
void cudbg_align_debug_buffer(struct cudbg_buffer *dbg_buff,
struct cudbg_entity_hdr *entity_hdr);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c
index e374b413d9ac..d7afe0746878 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c
@@ -66,6 +66,10 @@ static const struct cxgb4_collect_entity cxgb4_collect_hw_dump[] = {
{ CUDBG_HMA_INDIRECT, cudbg_collect_hma_indirect },
};
+static const struct cxgb4_collect_entity cxgb4_collect_flash_dump[] = {
+ { CUDBG_FLASH, cudbg_collect_flash },
+};
+
static u32 cxgb4_get_entity_length(struct adapter *adap, u32 entity)
{
struct cudbg_tcam tcam_region = { 0 };
@@ -330,6 +334,9 @@ u32 cxgb4_get_dump_length(struct adapter *adap, u32 flag)
}
}
+ if (flag & CXGB4_ETH_DUMP_FLASH)
+ len += adap->params.sf_size;
+
/* If compression is enabled, a smaller destination buffer is enough */
wsize = cudbg_get_workspace_size();
if (wsize && len > CUDBG_DUMP_BUFF_SIZE)
@@ -468,6 +475,13 @@ int cxgb4_cudbg_collect(struct adapter *adap, void *buf, u32 *buf_size,
buf,
&total_size);
+ if (flag & CXGB4_ETH_DUMP_FLASH)
+ cxgb4_cudbg_collect_entity(&cudbg_init, &dbg_buff,
+ cxgb4_collect_flash_dump,
+ ARRAY_SIZE(cxgb4_collect_flash_dump),
+ buf,
+ &total_size);
+
cudbg_free_compress_buff(&cudbg_init);
cudbg_hdr->data_len = total_size;
if (cudbg_init.compress_type != CUDBG_COMPRESSION_NONE)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.h
index 66b805c7a92c..c04a49b6378d 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.h
@@ -27,6 +27,7 @@ enum CXGB4_ETHTOOL_DUMP_FLAGS {
CXGB4_ETH_DUMP_NONE = ETH_FW_DUMP_DISABLE,
CXGB4_ETH_DUMP_MEM = (1 << 0), /* On-Chip Memory Dumps */
CXGB4_ETH_DUMP_HW = (1 << 1), /* various FW and HW dumps */
+ CXGB4_ETH_DUMP_FLASH = (1 << 2), /* Dump flash memory */
};
#define CXGB4_ETH_DUMP_ALL (CXGB4_ETH_DUMP_MEM | CXGB4_ETH_DUMP_HW)
--
2.18.2
^ permalink raw reply related
* [PATCH net-next 4/5] cxgb4: add support to flash boot cfg image
From: Vishal Kulkarni @ 2020-06-17 6:29 UTC (permalink / raw)
To: netdev, davem; +Cc: nirranjan, dt, Vishal Kulkarni
In-Reply-To: <20200617062907.26121-1-vishal@chelsio.com>
Update set_flash to flash boot cfg image to flash region
Signed-off-by: Vishal Kulkarni <vishal@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 9 ++
.../ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 30 +++++++
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 90 +++++++++++++++++++
3 files changed, 129 insertions(+)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index b0e06644da76..e6aab51a93ac 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -143,6 +143,12 @@ enum {
CXGB4_ETHTOOL_FLASH_FW = 1,
CXGB4_ETHTOOL_FLASH_PHY = 2,
CXGB4_ETHTOOL_FLASH_BOOT = 3,
+ CXGB4_ETHTOOL_FLASH_BOOTCFG = 4
+};
+
+struct cxgb4_bootcfg_data {
+ __le16 signature;
+ __u8 reserved[2];
};
struct cxgb4_pcir_data {
@@ -183,6 +189,7 @@ struct legacy_pci_rom_hdr {
/* BOOT constants */
enum {
+ BOOT_CFG_SIG = 0x4243,
BOOT_SIZE_INC = 512,
BOOT_SIGNATURE = 0xaa55,
BOOT_MIN_SIZE = sizeof(struct cxgb4_pci_exp_rom_header),
@@ -2061,6 +2068,8 @@ int t4_i2c_rd(struct adapter *adap, unsigned int mbox, int port,
unsigned int len, u8 *buf);
int t4_load_boot(struct adapter *adap, u8 *boot_data,
unsigned int boot_addr, unsigned int size);
+int t4_load_bootcfg(struct adapter *adap,
+ const u8 *cfg_data, unsigned int size);
void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, struct sge_fl *fl);
void free_tx_desc(struct adapter *adap, struct sge_txq *q,
unsigned int n, bool unmap);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
index d1fd01b2cc2a..6b48760a55cb 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
@@ -30,6 +30,7 @@ static const char * const flash_region_strings[] = {
"Firmware",
"PHY Firmware",
"Boot",
+ "Boot CFG",
};
static const char stats_strings[][ETH_GSTRING_LEN] = {
@@ -1244,6 +1245,19 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
return err;
}
+static int cxgb4_ethtool_flash_bootcfg(struct net_device *netdev,
+ const u8 *data, u32 size)
+{
+ struct adapter *adap = netdev2adap(netdev);
+ int ret;
+
+ ret = t4_load_bootcfg(adap, data, size);
+ if (ret)
+ dev_err(adap->pdev_dev, "Failed to load boot cfg image\n");
+
+ return ret;
+}
+
static int cxgb4_ethtool_flash_boot(struct net_device *netdev,
const u8 *bdata, u32 size)
{
@@ -1338,6 +1352,9 @@ static int cxgb4_ethtool_flash_region(struct net_device *netdev,
case CXGB4_ETHTOOL_FLASH_BOOT:
ret = cxgb4_ethtool_flash_boot(netdev, data, size);
break;
+ case CXGB4_ETHTOOL_FLASH_BOOTCFG:
+ ret = cxgb4_ethtool_flash_bootcfg(netdev, data, size);
+ break;
default:
ret = -EOPNOTSUPP;
break;
@@ -1367,6 +1384,17 @@ static int cxgb4_validate_fw_image(const u8 *data, u32 *size)
return 0;
}
+static int cxgb4_validate_bootcfg_image(const u8 *data, u32 *size)
+{
+ struct cxgb4_bootcfg_data *header;
+
+ header = (struct cxgb4_bootcfg_data *)data;
+ if (le16_to_cpu(header->signature) != BOOT_CFG_SIG)
+ return -EINVAL;
+
+ return 0;
+}
+
static int cxgb4_validate_boot_image(const u8 *data, u32 *size)
{
struct cxgb4_pci_exp_rom_header *exp_header;
@@ -1403,6 +1431,8 @@ static int cxgb4_ethtool_get_flash_region(const u8 *data, u32 *size)
return CXGB4_ETHTOOL_FLASH_BOOT;
if (!cxgb4_validate_phy_image(data, size))
return CXGB4_ETHTOOL_FLASH_PHY;
+ if (!cxgb4_validate_bootcfg_image(data, size))
+ return CXGB4_ETHTOOL_FLASH_BOOTCFG;
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index f1d345845d19..0ebb5d4b023a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -10668,3 +10668,93 @@ int t4_load_boot(struct adapter *adap, u8 *boot_data,
ret);
return ret;
}
+
+/**
+ * t4_flash_bootcfg_addr - return the address of the flash
+ * optionrom configuration
+ * @adapter: the adapter
+ *
+ * Return the address within the flash where the OptionROM Configuration
+ * is stored, or an error if the device FLASH is too small to contain
+ * a OptionROM Configuration.
+ */
+static int t4_flash_bootcfg_addr(struct adapter *adapter)
+{
+ /**
+ * If the device FLASH isn't large enough to hold a Firmware
+ * Configuration File, return an error.
+ */
+ if (adapter->params.sf_size <
+ FLASH_BOOTCFG_START + FLASH_BOOTCFG_MAX_SIZE)
+ return -ENOSPC;
+
+ return FLASH_BOOTCFG_START;
+}
+
+int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
+{
+ unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
+ struct cxgb4_bootcfg_data *header;
+ unsigned int flash_cfg_start_sec;
+ unsigned int addr, npad;
+ int ret, i, n, cfg_addr;
+
+ cfg_addr = t4_flash_bootcfg_addr(adap);
+ if (cfg_addr < 0)
+ return cfg_addr;
+
+ addr = cfg_addr;
+ flash_cfg_start_sec = addr / SF_SEC_SIZE;
+
+ if (size > FLASH_BOOTCFG_MAX_SIZE) {
+ dev_err(adap->pdev_dev, "bootcfg file too large, max is %u bytes\n",
+ FLASH_BOOTCFG_MAX_SIZE);
+ return -EFBIG;
+ }
+
+ header = (struct cxgb4_bootcfg_data *)cfg_data;
+ if (le16_to_cpu(header->signature) != BOOT_CFG_SIG) {
+ dev_err(adap->pdev_dev, "Wrong bootcfg signature\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ i = DIV_ROUND_UP(FLASH_BOOTCFG_MAX_SIZE,
+ sf_sec_size);
+ ret = t4_flash_erase_sectors(adap, flash_cfg_start_sec,
+ flash_cfg_start_sec + i - 1);
+
+ /**
+ * If size == 0 then we're simply erasing the FLASH sectors associated
+ * with the on-adapter OptionROM Configuration File.
+ */
+ if (ret || size == 0)
+ goto out;
+
+ /* this will write to the flash up to SF_PAGE_SIZE at a time */
+ for (i = 0; i < size; i += SF_PAGE_SIZE) {
+ n = min_t(u32, size - i, SF_PAGE_SIZE);
+
+ ret = t4_write_flash(adap, addr, n, cfg_data);
+ if (ret)
+ goto out;
+
+ addr += SF_PAGE_SIZE;
+ cfg_data += SF_PAGE_SIZE;
+ }
+
+ npad = ((size + 4 - 1) & ~3) - size;
+ for (i = 0; i < npad; i++) {
+ u8 data = 0;
+
+ ret = t4_write_flash(adap, cfg_addr + size + i, 1, &data);
+ if (ret)
+ goto out;
+ }
+
+out:
+ if (ret)
+ dev_err(adap->pdev_dev, "boot config data %s failed %d\n",
+ (size == 0 ? "clear" : "download"), ret);
+ return ret;
+}
--
2.18.2
^ permalink raw reply related
* [PATCH net-next 3/5] cxgb4: add support to flash boot image
From: Vishal Kulkarni @ 2020-06-17 6:29 UTC (permalink / raw)
To: netdev, davem; +Cc: nirranjan, dt, Vishal Kulkarni
In-Reply-To: <20200617062907.26121-1-vishal@chelsio.com>
Update set_flash to flash boot image to flash region
Signed-off-by: Vishal Kulkarni <vishal@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 48 +++++
.../ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 56 ++++++
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 187 ++++++++++++++++++
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 6 +
4 files changed, 297 insertions(+)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index cc76983130cc..b0e06644da76 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -142,6 +142,52 @@ enum cc_fec {
enum {
CXGB4_ETHTOOL_FLASH_FW = 1,
CXGB4_ETHTOOL_FLASH_PHY = 2,
+ CXGB4_ETHTOOL_FLASH_BOOT = 3,
+};
+
+struct cxgb4_pcir_data {
+ __le32 signature; /* Signature. The string "PCIR" */
+ __le16 vendor_id; /* Vendor Identification */
+ __le16 device_id; /* Device Identification */
+ __u8 vital_product[2]; /* Pointer to Vital Product Data */
+ __u8 length[2]; /* PCIR Data Structure Length */
+ __u8 revision; /* PCIR Data Structure Revision */
+ __u8 class_code[3]; /* Class Code */
+ __u8 image_length[2]; /* Image Length. Multiple of 512B */
+ __u8 code_revision[2]; /* Revision Level of Code/Data */
+ __u8 code_type;
+ __u8 indicator;
+ __u8 reserved[2];
+};
+
+/* BIOS boot headers */
+struct cxgb4_pci_exp_rom_header {
+ __le16 signature; /* ROM Signature. Should be 0xaa55 */
+ __u8 reserved[22]; /* Reserved per processor Architecture data */
+ __le16 pcir_offset; /* Offset to PCI Data Structure */
+};
+
+/* Legacy PCI Expansion ROM Header */
+struct legacy_pci_rom_hdr {
+ __u8 signature[2]; /* ROM Signature. Should be 0xaa55 */
+ __u8 size512; /* Current Image Size in units of 512 bytes */
+ __u8 initentry_point[4];
+ __u8 cksum; /* Checksum computed on the entire Image */
+ __u8 reserved[16]; /* Reserved */
+ __le16 pcir_offset; /* Offset to PCI Data Struture */
+};
+
+#define CXGB4_HDR_CODE1 0x00
+#define CXGB4_HDR_CODE2 0x03
+#define CXGB4_HDR_INDI 0x80
+
+/* BOOT constants */
+enum {
+ BOOT_SIZE_INC = 512,
+ BOOT_SIGNATURE = 0xaa55,
+ BOOT_MIN_SIZE = sizeof(struct cxgb4_pci_exp_rom_header),
+ BOOT_MAX_SIZE = 1024 * BOOT_SIZE_INC,
+ PCIR_SIGNATURE = 0x52494350
};
struct port_stats {
@@ -2013,6 +2059,8 @@ void t4_register_netevent_notifier(void);
int t4_i2c_rd(struct adapter *adap, unsigned int mbox, int port,
unsigned int devid, unsigned int offset,
unsigned int len, u8 *buf);
+int t4_load_boot(struct adapter *adap, u8 *boot_data,
+ unsigned int boot_addr, unsigned int size);
void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, struct sge_fl *fl);
void free_tx_desc(struct adapter *adap, struct sge_txq *q,
unsigned int n, bool unmap);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
index 4a72f481c4c0..d1fd01b2cc2a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
@@ -29,6 +29,7 @@ static const char * const flash_region_strings[] = {
"All",
"Firmware",
"PHY Firmware",
+ "Boot",
};
static const char stats_strings[][ETH_GSTRING_LEN] = {
@@ -1243,6 +1244,28 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
return err;
}
+static int cxgb4_ethtool_flash_boot(struct net_device *netdev,
+ const u8 *bdata, u32 size)
+{
+ struct adapter *adap = netdev2adap(netdev);
+ unsigned int offset;
+ u8 *data;
+ int ret;
+
+ data = kmemdup(bdata, size, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ offset = OFFSET_G(t4_read_reg(adap, PF_REG(0, PCIE_PF_EXPROM_OFST_A)));
+
+ ret = t4_load_boot(adap, data, offset, size);
+ if (ret)
+ dev_err(adap->pdev_dev, "Failed to load boot image\n");
+
+ kfree(data);
+ return ret;
+}
+
#define CXGB4_PHY_SIG 0x130000ea
static int cxgb4_validate_phy_image(const u8 *data, u32 *size)
@@ -1312,6 +1335,9 @@ static int cxgb4_ethtool_flash_region(struct net_device *netdev,
case CXGB4_ETHTOOL_FLASH_PHY:
ret = cxgb4_ethtool_flash_phy(netdev, data, size);
break;
+ case CXGB4_ETHTOOL_FLASH_BOOT:
+ ret = cxgb4_ethtool_flash_boot(netdev, data, size);
+ break;
default:
ret = -EOPNOTSUPP;
break;
@@ -1341,10 +1367,40 @@ static int cxgb4_validate_fw_image(const u8 *data, u32 *size)
return 0;
}
+static int cxgb4_validate_boot_image(const u8 *data, u32 *size)
+{
+ struct cxgb4_pci_exp_rom_header *exp_header;
+ struct cxgb4_pcir_data *pcir_header;
+ struct legacy_pci_rom_hdr *header;
+ const u8 *cur_header = data;
+ u16 pcir_offset;
+
+ exp_header = (struct cxgb4_pci_exp_rom_header *)data;
+
+ if (le16_to_cpu(exp_header->signature) != BOOT_SIGNATURE)
+ return -EINVAL;
+
+ if (size) {
+ do {
+ header = (struct legacy_pci_rom_hdr *)cur_header;
+ pcir_offset = le16_to_cpu(header->pcir_offset);
+ pcir_header = (struct cxgb4_pcir_data *)(cur_header +
+ pcir_offset);
+
+ *size += header->size512 * 512;
+ cur_header += header->size512 * 512;
+ } while (!(pcir_header->indicator & CXGB4_HDR_INDI));
+ }
+
+ return 0;
+}
+
static int cxgb4_ethtool_get_flash_region(const u8 *data, u32 *size)
{
if (!cxgb4_validate_fw_image(data, size))
return CXGB4_ETHTOOL_FLASH_FW;
+ if (!cxgb4_validate_boot_image(data, size))
+ return CXGB4_ETHTOOL_FLASH_BOOT;
if (!cxgb4_validate_phy_image(data, size))
return CXGB4_ETHTOOL_FLASH_PHY;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 1c8068c02728..f1d345845d19 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -10481,3 +10481,190 @@ int t4_set_vlan_acl(struct adapter *adap, unsigned int mbox, unsigned int vf,
return t4_wr_mbox(adap, adap->mbox, &vlan_cmd, sizeof(vlan_cmd), NULL);
}
+
+/**
+ * modify_device_id - Modifies the device ID of the Boot BIOS image
+ * @adatper: the device ID to write.
+ * @boot_data: the boot image to modify.
+ *
+ * Write the supplied device ID to the boot BIOS image.
+ */
+static void modify_device_id(int device_id, u8 *boot_data)
+{
+ struct cxgb4_pcir_data *pcir_header;
+ struct legacy_pci_rom_hdr *header;
+ u8 *cur_header = boot_data;
+ u16 pcir_offset;
+
+ /* Loop through all chained images and change the device ID's */
+ do {
+ header = (struct legacy_pci_rom_hdr *)cur_header;
+ pcir_offset = le16_to_cpu(header->pcir_offset);
+ pcir_header = (struct cxgb4_pcir_data *)(cur_header +
+ pcir_offset);
+
+ /**
+ * Only modify the Device ID if code type is Legacy or HP.
+ * 0x00: Okay to modify
+ * 0x01: FCODE. Do not modify
+ * 0x03: Okay to modify
+ * 0x04-0xFF: Do not modify
+ */
+ if (pcir_header->code_type == CXGB4_HDR_CODE1) {
+ u8 csum = 0;
+ int i;
+
+ /**
+ * Modify Device ID to match current adatper
+ */
+ pcir_header->device_id = cpu_to_le16(device_id);
+
+ /**
+ * Set checksum temporarily to 0.
+ * We will recalculate it later.
+ */
+ header->cksum = 0x0;
+
+ /**
+ * Calculate and update checksum
+ */
+ for (i = 0; i < (header->size512 * 512); i++)
+ csum += cur_header[i];
+
+ /**
+ * Invert summed value to create the checksum
+ * Writing new checksum value directly to the boot data
+ */
+ cur_header[7] = -csum;
+
+ } else if (pcir_header->code_type == CXGB4_HDR_CODE2) {
+ /**
+ * Modify Device ID to match current adatper
+ */
+ pcir_header->device_id = cpu_to_le16(device_id);
+ }
+
+ /**
+ * Move header pointer up to the next image in the ROM.
+ */
+ cur_header += header->size512 * 512;
+ } while (!(pcir_header->indicator & CXGB4_HDR_INDI));
+}
+
+/**
+ * t4_load_boot - download boot flash
+ * @adapter: the adapter
+ * @boot_data: the boot image to write
+ * @boot_addr: offset in flash to write boot_data
+ * @size: image size
+ *
+ * Write the supplied boot image to the card's serial flash.
+ * The boot image has the following sections: a 28-byte header and the
+ * boot image.
+ */
+int t4_load_boot(struct adapter *adap, u8 *boot_data,
+ unsigned int boot_addr, unsigned int size)
+{
+ unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
+ unsigned int boot_sector = (boot_addr * 1024);
+ struct cxgb4_pci_exp_rom_header *header;
+ struct cxgb4_pcir_data *pcir_header;
+ int pcir_offset;
+ unsigned int i;
+ u16 device_id;
+ int ret, addr;
+
+ /**
+ * Make sure the boot image does not encroach on the firmware region
+ */
+ if ((boot_sector + size) >> 16 > FLASH_FW_START_SEC) {
+ dev_err(adap->pdev_dev, "boot image encroaching on firmware region\n");
+ return -EFBIG;
+ }
+
+ /* Get boot header */
+ header = (struct cxgb4_pci_exp_rom_header *)boot_data;
+ pcir_offset = le16_to_cpu(header->pcir_offset);
+ /* PCIR Data Structure */
+ pcir_header = (struct cxgb4_pcir_data *)&boot_data[pcir_offset];
+
+ /**
+ * Perform some primitive sanity testing to avoid accidentally
+ * writing garbage over the boot sectors. We ought to check for
+ * more but it's not worth it for now ...
+ */
+ if (size < BOOT_MIN_SIZE || size > BOOT_MAX_SIZE) {
+ dev_err(adap->pdev_dev, "boot image too small/large\n");
+ return -EFBIG;
+ }
+
+ if (le16_to_cpu(header->signature) != BOOT_SIGNATURE) {
+ dev_err(adap->pdev_dev, "Boot image missing signature\n");
+ return -EINVAL;
+ }
+
+ /* Check PCI header signature */
+ if (le32_to_cpu(pcir_header->signature) != PCIR_SIGNATURE) {
+ dev_err(adap->pdev_dev, "PCI header missing signature\n");
+ return -EINVAL;
+ }
+
+ /* Check Vendor ID matches Chelsio ID*/
+ if (le16_to_cpu(pcir_header->vendor_id) != PCI_VENDOR_ID_CHELSIO) {
+ dev_err(adap->pdev_dev, "Vendor ID missing signature\n");
+ return -EINVAL;
+ }
+
+ /**
+ * The boot sector is comprised of the Expansion-ROM boot, iSCSI boot,
+ * and Boot configuration data sections. These 3 boot sections span
+ * sectors 0 to 7 in flash and live right before the FW image location.
+ */
+ i = DIV_ROUND_UP(size ? size : FLASH_FW_START, sf_sec_size);
+ ret = t4_flash_erase_sectors(adap, boot_sector >> 16,
+ (boot_sector >> 16) + i - 1);
+
+ /**
+ * If size == 0 then we're simply erasing the FLASH sectors associated
+ * with the on-adapter option ROM file
+ */
+ if (ret || size == 0)
+ goto out;
+ /* Retrieve adapter's device ID */
+ pci_read_config_word(adap->pdev, PCI_DEVICE_ID, &device_id);
+ /* Want to deal with PF 0 so I strip off PF 4 indicator */
+ device_id = device_id & 0xf0ff;
+
+ /* Check PCIE Device ID */
+ if (le16_to_cpu(pcir_header->device_id) != device_id) {
+ /**
+ * Change the device ID in the Boot BIOS image to match
+ * the Device ID of the current adapter.
+ */
+ modify_device_id(device_id, boot_data);
+ }
+
+ /**
+ * Skip over the first SF_PAGE_SIZE worth of data and write it after
+ * we finish copying the rest of the boot image. This will ensure
+ * that the BIOS boot header will only be written if the boot image
+ * was written in full.
+ */
+ addr = boot_sector;
+ for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
+ addr += SF_PAGE_SIZE;
+ boot_data += SF_PAGE_SIZE;
+ ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, boot_data);
+ if (ret)
+ goto out;
+ }
+
+ ret = t4_write_flash(adap, boot_sector, SF_PAGE_SIZE,
+ (const u8 *)header);
+
+out:
+ if (ret)
+ dev_err(adap->pdev_dev, "boot image load failed, error %d\n",
+ ret);
+ return ret;
+}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index bb89d3be360b..065c01c654ff 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -563,6 +563,12 @@
#define AIVEC_V(x) ((x) << AIVEC_S)
#define PCIE_PF_CLI_A 0x44
+
+#define PCIE_PF_EXPROM_OFST_A 0x4c
+#define OFFSET_S 10
+#define OFFSET_M 0x3fffU
+#define OFFSET_G(x) (((x) >> OFFSET_S) & OFFSET_M)
+
#define PCIE_INT_CAUSE_A 0x3004
#define UNXSPLCPLERR_S 29
--
2.18.2
^ permalink raw reply related
* [PATCH net-next 2/5] cxgb4: add support to flash PHY image
From: Vishal Kulkarni @ 2020-06-17 6:29 UTC (permalink / raw)
To: netdev, davem; +Cc: nirranjan, dt, Vishal Kulkarni
In-Reply-To: <20200617062907.26121-1-vishal@chelsio.com>
Update set_flash to flash PHY image to flash region
Signed-off-by: Vishal Kulkarni <vishal@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 +
.../ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 39 +++++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 4b4168c77039..cc76983130cc 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -141,6 +141,7 @@ enum cc_fec {
enum {
CXGB4_ETHTOOL_FLASH_FW = 1,
+ CXGB4_ETHTOOL_FLASH_PHY = 2,
};
struct port_stats {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
index 46c70feb5fdc..4a72f481c4c0 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
@@ -28,6 +28,7 @@ static void set_msglevel(struct net_device *dev, u32 val)
static const char * const flash_region_strings[] = {
"All",
"Firmware",
+ "PHY Firmware",
};
static const char stats_strings[][ETH_GSTRING_LEN] = {
@@ -1242,6 +1243,39 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
return err;
}
+#define CXGB4_PHY_SIG 0x130000ea
+
+static int cxgb4_validate_phy_image(const u8 *data, u32 *size)
+{
+ struct cxgb4_fw_data *header;
+
+ header = (struct cxgb4_fw_data *)data;
+ if (be32_to_cpu(header->signature) != CXGB4_PHY_SIG)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int cxgb4_ethtool_flash_phy(struct net_device *netdev,
+ const u8 *data, u32 size)
+{
+ struct adapter *adap = netdev2adap(netdev);
+ int ret;
+
+ ret = cxgb4_validate_phy_image(data, NULL);
+ if (ret) {
+ dev_err(adap->pdev_dev, "PHY signature mismatch\n");
+ return ret;
+ }
+
+ ret = t4_load_phy_fw(adap, MEMWIN_NIC, &adap->win0_lock,
+ NULL, data, size);
+ if (ret)
+ dev_err(adap->pdev_dev, "Failed to load PHY FW\n");
+
+ return ret;
+}
+
static int cxgb4_ethtool_flash_fw(struct net_device *netdev,
const u8 *data, u32 size)
{
@@ -1275,6 +1309,9 @@ static int cxgb4_ethtool_flash_region(struct net_device *netdev,
case CXGB4_ETHTOOL_FLASH_FW:
ret = cxgb4_ethtool_flash_fw(netdev, data, size);
break;
+ case CXGB4_ETHTOOL_FLASH_PHY:
+ ret = cxgb4_ethtool_flash_phy(netdev, data, size);
+ break;
default:
ret = -EOPNOTSUPP;
break;
@@ -1308,6 +1345,8 @@ static int cxgb4_ethtool_get_flash_region(const u8 *data, u32 *size)
{
if (!cxgb4_validate_fw_image(data, size))
return CXGB4_ETHTOOL_FLASH_FW;
+ if (!cxgb4_validate_phy_image(data, size))
+ return CXGB4_ETHTOOL_FLASH_PHY;
return -EOPNOTSUPP;
}
--
2.18.2
^ permalink raw reply related
* [PATCH net-next 1/5] cxgb4: update set_flash to flash different images
From: Vishal Kulkarni @ 2020-06-17 6:29 UTC (permalink / raw)
To: netdev, davem; +Cc: nirranjan, dt, Vishal Kulkarni
In-Reply-To: <20200617062907.26121-1-vishal@chelsio.com>
Chelsio adapter contains different flash regions and each
region is used by different binary files. This patch adds
support to flash images like PHY firmware, boot and boot config
using ethtool -f N.
The N value mapping is as follows.
N = 0 : Parse image and decide which region to flash
N = 1 : Firmware
N = 2 : PHY firmware
N = 3 : boot image
N = 4 : boot cfg
Signed-off-by: Vishal Kulkarni <vishal@chelsio.com>"
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 9 ++
.../ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 121 +++++++++++++++---
2 files changed, 115 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 116df23ee927..4b4168c77039 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -139,6 +139,10 @@ enum cc_fec {
FEC_BASER_RS = 1 << 2 /* BaseR/Reed-Solomon */
};
+enum {
+ CXGB4_ETHTOOL_FLASH_FW = 1,
+};
+
struct port_stats {
u64 tx_octets; /* total # of octets in good frames */
u64 tx_frames; /* all good frames */
@@ -492,6 +496,11 @@ struct trace_params {
unsigned char port;
};
+struct cxgb4_fw_data {
+ __be32 signature;
+ __u8 reserved[4];
+};
+
/* Firmware Port Capabilities types. */
typedef u16 fw_port_cap16_t; /* 16-bit Port Capabilities integral value */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
index cb34628d5b0b..46c70feb5fdc 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
@@ -25,6 +25,11 @@ static void set_msglevel(struct net_device *dev, u32 val)
netdev2adap(dev)->msg_enable = val;
}
+static const char * const flash_region_strings[] = {
+ "All",
+ "Firmware",
+};
+
static const char stats_strings[][ETH_GSTRING_LEN] = {
"tx_octets_ok ",
"tx_frames_ok ",
@@ -1237,15 +1242,88 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
return err;
}
-static int set_flash(struct net_device *netdev, struct ethtool_flash *ef)
+static int cxgb4_ethtool_flash_fw(struct net_device *netdev,
+ const u8 *data, u32 size)
{
- int ret;
- const struct firmware *fw;
struct adapter *adap = netdev2adap(netdev);
unsigned int mbox = PCIE_FW_MASTER_M + 1;
- u32 pcie_fw;
+ int ret;
+
+ /* If the adapter has been fully initialized then we'll go ahead and
+ * try to get the firmware's cooperation in upgrading to the new
+ * firmware image otherwise we'll try to do the entire job from the
+ * host ... and we always "force" the operation in this path.
+ */
+ if (adap->flags & CXGB4_FULL_INIT_DONE)
+ mbox = adap->mbox;
+
+ ret = t4_fw_upgrade(adap, mbox, data, size, 1);
+ if (ret)
+ dev_err(adap->pdev_dev,
+ "Failed to flash firmware\n");
+
+ return ret;
+}
+
+static int cxgb4_ethtool_flash_region(struct net_device *netdev,
+ const u8 *data, u32 size, u32 region)
+{
+ struct adapter *adap = netdev2adap(netdev);
+ int ret;
+
+ switch (region) {
+ case CXGB4_ETHTOOL_FLASH_FW:
+ ret = cxgb4_ethtool_flash_fw(netdev, data, size);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ if (!ret)
+ dev_info(adap->pdev_dev,
+ "loading %s successful, reload cxgb4 driver\n",
+ flash_region_strings[region]);
+ return ret;
+}
+
+#define CXGB4_FW_SIG 0x4368656c
+#define CXGB4_FW_SIG_OFFSET 0x160
+
+static int cxgb4_validate_fw_image(const u8 *data, u32 *size)
+{
+ struct cxgb4_fw_data *header;
+
+ header = (struct cxgb4_fw_data *)&data[CXGB4_FW_SIG_OFFSET];
+ if (be32_to_cpu(header->signature) != CXGB4_FW_SIG)
+ return -EINVAL;
+
+ if (size)
+ *size = be16_to_cpu(((struct fw_hdr *)data)->len512) * 512;
+
+ return 0;
+}
+
+static int cxgb4_ethtool_get_flash_region(const u8 *data, u32 *size)
+{
+ if (!cxgb4_validate_fw_image(data, size))
+ return CXGB4_ETHTOOL_FLASH_FW;
+
+ return -EOPNOTSUPP;
+}
+
+static int set_flash(struct net_device *netdev, struct ethtool_flash *ef)
+{
+ struct adapter *adap = netdev2adap(netdev);
+ const struct firmware *fw;
unsigned int master;
u8 master_vld = 0;
+ const u8 *fw_data;
+ size_t fw_size;
+ u32 size = 0;
+ u32 pcie_fw;
+ int region;
+ int ret;
pcie_fw = t4_read_reg(adap, PCIE_FW_A);
master = PCIE_FW_MASTER_G(pcie_fw);
@@ -1263,19 +1341,32 @@ static int set_flash(struct net_device *netdev, struct ethtool_flash *ef)
if (ret < 0)
return ret;
- /* If the adapter has been fully initialized then we'll go ahead and
- * try to get the firmware's cooperation in upgrading to the new
- * firmware image otherwise we'll try to do the entire job from the
- * host ... and we always "force" the operation in this path.
- */
- if (adap->flags & CXGB4_FULL_INIT_DONE)
- mbox = adap->mbox;
+ fw_data = fw->data;
+ fw_size = fw->size;
+ if (ef->region == ETHTOOL_FLASH_ALL_REGIONS) {
+ while (fw_size > 0) {
+ size = 0;
+ region = cxgb4_ethtool_get_flash_region(fw_data, &size);
+ if (region < 0 || !size) {
+ ret = region;
+ goto out_free_fw;
+ }
+
+ ret = cxgb4_ethtool_flash_region(netdev, fw_data, size,
+ region);
+ if (ret)
+ goto out_free_fw;
+
+ fw_data += size;
+ fw_size -= size;
+ }
+ } else {
+ ret = cxgb4_ethtool_flash_region(netdev, fw_data, fw_size,
+ ef->region);
+ }
- ret = t4_fw_upgrade(adap, mbox, fw->data, fw->size, 1);
+out_free_fw:
release_firmware(fw);
- if (!ret)
- dev_info(adap->pdev_dev,
- "loaded firmware %s, reload cxgb4 driver\n", ef->data);
return ret;
}
--
2.18.2
^ permalink raw reply related
* [PATCH net-next 0/5] cxgb4: add support to read/write flash
From: Vishal Kulkarni @ 2020-06-17 6:29 UTC (permalink / raw)
To: netdev, davem; +Cc: nirranjan, dt, Vishal Kulkarni
This series of patches adds support to read/write different binary images
of serial flash present in Chelsio terminator.
Vishal Kulkarni (5):
cxgb4: update set_flash to flash different images
cxgb4: add support to flash PHY image
cxgb4: add support to flash boot image
cxgb4: add support to flash boot cfg image
cxgb4: add support to read serial flash
drivers/net/ethernet/chelsio/cxgb4/cudbg_if.h | 3 +-
.../net/ethernet/chelsio/cxgb4/cudbg_lib.c | 38 +++
.../net/ethernet/chelsio/cxgb4/cudbg_lib.h | 4 +-
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 67 +++++
.../net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c | 14 +
.../net/ethernet/chelsio/cxgb4/cxgb4_cudbg.h | 1 +
.../ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 244 ++++++++++++++-
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 279 ++++++++++++++++++
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 6 +
9 files changed, 640 insertions(+), 16 deletions(-)
--
2.18.2
^ permalink raw reply
* RE: [PATCH bpf] devmap: use bpf_map_area_alloc() for allocating hash buckets
From: John Fastabend @ 2020-06-17 6:06 UTC (permalink / raw)
To: Toke Høiland-Jørgensen, daniel, ast
Cc: Toke Høiland-Jørgensen, bpf, netdev, Xiumei Mu
In-Reply-To: <20200616142829.114173-1-toke@redhat.com>
Toke Høiland-Jørgensen wrote:
> Syzkaller discovered that creating a hash of type devmap_hash with a large
> number of entries can hit the memory allocator limit for allocating
> contiguous memory regions. There's really no reason to use kmalloc_array()
> directly in the devmap code, so just switch it to the existing
> bpf_map_area_alloc() function that is used elsewhere.
>
> Reported-by: Xiumei Mu <xmu@redhat.com>
> Fixes: 6f9d451ab1a3 ("xdp: Add devmap_hash map type for looking up devices by hashed index")
> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
> ---
> kernel/bpf/devmap.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
Acked-by: John Fastabend <john.fastabend@gmail.com>
^ permalink raw reply
* Re: [PATCH bpf] xdp: handle frame_sz in xdp_convert_zc_to_xdp_frame()
From: John Fastabend @ 2020-06-17 6:02 UTC (permalink / raw)
To: Jesper Dangaard Brouer, Hangbin Liu
Cc: netdev, bpf, Toke Høiland-Jørgensen, Daniel Borkmann,
Alexei Starovoitov, brouer
In-Reply-To: <20200616171233.1579d079@carbon>
Jesper Dangaard Brouer wrote:
> On Tue, 16 Jun 2020 18:35:18 +0800
> Hangbin Liu <liuhangbin@gmail.com> wrote:
>
> > In commit 34cc0b338a61 we only handled the frame_sz in convert_to_xdp_frame().
> > This patch will also handle frame_sz in xdp_convert_zc_to_xdp_frame().
> >
> > Fixes: 34cc0b338a61 ("xdp: Xdp_frame add member frame_sz and handle in convert_to_xdp_frame")
> > Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
>
> Thanks for spotting and fixing this! :-)
>
> Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
>
Acked-by: John Fastabend <john.fastabend@gmail.com>
^ permalink raw reply
* Re: [PATCH net v4 0/3] esp, ah: improve crypto algorithm selections
From: Steffen Klassert @ 2020-06-17 5:58 UTC (permalink / raw)
To: Eric Biggers
Cc: netdev, linux-crypto, Corentin Labbe, Greg Kroah-Hartman,
Herbert Xu
In-Reply-To: <20200610161437.4290-1-ebiggers@kernel.org>
On Wed, Jun 10, 2020 at 09:14:34AM -0700, Eric Biggers wrote:
> This series consolidates and modernizes the lists of crypto algorithms
> that are selected by the IPsec kconfig options, and adds CRYPTO_SEQIV
> since it no longer gets selected automatically by other things.
>
> See previous discussion at
> https://lkml.kernel.org/netdev/20200604192322.22142-1-ebiggers@kernel.org/T/#u
>
> Changed v3 => v4:
> - Don't say that AH is "NOT RECOMMENDED" by RFC 8221.
> - Updated commit messages (added Acked-by tags, fixed a bad Fixes tag,
> added some more explanation to patch 3).
Series applied to the ipsec tree, thanks a lot Eric!
^ permalink raw reply
* net-next is OPEN...
From: David Miller @ 2020-06-17 5:43 UTC (permalink / raw)
To: netdev
Roses are red
Violets are blue
We're taking bug fixes
And new features too
^ permalink raw reply
* [PATCH v2 02/02] net: phy: marvell: Add Marvell 88E1548 support
From: Maxim Kochetkov @ 2020-06-17 4:52 UTC (permalink / raw)
To: netdev; +Cc: andrew, f.fainelli, hkallweit1, linux
Add Marvell 88E1548 support
Signed-off-by: Maxim Kochetkov <fido_max@inbox.ru>
---
drivers/net/phy/marvell.c | 24 ++++++++++++++++++++++++
include/linux/marvell_phy.h | 1 +
2 files changed, 25 insertions(+)
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 4cc4e25fed2d..f0d4ca87e4bc 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -2481,6 +2481,29 @@ static struct phy_driver marvell_drivers[] = {
.get_tunable = m88e1540_get_tunable,
.set_tunable = m88e1540_set_tunable,
},
+ {
+ .phy_id = MARVELL_PHY_ID_88E1548,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .name = "Marvell 88E1548P",
+ .probe = m88e1510_probe,
+ .features = PHY_GBIT_FIBRE_FEATURES,
+ .config_init = &marvell_config_init,
+ .config_aneg = &m88e1510_config_aneg,
+ .read_status = &marvell_read_status,
+ .ack_interrupt = &marvell_ack_interrupt,
+ .config_intr = &marvell_config_intr,
+ .did_interrupt = &m88e1121_did_interrupt,
+ .resume = &genphy_resume,
+ .suspend = &genphy_suspend,
+ .read_page = marvell_read_page,
+ .write_page = marvell_write_page,
+ .get_sset_count = marvell_get_sset_count,
+ .get_strings = marvell_get_strings,
+ .get_stats = marvell_get_stats,
+ .get_tunable = m88e1540_get_tunable,
+ .set_tunable = m88e1540_set_tunable,
+ },
+
};
module_phy_driver(marvell_drivers);
@@ -2502,6 +2525,7 @@ static struct mdio_device_id __maybe_unused
marvell_tbl[] = {
{ MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK },
{ MARVELL_PHY_ID_88E6390, MARVELL_PHY_ID_MASK },
{ MARVELL_PHY_ID_88E1340S, MARVELL_PHY_ID_MASK },
+ { MARVELL_PHY_ID_88E1548, MARVELL_PHY_ID_MASK },
{ }
};
diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h
index 39e8c382defb..3d8249c3e31d 100644
--- a/include/linux/marvell_phy.h
+++ b/include/linux/marvell_phy.h
@@ -20,6 +20,7 @@
#define MARVELL_PHY_ID_88E1510 0x01410dd0
#define MARVELL_PHY_ID_88E1540 0x01410eb0
#define MARVELL_PHY_ID_88E1545 0x01410ea0
+#define MARVELL_PHY_ID_88E1548 0x01410ec0
#define MARVELL_PHY_ID_88E3016 0x01410e60
#define MARVELL_PHY_ID_88X3310 0x002b09a0
#define MARVELL_PHY_ID_88E2110 0x002b09b0
--
2.25.1
^ permalink raw reply related
* [PATCH v2 01/02] net: phy: marvell: Add Marvell 88E1340 support
From: Maxim Kochetkov @ 2020-06-17 4:52 UTC (permalink / raw)
To: netdev; +Cc: andrew, f.fainelli, hkallweit1, linux
Add Marvell 88E1340 support
Signed-off-by: Maxim Kochetkov <fido_max@inbox.ru>
---
drivers/net/phy/marvell.c | 23 +++++++++++++++++++++++
include/linux/marvell_phy.h | 1 +
2 files changed, 24 insertions(+)
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 7fc8e10c5f33..4cc4e25fed2d 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -2459,6 +2459,28 @@ static struct phy_driver marvell_drivers[] = {
.get_tunable = m88e1540_get_tunable,
.set_tunable = m88e1540_set_tunable,
},
+ {
+ .phy_id = MARVELL_PHY_ID_88E1340S,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .name = "Marvell 88E1340S",
+ .probe = m88e1510_probe,
+ /* PHY_GBIT_FEATURES */
+ .config_init = &marvell_config_init,
+ .config_aneg = &m88e1510_config_aneg,
+ .read_status = &marvell_read_status,
+ .ack_interrupt = &marvell_ack_interrupt,
+ .config_intr = &marvell_config_intr,
+ .did_interrupt = &m88e1121_did_interrupt,
+ .resume = &genphy_resume,
+ .suspend = &genphy_suspend,
+ .read_page = marvell_read_page,
+ .write_page = marvell_write_page,
+ .get_sset_count = marvell_get_sset_count,
+ .get_strings = marvell_get_strings,
+ .get_stats = marvell_get_stats,
+ .get_tunable = m88e1540_get_tunable,
+ .set_tunable = m88e1540_set_tunable,
+ },
};
module_phy_driver(marvell_drivers);
@@ -2479,6 +2501,7 @@ static struct mdio_device_id __maybe_unused
marvell_tbl[] = {
{ MARVELL_PHY_ID_88E1545, MARVELL_PHY_ID_MASK },
{ MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK },
{ MARVELL_PHY_ID_88E6390, MARVELL_PHY_ID_MASK },
+ { MARVELL_PHY_ID_88E1340S, MARVELL_PHY_ID_MASK },
{ }
};
diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h
index af6b11d4d673..39e8c382defb 100644
--- a/include/linux/marvell_phy.h
+++ b/include/linux/marvell_phy.h
@@ -15,6 +15,7 @@
#define MARVELL_PHY_ID_88E1149R 0x01410e50
#define MARVELL_PHY_ID_88E1240 0x01410e30
#define MARVELL_PHY_ID_88E1318S 0x01410e90
+#define MARVELL_PHY_ID_88E1340S 0x01410dc0
#define MARVELL_PHY_ID_88E1116R 0x01410e40
#define MARVELL_PHY_ID_88E1510 0x01410dd0
#define MARVELL_PHY_ID_88E1540 0x01410eb0
--
2.25.1
^ permalink raw reply related
* Re: [PATCH 01/02] net: phy: marvell: Add Marvell 88E1340 support
From: Maxim Kochetkov @ 2020-06-17 4:49 UTC (permalink / raw)
To: Andrew Lunn; +Cc: netdev, f.fainelli, hkallweit1, linux
In-Reply-To: <20200616145459.GA197468@lunn.ch>
Yes. This is 88E1340S. My mistake.
16.06.2020 17:54, Andrew Lunn wrote:
> On Tue, Jun 16, 2020 at 10:01:11AM +0300, Maxim Kochetkov wrote:
>> Add Marvell 88E1340 support
>
> Hi Maxim
>
> Are you sure this is an 88E1340, not a 88E1340S?
>
> Marvells DSDT SDK has:
>
> MAD_88E1340S = 0x1C, /* 88E1340S */
> MAD_88E1340 = 0x1e, /* 88E1340/x0a */
> MAD_88E1340M = 0x1f, /* 88E1340M/x0a */
>
>> #define MARVELL_PHY_ID_88E1149R 0x01410e50
>> #define MARVELL_PHY_ID_88E1240 0x01410e30
>> #define MARVELL_PHY_ID_88E1318S 0x01410e90
>> +#define MARVELL_PHY_ID_88E1340 0x01410dc0
>> #define MARVELL_PHY_ID_88E1116R 0x01410e40
>> #define MARVELL_PHY_ID_88E1510 0x01410dd0
>> #define MARVELL_PHY_ID_88E1540 0x01410eb0
>
> For 88E1340 i would expect the ID to be 0x01410de0
>
> Andrew
>
^ 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