Netdev List
 help / color / mirror / Atom feed
* Re: mv88e6xxx -- DSA support for Marvell 88e6065 switch (and maybe 88e6060?)
From: Andrew Lunn @ 2019-01-29 23:12 UTC (permalink / raw)
  To: Pavel Machek; +Cc: netdev, f.fainelli, buytenh, buytenh, nico
In-Reply-To: <20190129225732.GA11686@amd>

> Is someone is interested in getting 6060 to work with mv88e6xxx?

Vivien is. 

I also have a set of patches which modernize the driver. That might be
a step towards merging it in.

> @@ -2126,6 +2146,7 @@ static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
>  
>  	/* Upstream ports flood frames with unknown unicast or multicast DA */
>  	flood = dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port);
> +	flood = 1; /* This is strange, but original driver also sets flood everywhere */

This might be because the driver did not support hardware offload.
What happens if you don't have this?

> +static const struct mv88e6xxx_ops mv88e6065_ops = {
> +	/* MV88E6XXX_FAMILY_6095 */ /* Here */
> +  //.ieee_pri_map = mv88e6085_g1_ieee_pri_map, /* FIXME */
> +  //	.ip_pri_map = mv88e6085_g1_ip_pri_map, /* FIXME */
> +  //	.set_switch_mac = mv88e6xxx_g1_set_switch_mac, /* FIXME */

What you should do is see if the hardware supports these functions. If
it does not, simply leave it out of mv88e6065_ops. If it does have the
functionality, but needs a new implementation, add a mv88e6065_
version. In theory, nearly everything is optional. So you can start
simple and then add features.

	Andrew

^ permalink raw reply

* Re: [PATCH net] vhost: fix OOB in get_rx_bufs()
From: David Miller @ 2019-01-29 23:10 UTC (permalink / raw)
  To: mst; +Cc: jasowang, stefanha, kvm, virtualization, netdev, linux-kernel
In-Reply-To: <20190129175145-mutt-send-email-mst@kernel.org>

From: "Michael S. Tsirkin" <mst@redhat.com>
Date: Tue, 29 Jan 2019 17:54:44 -0500

> On Mon, Jan 28, 2019 at 10:54:44PM -0800, David Miller wrote:
>> From: Jason Wang <jasowang@redhat.com>
>> Date: Mon, 28 Jan 2019 15:05:05 +0800
>> 
>> > After batched used ring updating was introduced in commit e2b3b35eb989
>> > ("vhost_net: batch used ring update in rx"). We tend to batch heads in
>> > vq->heads for more than one packet. But the quota passed to
>> > get_rx_bufs() was not correctly limited, which can result a OOB write
>> > in vq->heads.
>> > 
>> >         headcount = get_rx_bufs(vq, vq->heads + nvq->done_idx,
>> >                     vhost_len, &in, vq_log, &log,
>> >                     likely(mergeable) ? UIO_MAXIOV : 1);
>> > 
>> > UIO_MAXIOV was still used which is wrong since we could have batched
>> > used in vq->heads, this will cause OOB if the next buffer needs more
>> > than 960 (1024 (UIO_MAXIOV) - 64 (VHOST_NET_BATCH)) heads after we've
>> > batched 64 (VHOST_NET_BATCH) heads:
>>  ...
>> > Fixing this by allocating UIO_MAXIOV + VHOST_NET_BATCH iovs for
>> > vhost-net. This is done through set the limitation through
>> > vhost_dev_init(), then set_owner can allocate the number of iov in a
>> > per device manner.
>> > 
>> > This fixes CVE-2018-16880.
>> > 
>> > Fixes: e2b3b35eb989 ("vhost_net: batch used ring update in rx")
>> > Signed-off-by: Jason Wang <jasowang@redhat.com>
>> 
>> Applied and queued up for -stable, thanks!
> 
> Wow it seems we are down to hours round time post to queue.
> It would be hard to keep up that rate generally.
> However, I am guessing this was already in downstreams, and it's a CVE,
> so I guess it's a no brainer and review wasn't really necessary - was
> that the idea? Just checking.

Yeah the CVE pushed my hand a little bit, and I knew I was going to send Linus
a pull request today because David Watson needs some TLS changes in net-next.

^ permalink raw reply

* mv88e6xxx -- DSA support for Marvell 88e6065 switch (and maybe 88e6060?)
From: Pavel Machek @ 2019-01-29 22:57 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, f.fainelli, buytenh, buytenh, nico
In-Reply-To: <20181118182053.GE7446@lunn.ch>


[-- Attachment #1.1: Type: text/plain, Size: 8160 bytes --]

Hi!

> > > > I'm trying to create support for Marvell 88e6065 switch... and it
> > > > seems like drivers/net/dsa supports everything, but this model.
> > > > 
> > > > Did someone work with this hardware before? Any idea if it would be
> > > > more suitable to support by existing 88e6060 code, or if 88e6xxx code
> > > > should serve as a base?
> > > 
> > > Hi Pavel
> > > 
> > > The 88e6xxx should be extended to support this. I think you will find
> > > a lot of the building blocks are already in the driver. Compare the
> > > various implementations of the functions in the mv88e6xxx_ops to what
> > > the datasheet says for the registers, and pick those that match.
> > 
> > Ok, so I played a bit.
> > 
> > It looks like e6065 has different register layout from those supported
> > by 6xxx, and is quite similar to e6060.
> 
> However, if you look in the mv88e6xxx, there are quite a few functions
> called mv88e6065_foo. Marvell keeps changing the register layout. When
> writing code, we try to name the functions based on which family of
> devices introduced those registers. But we don't have the whole
> history, so we probably have some names wrong.

Ok, so I took a long look at mv88e6xxx... and got it to work.

Good news is that modifications needed are not too heavy. Most are 
inlined below. (tag_daddr is still needed. I can send that too). 

Bad news is that only about half of all the registers are present on
6065 (6060 is similar), and I'm not sure how to do that
cleanly. Anything marked "W" is not present or reserved or different
in 6065. What would be good markup of registers that are common to all
and that are newer-generations-only be? Mark everything not present on
6065 as MV88E6085_*?

Is someone is interested in getting 6060 to work with mv88e6xxx?

Best regards,
									Pavel


commit b0a8ed2459b8bc1922441edb482d0c7a4217eb1f
Author: Pavel Machek <pavel@denx.de>
Date:   Mon Jan 28 15:12:30 2019 +0100

    6xxx: Add basic support for 6065.

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 33e99dfa00a8..0a1fc2432094 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2094,6 +2094,21 @@ static int mv88e6xxx_set_port_mode_edsa(struct mv88e6xxx_chip *chip, int port)
 				       ETH_P_EDSA);
 }
 
+static int mv88e6xxx_set_port_mode_header(struct mv88e6xxx_chip *chip, int port)
+{
+  	u16 reg;
+	int err;
+
+	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
+	if (err)
+		return err;
+
+	reg |= MV88E6XXX_PORT_CTL0_HEADER;
+	printk("port %d -- enabling header, val %lx\n", port, (unsigned long) reg);
+
+	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
+}
+
 static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)
 {
 	if (dsa_is_dsa_port(chip->ds, port))
@@ -2109,6 +2124,11 @@ static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)
 	if (chip->info->tag_protocol == DSA_TAG_PROTO_EDSA)
 		return mv88e6xxx_set_port_mode_edsa(chip, port);
 
+	if (chip->info->tag_protocol == DSA_TAG_PROTO_DADDR)
+		return mv88e6xxx_set_port_mode_header(chip, port);
+
+	dev_warn(chip->dev, "set port mode failed");
+
 	return -EINVAL;
 }
 
@@ -2126,6 +2146,7 @@ static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
 
 	/* Upstream ports flood frames with unknown unicast or multicast DA */
 	flood = dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port);
+	flood = 1; /* This is strange, but original driver also sets flood everywhere */
 	if (chip->info->ops->port_set_egress_floods)
 		return chip->info->ops->port_set_egress_floods(chip, port,
 							       flood, flood);
@@ -3777,7 +3798,58 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
 	.phylink_validate = mv88e6390x_phylink_validate,
 };
 
+static const struct mv88e6xxx_ops mv88e6065_ops = {
+	/* MV88E6XXX_FAMILY_6095 */ /* Here */
+  //.ieee_pri_map = mv88e6085_g1_ieee_pri_map, /* FIXME */
+  //	.ip_pri_map = mv88e6085_g1_ip_pri_map, /* FIXME */
+  //	.set_switch_mac = mv88e6xxx_g1_set_switch_mac, /* FIXME */
+  	.phy_read = mv88e6185_phy_ppu_read,
+  	.phy_write = mv88e6185_phy_ppu_write,
+  	.port_set_link = mv88e6xxx_port_set_link, /* ok */
+	.port_set_duplex = mv88e6xxx_port_set_duplex, /* ok */
+	.port_set_speed = mv88e6065_port_set_speed, /* ok */
+	.port_set_frame_mode = mv88e6065_port_set_frame_mode, // -- definitely not compatible on 6065; neccessary for correct operation? */
+	.port_set_egress_floods = mv88e6352_port_set_egress_floods, /* ok */
+	//.port_set_upstream_port = mv88e6095_port_set_upstream_port, /* FIXME */
+	.port_link_state = mv88e6352_port_link_state, /* FIXME -- this one is wrong, 6065 uses dufferebt bits */
+	//.port_get_cmode = mv88e6185_port_get_cmode, /* FIXME -- wrong bits */
+	//.stats_snapshot = mv88e6xxx_g1_stats_snapshot, /* FIXME */
+	//.stats_set_histogram = mv88e6095_g1_stats_set_histogram, /* FIXME */
+	//.stats_get_sset_count = mv88e6095_stats_get_sset_count, /* FIXME */
+	//.stats_get_strings = mv88e6095_stats_get_strings, /* FIXME */
+	//.stats_get_stats = mv88e6095_stats_get_stats, /* FIXME */
+	//.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu, /* FIXME */
+	//.ppu_enable = mv88e6185_g1_ppu_enable, /* FIXME */
+	//.ppu_disable = mv88e6185_g1_ppu_disable, /* FIXME */
+	.reset = NULL, /* No reset bit in global1: register 4, but we have MV88E6065_G1_RESET */
+	.vtu_getnext = mv88e6185_g1_vtu_getnext, /* ok? */
+	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, /* FIXME */
+	.phylink_validate = mv88e6065_phylink_validate,
+};
+
 static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+  	[MV88E6065] = {
+		.prod_num = 0x650,
+		.family = MV88E6XXX_FAMILY_6065,
+		.name = "Marvell 88E6065 not so hacked :-)",
+		.num_databases = 16,
+		.num_ports = 6,
+		.num_internal_phys = 6,
+		.max_vid = 4095,
+		.port_base_addr = 0x18,
+		.phy_base_addr = 0x10,
+		.global1_addr = 0x1f,
+		.global2_addr = 0,
+		.age_time_coeff = 15000,
+		.g1_irqs = 8,
+		.g2_irqs = 0,
+		.atu_move_port_mask = 0xf,
+		.pvt = false,
+		.multi_chip = true,
+		.tag_protocol = DSA_TAG_PROTO_DADDR,
+		.ops = &mv88e6065_ops,
+	},
+
 	[MV88E6085] = {
 		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6085,
 		.family = MV88E6XXX_FAMILY_6097,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index fc82085d4296..7d6c746d4b66 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -57,10 +57,12 @@ enum mv88e6xxx_frame_mode {
 	MV88E6XXX_FRAME_MODE_DSA,
 	MV88E6XXX_FRAME_MODE_PROVIDER,
 	MV88E6XXX_FRAME_MODE_ETHERTYPE,
+	MV88E6XXX_FRAME_MODE_HEADER,
 };
 
 /* List of supported models */
 enum mv88e6xxx_model {
+  	MV88E6065,
 	MV88E6085,
 	MV88E6095,
 	MV88E6097,
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 3f43c231f40b..cfa16b5fd41a 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -631,6 +631,31 @@ int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
 	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 }
 
+int mv88e6065_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
+				  enum mv88e6xxx_frame_mode mode)
+{
+  	int err;
+	u16 reg;
+
+	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
+	if (err)
+		return err;
+
+	reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
+
+	switch (mode) {
+	case MV88E6XXX_FRAME_MODE_NORMAL:
+	  /* FIXME ... ?  why is it needed */
+		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
+		break;
+	default:
+	  printk("Bad frame mode\n");
+		return -EINVAL;
+	}
+
+	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
+}
+
 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
 				  enum mv88e6xxx_frame_mode mode)
 {

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #1.2: delme2 --]
[-- Type: text/plain, Size: 35206 bytes --]

commit 58a8b67092027331b83311e5621e12870fef0845
Author: Pavel Machek <pavel@denx.de>
Date:   Mon Jan 28 14:59:36 2019 +0100

    6xxx: headers-only: anotate same and different registers on 6065.

diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
index 5df4fc049733..6d7c7868f7d8 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.h
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
@@ -18,15 +18,15 @@
 #include "chip.h"
 
 /* Offset 0x00: Switch Global Status Register */
-#define MV88E6XXX_G1_STS				0x00
-#define MV88E6352_G1_STS_PPU_STATE			0x8000
-#define MV88E6185_G1_STS_PPU_STATE_MASK			0xc000
-#define MV88E6185_G1_STS_PPU_STATE_DISABLED_RST		0x0000
-#define MV88E6185_G1_STS_PPU_STATE_INITIALIZING		0x4000
-#define MV88E6185_G1_STS_PPU_STATE_DISABLED		0x8000
-#define MV88E6185_G1_STS_PPU_STATE_POLLING		0xc000
-#define MV88E6XXX_G1_STS_INIT_READY			0x0800
-#define MV88E6XXX_G1_STS_IRQ_AVB			8
+#define MV88E6XXX_G1_STS				0x00 /* ok */
+#define MV88E6352_G1_STS_PPU_STATE			0x8000 
+#define MV88E6185_G1_STS_PPU_STATE_MASK			0xc000 W /* not on 6065 */
+#define MV88E6185_G1_STS_PPU_STATE_DISABLED_RST		0x0000 W
+#define MV88E6185_G1_STS_PPU_STATE_INITIALIZING		0x4000 W
+#define MV88E6185_G1_STS_PPU_STATE_DISABLED		0x8000 W
+#define MV88E6185_G1_STS_PPU_STATE_POLLING		0xc000 W
+#define MV88E6XXX_G1_STS_INIT_READY			0x0800 /* ok */
+#define MV88E6XXX_G1_STS_IRQ_AVB			8      /* ok vv */
 #define MV88E6XXX_G1_STS_IRQ_DEVICE			7
 #define MV88E6XXX_G1_STS_IRQ_STATS			6
 #define MV88E6XXX_G1_STS_IRQ_VTU_PROB			5
@@ -34,13 +34,13 @@
 #define MV88E6XXX_G1_STS_IRQ_ATU_PROB			3
 #define MV88E6XXX_G1_STS_IRQ_ATU_DONE			2
 #define MV88E6XXX_G1_STS_IRQ_TCAM_DONE			1
-#define MV88E6XXX_G1_STS_IRQ_EEPROM_DONE		0
+#define MV88E6XXX_G1_STS_IRQ_EEPROM_DONE		0      /* ok ^^ */
 
 /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1
  * Offset 0x02: Switch MAC Address Register Bytes 2 & 3
  * Offset 0x03: Switch MAC Address Register Bytes 4 & 5
  */
-#define MV88E6XXX_G1_MAC_01		0x01
+#define MV88E6XXX_G1_MAC_01		0x01 /* ok */
 #define MV88E6XXX_G1_MAC_23		0x02
 #define MV88E6XXX_G1_MAC_45		0x03
 
@@ -57,13 +57,13 @@
 
 /* Offset 0x04: Switch Global Control Register */
 #define MV88E6XXX_G1_CTL1			0x04
-#define MV88E6XXX_G1_CTL1_SW_RESET		0x8000
-#define MV88E6XXX_G1_CTL1_PPU_ENABLE		0x4000
-#define MV88E6352_G1_CTL1_DISCARD_EXCESS	0x2000
-#define MV88E6185_G1_CTL1_SCHED_PRIO		0x0800
-#define MV88E6185_G1_CTL1_MAX_FRAME_1632	0x0400
-#define MV88E6185_G1_CTL1_RELOAD_EEPROM		0x0200
-#define MV88E6XXX_G1_CTL1_DEVICE_EN		0x0080
+#define MV88E6XXX_G1_CTL1_SW_RESET		0x8000 W /* Not on 6065 */
+#define MV88E6XXX_G1_CTL1_PPU_ENABLE		0x4000 W /* Not on 6065 */
+#define MV88E6352_G1_CTL1_DISCARD_EXCESS	0x2000 /* ok */
+#define MV88E6185_G1_CTL1_SCHED_PRIO		0x0800 /* ok */
+#define MV88E6185_G1_CTL1_MAX_FRAME_1632	0x0400 /* ok */
+#define MV88E6185_G1_CTL1_RELOAD_EEPROM		0x0200 /* ok */ 
+#define MV88E6XXX_G1_CTL1_DEVICE_EN		0x0080 /* ?? vv */
 #define MV88E6XXX_G1_CTL1_STATS_DONE_EN		0x0040
 #define MV88E6XXX_G1_CTL1_VTU_PROBLEM_EN	0x0020
 #define MV88E6XXX_G1_CTL1_VTU_DONE_EN		0x0010
@@ -74,24 +74,24 @@
 
 /* Offset 0x05: VTU Operation Register */
 #define MV88E6XXX_G1_VTU_OP			0x05
-#define MV88E6XXX_G1_VTU_OP_BUSY		0x8000
-#define MV88E6XXX_G1_VTU_OP_MASK		0x7000
-#define MV88E6XXX_G1_VTU_OP_FLUSH_ALL		0x1000
+#define MV88E6XXX_G1_VTU_OP_BUSY		0x8000 /* ok */ 
+#define MV88E6XXX_G1_VTU_OP_MASK		0x7000 /* ok */ 
+#define MV88E6XXX_G1_VTU_OP_FLUSH_ALL		0x1000 /* ok vv */
 #define MV88E6XXX_G1_VTU_OP_NOOP		0x2000
 #define MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE	0x3000
-#define MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT	0x4000
-#define MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE	0x5000
-#define MV88E6XXX_G1_VTU_OP_STU_GET_NEXT	0x6000
-#define MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION	0x7000
-#define MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION	BIT(6)
-#define MV88E6XXX_G1_VTU_OP_MISS_VIOLATION	BIT(5)
-#define MV88E6XXX_G1_VTU_OP_SPID_MASK		0xf
+#define MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT	0x4000 /* ok ^^ */
+#define MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE	0x5000 W /* reserved on 6065 */
+#define MV88E6XXX_G1_VTU_OP_STU_GET_NEXT	0x6000 W /* reserved on 6065 */
+#define MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION	0x7000 /* ok */
+#define MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION	BIT(6) /* ok */
+#define MV88E6XXX_G1_VTU_OP_MISS_VIOLATION	BIT(5) /* ok */
+#define MV88E6XXX_G1_VTU_OP_SPID_MASK		0xf    /* ok */
 
 /* Offset 0x06: VTU VID Register */
 #define MV88E6XXX_G1_VTU_VID		0x06
 #define MV88E6XXX_G1_VTU_VID_MASK	0x0fff
-#define MV88E6390_G1_VTU_VID_PAGE	0x2000
-#define MV88E6XXX_G1_VTU_VID_VALID	0x1000
+#define MV88E6390_G1_VTU_VID_PAGE	0x2000 W /* not on 6065 */
+#define MV88E6XXX_G1_VTU_VID_VALID	0x1000 /* ok */
 
 /* Offset 0x07: VTU/STU Data Register 1
  * Offset 0x08: VTU/STU Data Register 2
@@ -99,7 +99,7 @@
  */
 #define MV88E6XXX_G1_VTU_DATA1				0x07
 #define MV88E6XXX_G1_VTU_DATA2				0x08
-#define MV88E6XXX_G1_VTU_DATA3				0x09
+#define MV88E6XXX_G1_VTU_DATA3				0x09 W /* reserved on 6065 */
 #define MV88E6XXX_G1_VTU_STU_DATA_MASK			0x0003
 #define MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED	0x0000
 #define MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNTAGGED	0x0001
@@ -113,12 +113,12 @@
 /* Offset 0x0A: ATU Control Register */
 #define MV88E6XXX_G1_ATU_CTL		0x0a
 #define MV88E6065_G1_RESET              0x8000
-#define MV88E6XXX_G1_ATU_CTL_LEARN2ALL	0x0008
+#define MV88E6XXX_G1_ATU_CTL_LEARN2ALL	0x0008 W /* reserved bit */
 
 /* Offset 0x0B: ATU Operation Register */
 #define MV88E6XXX_G1_ATU_OP				0x0b
-#define MV88E6XXX_G1_ATU_OP_BUSY			0x8000
-#define MV88E6XXX_G1_ATU_OP_MASK			0x7000
+#define MV88E6XXX_G1_ATU_OP_BUSY			0x8000 /* ok */
+#define MV88E6XXX_G1_ATU_OP_MASK			0x7000 /* ok vv */
 #define MV88E6XXX_G1_ATU_OP_NOOP			0x0000
 #define MV88E6XXX_G1_ATU_OP_FLUSH_MOVE_ALL		0x1000
 #define MV88E6XXX_G1_ATU_OP_FLUSH_MOVE_NON_STATIC	0x2000
@@ -126,18 +126,18 @@
 #define MV88E6XXX_G1_ATU_OP_GET_NEXT_DB			0x4000
 #define MV88E6XXX_G1_ATU_OP_FLUSH_MOVE_ALL_DB		0x5000
 #define MV88E6XXX_G1_ATU_OP_FLUSH_MOVE_NON_STATIC_DB	0x6000
-#define MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION		0x7000
+#define MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION		0x7000 
 #define MV88E6XXX_G1_ATU_OP_AGE_OUT_VIOLATION		BIT(7)
 #define MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION		BIT(6)
 #define MV88E6XXX_G1_ATU_OP_MISS_VIOLATION		BIT(5)
-#define MV88E6XXX_G1_ATU_OP_FULL_VIOLATION		BIT(4)
+#define MV88E6XXX_G1_ATU_OP_FULL_VIOLATION		BIT(4) /* ok ^^ */
 
 /* Offset 0x0C: ATU Data Register */
 #define MV88E6XXX_G1_ATU_DATA				0x0c
-#define MV88E6XXX_G1_ATU_DATA_TRUNK			0x8000
+#define MV88E6XXX_G1_ATU_DATA_TRUNK			0x8000 /* ??? */
 #define MV88E6XXX_G1_ATU_DATA_TRUNK_ID_MASK		0x00f0
 #define MV88E6XXX_G1_ATU_DATA_PORT_VECTOR_MASK		0x3ff0
-#define MV88E6XXX_G1_ATU_DATA_STATE_MASK		0x000f
+#define MV88E6XXX_G1_ATU_DATA_STATE_MASK		0x000f /* ok */
 #define MV88E6XXX_G1_ATU_DATA_STATE_UNUSED		0x0000
 #define MV88E6XXX_G1_ATU_DATA_STATE_UC_MGMT		0x000d
 #define MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC		0x000e
@@ -151,7 +151,7 @@
  * Offset 0x0E: ATU MAC Address Register Bytes 2 & 3
  * Offset 0x0F: ATU MAC Address Register Bytes 4 & 5
  */
-#define MV88E6XXX_G1_ATU_MAC01		0x0d
+#define MV88E6XXX_G1_ATU_MAC01		0x0d /* ok */
 #define MV88E6XXX_G1_ATU_MAC23		0x0e
 #define MV88E6XXX_G1_ATU_MAC45		0x0f
 
@@ -164,7 +164,7 @@
  * Offset 0x16: IP-PRI Mapping Register 6
  * Offset 0x17: IP-PRI Mapping Register 7
  */
-#define MV88E6XXX_G1_IP_PRI_0	0x10
+#define MV88E6XXX_G1_IP_PRI_0	0x10 /* ok */
 #define MV88E6XXX_G1_IP_PRI_1	0x11
 #define MV88E6XXX_G1_IP_PRI_2	0x12
 #define MV88E6XXX_G1_IP_PRI_3	0x13
@@ -174,10 +174,10 @@
 #define MV88E6XXX_G1_IP_PRI_7	0x17
 
 /* Offset 0x18: IEEE-PRI Register */
-#define MV88E6XXX_G1_IEEE_PRI	0x18
+#define MV88E6XXX_G1_IEEE_PRI	0x18 /* ok */
 
 /* Offset 0x19: Core Tag Type */
-#define MV88E6185_G1_CORE_TAG_TYPE	0x19
+#define MV88E6185_G1_CORE_TAG_TYPE	0x19 W /* reserved on 6065 */
 
 /* Offset 0x1A: Monitor Control */
 #define MV88E6185_G1_MONITOR_CTL			0x1a
@@ -188,8 +188,8 @@
 #define MV88E6352_G1_MONITOR_CTL_MIRROR_DEST_MASK	0x000f
 
 /* Offset 0x1A: Monitor & MGMT Control Register */
-#define MV88E6390_G1_MONITOR_MGMT_CTL				0x1a
-#define MV88E6390_G1_MONITOR_MGMT_CTL_UPDATE			0x8000
+#define MV88E6390_G1_MONITOR_MGMT_CTL				0x1a  /* ok */
+#define MV88E6390_G1_MONITOR_MGMT_CTL_UPDATE			0x8000 W /* not on 6065 */
 #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_MASK			0x3f00
 #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C280000000XLO	0x0000
 #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C280000000XHI	0x0100
@@ -198,10 +198,10 @@
 #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST		0x2000
 #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST		0x2100
 #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST		0x3000
-#define MV88E6390_G1_MONITOR_MGMT_CTL_DATA_MASK			0x00ff
+#define MV88E6390_G1_MONITOR_MGMT_CTL_DATA_MASK			0x00ff W /* different on 6065 ? */
 
 /* Offset 0x1C: Global Control 2 */
-#define MV88E6XXX_G1_CTL2			0x1c
+#define MV88E6XXX_G1_CTL2			0x1c W /* different, mostly reserved on 6065 */
 #define MV88E6185_G1_CTL2_CASCADE_PORT_MASK	0xf000
 #define MV88E6185_G1_CTL2_CASCADE_PORT_NONE	0xe000
 #define MV88E6185_G1_CTL2_CASCADE_PORT_MULTI	0xf000
@@ -230,11 +230,11 @@
 #define MV88E6390_G1_CTL2_HIST_MODE_TX		0x0080
 #define MV88E6352_G1_CTL2_CTR_MODE_MASK		0x0060
 #define MV88E6390_G1_CTL2_CTR_MODE		0x0020
-#define MV88E6XXX_G1_CTL2_DEVICE_NUMBER_MASK	0x001f
+#define MV88E6XXX_G1_CTL2_DEVICE_NUMBER_MASK	0x001f W /* reserved on 6065 */
 
 /* Offset 0x1D: Stats Operation Register */
 #define MV88E6XXX_G1_STATS_OP			0x1d
-#define MV88E6XXX_G1_STATS_OP_BUSY		0x8000
+#define MV88E6XXX_G1_STATS_OP_BUSY		0x8000 /* ok */
 #define MV88E6XXX_G1_STATS_OP_NOP		0x0000
 #define MV88E6XXX_G1_STATS_OP_FLUSH_ALL		0x1000
 #define MV88E6XXX_G1_STATS_OP_FLUSH_PORT	0x2000
@@ -242,14 +242,14 @@
 #define MV88E6XXX_G1_STATS_OP_CAPTURE_PORT	0x5000
 #define MV88E6XXX_G1_STATS_OP_HIST_RX		0x0400
 #define MV88E6XXX_G1_STATS_OP_HIST_TX		0x0800
-#define MV88E6XXX_G1_STATS_OP_HIST_RX_TX	0x0c00
+#define MV88E6XXX_G1_STATS_OP_HIST_RX_TX	0x0c00 /* ok */
 #define MV88E6XXX_G1_STATS_OP_BANK_1_BIT_9	0x0200
 #define MV88E6XXX_G1_STATS_OP_BANK_1_BIT_10	0x0400
 
 /* Offset 0x1E: Stats Counter Register Bytes 3 & 2
  * Offset 0x1F: Stats Counter Register Bytes 1 & 0
  */
-#define MV88E6XXX_G1_STATS_COUNTER_32	0x1e
+#define MV88E6XXX_G1_STATS_COUNTER_32	0x1e /* ok */
 #define MV88E6XXX_G1_STATS_COUNTER_01	0x1f
 
 int mv88e6xxx_g1_read(struct mv88e6xxx_chip *chip, int reg, u16 *val);
diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
index 48e501d15e20..f5a52b7bfb12 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.h
+++ b/drivers/net/dsa/mv88e6xxx/global2.h
@@ -18,7 +18,7 @@
 #include "chip.h"
 
 /* Offset 0x00: Interrupt Source Register */
-#define MV88E6XXX_G2_INT_SRC			0x00 /* FIXME: reserved */
+#define MV88E6XXX_G2_INT_SRC			0x00 W /* reserved */
 #define MV88E6XXX_G2_INT_SRC_WDOG		0x8000
 #define MV88E6XXX_G2_INT_SRC_JAM_LIMIT		0x4000
 #define MV88E6XXX_G2_INT_SRC_DUPLEX_MISMATCH	0x2000
@@ -30,7 +30,7 @@
 #define MV88E6XXX_G2_INT_SOURCE_WATCHDOG	15
 
 /* Offset 0x01: Interrupt Mask Register */
-#define MV88E6XXX_G2_INT_MASK			0x01 /* FIXME: reserved */
+#define MV88E6XXX_G2_INT_MASK			0x01 W /* reserved */
 #define MV88E6XXX_G2_INT_MASK_WDOG		0x8000
 #define MV88E6XXX_G2_INT_MASK_JAM_LIMIT		0x4000
 #define MV88E6XXX_G2_INT_MASK_DUPLEX_MISMATCH	0x2000
@@ -40,16 +40,16 @@
 #define MV88E6390_G2_INT_MASK_PHY		0x07fe
 
 /* Offset 0x02: MGMT Enable Register 2x */
-#define MV88E6XXX_G2_MGMT_EN_2X		0x02 /* FIXME: reserved */
+#define MV88E6XXX_G2_MGMT_EN_2X		0x02 W /* reserved */
 
 /* Offset 0x03: MGMT Enable Register 0x */
-#define MV88E6XXX_G2_MGMT_EN_0X		0x03 /* FIXME: reserved */
+#define MV88E6XXX_G2_MGMT_EN_0X		0x03 W /* reserved */
 
 /* Offset 0x04: Flow Control Delay Register */
-#define MV88E6XXX_G2_FLOW_CTL	0x04 /* FIXME: reserved */
+#define MV88E6XXX_G2_FLOW_CTL	0x04 W /* reserved */
 
 /* Offset 0x05: Switch Management Register */
-#define MV88E6XXX_G2_SWITCH_MGMT			0x05 /* FIXME: reserved */
+#define MV88E6XXX_G2_SWITCH_MGMT			0x05 W /* reserved */
 #define MV88E6XXX_G2_SWITCH_MGMT_USE_DOUBLE_TAG_DATA	0x8000
 #define MV88E6XXX_G2_SWITCH_MGMT_PREVENT_LOOPS		0x4000
 #define MV88E6XXX_G2_SWITCH_MGMT_FLOW_CTL_MSG		0x2000
@@ -57,7 +57,7 @@
 #define MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU		0x0008
 
 /* Offset 0x06: Device Mapping Table Register */
-#define MV88E6XXX_G2_DEVICE_MAPPING		0x06 /* FIXME: reserved */
+#define MV88E6XXX_G2_DEVICE_MAPPING		0x06 W /* reserved */
 #define MV88E6XXX_G2_DEVICE_MAPPING_UPDATE	0x8000
 #define MV88E6XXX_G2_DEVICE_MAPPING_DEV_MASK	0x1f00
 #define MV88E6352_G2_DEVICE_MAPPING_PORT_MASK	0x000f
@@ -70,7 +70,7 @@
 #define MV88E6XXX_G2_TRUNK_MASK_HASH		0x0800
 
 /* Offset 0x08: Trunk Mapping Table Register */
-#define MV88E6XXX_G2_TRUNK_MAPPING		0x08 /* FIXME: reserved */
+#define MV88E6XXX_G2_TRUNK_MAPPING		0x08 W /* reserved */
 #define MV88E6XXX_G2_TRUNK_MAPPING_UPDATE	0x8000
 #define MV88E6XXX_G2_TRUNK_MAPPING_ID_MASK	0x7800
 
@@ -94,11 +94,11 @@
 #define MV88E6XXX_G2_IRL_CMD_REG_MASK		0x000f
 
 /* Offset 0x0A: Ingress Rate Data Register */
-#define MV88E6XXX_G2_IRL_DATA		0x0a
+#define MV88E6XXX_G2_IRL_DATA		0x0a /* ok */
 #define MV88E6XXX_G2_IRL_DATA_MASK	0xffff
 
 /* Offset 0x0B: Cross-chip Port VLAN Register */
-#define MV88E6XXX_G2_PVT_ADDR			0x0b
+#define MV88E6XXX_G2_PVT_ADDR			0x0b W /* reserved */
 #define MV88E6XXX_G2_PVT_ADDR_BUSY		0x8000
 #define MV88E6XXX_G2_PVT_ADDR_OP_MASK		0x7000
 #define MV88E6XXX_G2_PVT_ADDR_OP_INIT_ONES	0x1000
@@ -107,11 +107,11 @@
 #define MV88E6XXX_G2_PVT_ADDR_PTR_MASK		0x01ff
 
 /* Offset 0x0C: Cross-chip Port VLAN Data Register */
-#define MV88E6XXX_G2_PVT_DATA		0x0c
+#define MV88E6XXX_G2_PVT_DATA		0x0c W /* reserved */
 #define MV88E6XXX_G2_PVT_DATA_MASK	0x7f
 
 /* Offset 0x0D: Switch MAC/WoL/WoF Register */
-#define MV88E6XXX_G2_SWITCH_MAC			0x0d
+#define MV88E6XXX_G2_SWITCH_MAC			0x0d W /* reserved */
 #define MV88E6XXX_G2_SWITCH_MAC_UPDATE		0x8000
 #define MV88E6XXX_G2_SWITCH_MAC_PTR_MASK	0x1f00
 #define MV88E6XXX_G2_SWITCH_MAC_DATA_MASK	0x00ff
@@ -120,7 +120,7 @@
 #define MV88E6XXX_G2_ATU_STATS		0x0e
 
 /* Offset 0x0F: Priority Override Table */
-#define MV88E6XXX_G2_PRIO_OVERRIDE		0x0f
+#define MV88E6XXX_G2_PRIO_OVERRIDE		0x0f W /* reserved */
 #define MV88E6XXX_G2_PRIO_OVERRIDE_UPDATE	0x8000
 #define MV88E6XXX_G2_PRIO_OVERRIDE_FPRISET	0x1000
 #define MV88E6XXX_G2_PRIO_OVERRIDE_PTR_MASK	0x0f00
@@ -130,7 +130,7 @@
 #define MV88E6XXX_G2_PRIO_OVERRIDE_DATA_MASK	0x0007
 
 /* Offset 0x14: EEPROM Command */
-#define MV88E6XXX_G2_EEPROM_CMD			0x14
+#define MV88E6XXX_G2_EEPROM_CMD			0x14 W /* reserved */
 #define MV88E6XXX_G2_EEPROM_CMD_BUSY		0x8000
 #define MV88E6XXX_G2_EEPROM_CMD_OP_MASK		0x7000
 #define MV88E6XXX_G2_EEPROM_CMD_OP_WRITE	0x3000
@@ -142,15 +142,15 @@
 #define MV88E6390_G2_EEPROM_CMD_DATA_MASK	0x00ff
 
 /* Offset 0x15: EEPROM Data */
-#define MV88E6352_G2_EEPROM_DATA	0x15
+#define MV88E6352_G2_EEPROM_DATA	0x15 W /* reserved */
 #define MV88E6352_G2_EEPROM_DATA_MASK	0xffff
 
 /* Offset 0x15: EEPROM Addr */
-#define MV88E6390_G2_EEPROM_ADDR	0x15
+#define MV88E6390_G2_EEPROM_ADDR	0x15 W /* reserved */
 #define MV88E6390_G2_EEPROM_ADDR_MASK	0xffff
 
 /* Offset 0x16: AVB Command Register */
-#define MV88E6352_G2_AVB_CMD			0x16
+#define MV88E6352_G2_AVB_CMD			0x16 W /* reserved */
 #define MV88E6352_G2_AVB_CMD_BUSY		0x8000
 #define MV88E6352_G2_AVB_CMD_OP_READ		0x4000
 #define MV88E6352_G2_AVB_CMD_OP_READ_INCR	0x6000
@@ -173,10 +173,10 @@
 #define MV88E6352_G2_AVB_CMD_ADDR_MASK		0x001f
 
 /* Offset 0x17: AVB Data Register */
-#define MV88E6352_G2_AVB_DATA		0x17
+#define MV88E6352_G2_AVB_DATA		0x17 W /* reserved */
 
 /* Offset 0x18: SMI PHY Command Register */
-#define MV88E6XXX_G2_SMI_PHY_CMD			0x18
+#define MV88E6XXX_G2_SMI_PHY_CMD			0x18 W /* reserved */
 #define MV88E6XXX_G2_SMI_PHY_CMD_BUSY			0x8000
 #define MV88E6390_G2_SMI_PHY_CMD_FUNC_MASK		0x6000
 #define MV88E6390_G2_SMI_PHY_CMD_FUNC_INTERNAL		0x0000
@@ -197,16 +197,16 @@
 #define MV88E6XXX_G2_SMI_PHY_CMD_SETUP_PTR_MASK		0x03ff
 
 /* Offset 0x19: SMI PHY Data Register */
-#define MV88E6XXX_G2_SMI_PHY_DATA	0x19
+#define MV88E6XXX_G2_SMI_PHY_DATA	0x19 W /* reserved */
 
 /* Offset 0x1A: Scratch and Misc. Register */
-#define MV88E6XXX_G2_SCRATCH_MISC_MISC		0x1a
+#define MV88E6XXX_G2_SCRATCH_MISC_MISC		0x1a W /* reserved */
 #define MV88E6XXX_G2_SCRATCH_MISC_UPDATE	0x8000
 #define MV88E6XXX_G2_SCRATCH_MISC_PTR_MASK	0x7f00
 #define MV88E6XXX_G2_SCRATCH_MISC_DATA_MASK	0x00ff
 
 /* Offset 0x1B: Watch Dog Control Register */
-#define MV88E6352_G2_WDOG_CTL			0x1b
+#define MV88E6352_G2_WDOG_CTL			0x1b W /* reserved */
 #define MV88E6352_G2_WDOG_CTL_EGRESS_EVENT	0x0080
 #define MV88E6352_G2_WDOG_CTL_RMU_TIMEOUT	0x0040
 #define MV88E6352_G2_WDOG_CTL_QC_ENABLE		0x0020
@@ -217,7 +217,7 @@
 #define MV88E6352_G2_WDOG_CTL_SWRESET		0x0001
 
 /* Offset 0x1B: Watch Dog Control Register */
-#define MV88E6390_G2_WDOG_CTL				0x1b
+#define MV88E6390_G2_WDOG_CTL				0x1b W /* reserved */
 #define MV88E6390_G2_WDOG_CTL_UPDATE			0x8000
 #define MV88E6390_G2_WDOG_CTL_PTR_MASK			0x7f00
 #define MV88E6390_G2_WDOG_CTL_PTR_INT_SOURCE		0x0000
@@ -232,14 +232,14 @@
 #define MV88E6390_G2_WDOG_CTL_FORCE_IRQ			0x0001
 
 /* Offset 0x1C: QoS Weights Register */
-#define MV88E6XXX_G2_QOS_WEIGHTS		0x1c
+#define MV88E6XXX_G2_QOS_WEIGHTS		0x1c W /* reserved */
 #define MV88E6XXX_G2_QOS_WEIGHTS_UPDATE		0x8000
 #define MV88E6352_G2_QOS_WEIGHTS_PTR_MASK	0x3f00
 #define MV88E6390_G2_QOS_WEIGHTS_PTR_MASK	0x7f00
 #define MV88E6XXX_G2_QOS_WEIGHTS_DATA_MASK	0x00ff
 
 /* Offset 0x1D: Misc Register */
-#define MV88E6XXX_G2_MISC		0x1d
+#define MV88E6XXX_G2_MISC		0x1d W /* reserved */
 #define MV88E6XXX_G2_MISC_5_BIT_PORT	0x4000
 #define MV88E6352_G2_NOEGR_POLICY	0x2000
 #define MV88E6390_G2_LAG_ID_4		0x2000
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index f32f56af8e35..5b9dde5c3334 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -19,13 +19,13 @@
 
 /* Offset 0x00: Port Status Register */
 #define MV88E6XXX_PORT_STS			0x00
-#define MV88E6XXX_PORT_STS_PAUSE_EN		0x8000
+#define MV88E6XXX_PORT_STS_PAUSE_EN		0x8000 /* ok vvv */
 #define MV88E6XXX_PORT_STS_MY_PAUSE		0x4000
-#define MV88E6XXX_PORT_STS_HD_FLOW		0x2000
+#define MV88E6XXX_PORT_STS_HD_FLOW		0x2000 W /* "link mode is resolved" on 6065 */
 #define MV88E6XXX_PORT_STS_PHY_DETECT		0x1000
-#define MV88E6XXX_PORT_STS_LINK			0x0800
-#define MV88E6XXX_PORT_STS_DUPLEX		0x0400
-#define MV88E6XXX_PORT_STS_SPEED_MASK		0x0300
+#define MV88E6XXX_PORT_STS_LINK			0x0800 W /* -- 0x1000 on 6065? */
+#define MV88E6XXX_PORT_STS_DUPLEX		0x0400 W /* -- 0x200 on 6065*/
+#define MV88E6XXX_PORT_STS_SPEED_MASK		0x0300 W /* -- mask is 0x0f00 on 6065 */
 #define MV88E6XXX_PORT_STS_SPEED_10		0x0000
 #define MV88E6XXX_PORT_STS_SPEED_100		0x0100
 #define MV88E6XXX_PORT_STS_SPEED_1000		0x0200
@@ -33,38 +33,38 @@
 #define MV88E6352_PORT_STS_EEE			0x0040
 #define MV88E6165_PORT_STS_AM_DIS		0x0040
 #define MV88E6185_PORT_STS_MGMII		0x0040
-#define MV88E6XXX_PORT_STS_TX_PAUSED		0x0020
-#define MV88E6XXX_PORT_STS_FLOW_CTL		0x0010
-#define MV88E6XXX_PORT_STS_CMODE_MASK		0x000f
-#define MV88E6XXX_PORT_STS_CMODE_100BASE_X	0x0008
-#define MV88E6XXX_PORT_STS_CMODE_1000BASE_X	0x0009
-#define MV88E6XXX_PORT_STS_CMODE_SGMII		0x000a
-#define MV88E6XXX_PORT_STS_CMODE_2500BASEX	0x000b
-#define MV88E6XXX_PORT_STS_CMODE_XAUI		0x000c
-#define MV88E6XXX_PORT_STS_CMODE_RXAUI		0x000d
-#define MV88E6185_PORT_STS_CDUPLEX		0x0008
-#define MV88E6185_PORT_STS_CMODE_MASK		0x0007
-#define MV88E6185_PORT_STS_CMODE_GMII_FD	0x0000
-#define MV88E6185_PORT_STS_CMODE_MII_100_FD_PS	0x0001
-#define MV88E6185_PORT_STS_CMODE_MII_100	0x0002
-#define MV88E6185_PORT_STS_CMODE_MII_10		0x0003
-#define MV88E6185_PORT_STS_CMODE_SERDES		0x0004
-#define MV88E6185_PORT_STS_CMODE_1000BASE_X	0x0005
-#define MV88E6185_PORT_STS_CMODE_PHY		0x0006
-#define MV88E6185_PORT_STS_CMODE_DISABLED	0x0007
+#define MV88E6XXX_PORT_STS_TX_PAUSED		0x0020 /* ok */
+#define MV88E6XXX_PORT_STS_FLOW_CTL		0x0010 /* ok */
+#define MV88E6XXX_PORT_STS_CMODE_MASK		0x000f W /* vv these are reserved or different */
+#define MV88E6XXX_PORT_STS_CMODE_100BASE_X	0x0008 W
+#define MV88E6XXX_PORT_STS_CMODE_1000BASE_X	0x0009 W
+#define MV88E6XXX_PORT_STS_CMODE_SGMII		0x000a W
+#define MV88E6XXX_PORT_STS_CMODE_2500BASEX	0x000b W
+#define MV88E6XXX_PORT_STS_CMODE_XAUI		0x000c W
+#define MV88E6XXX_PORT_STS_CMODE_RXAUI		0x000d W
+#define MV88E6185_PORT_STS_CDUPLEX		0x0008 W
+#define MV88E6185_PORT_STS_CMODE_MASK		0x0007 W
+#define MV88E6185_PORT_STS_CMODE_GMII_FD	0x0000 W
+#define MV88E6185_PORT_STS_CMODE_MII_100_FD_PS	0x0001 W
+#define MV88E6185_PORT_STS_CMODE_MII_100	0x0002 W
+#define MV88E6185_PORT_STS_CMODE_MII_10		0x0003 W
+#define MV88E6185_PORT_STS_CMODE_SERDES		0x0004 W
+#define MV88E6185_PORT_STS_CMODE_1000BASE_X	0x0005 W
+#define MV88E6185_PORT_STS_CMODE_PHY		0x0006 W
+#define MV88E6185_PORT_STS_CMODE_DISABLED	0x0007 W /* ^^ */
 
 /* Offset 0x01: MAC (or PCS or Physical) Control Register */
 #define MV88E6XXX_PORT_MAC_CTL				0x01
-#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK	0x8000
-#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK	0x4000
-#define MV88E6185_PORT_MAC_CTL_SYNC_OK			0x4000
-#define MV88E6390_PORT_MAC_CTL_FORCE_SPEED		0x2000
-#define MV88E6390_PORT_MAC_CTL_ALTSPEED			0x1000
-#define MV88E6352_PORT_MAC_CTL_200BASE			0x1000
-#define MV88E6185_PORT_MAC_CTL_AN_EN			0x0400
-#define MV88E6185_PORT_MAC_CTL_AN_RESTART		0x0200
-#define MV88E6185_PORT_MAC_CTL_AN_DONE			0x0100
-#define MV88E6XXX_PORT_MAC_CTL_FC			0x0080
+#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK	0x8000 W /* vv reserved */
+#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK	0x4000 W
+#define MV88E6185_PORT_MAC_CTL_SYNC_OK			0x4000 W
+#define MV88E6390_PORT_MAC_CTL_FORCE_SPEED		0x2000 W
+#define MV88E6390_PORT_MAC_CTL_ALTSPEED			0x1000 W
+#define MV88E6352_PORT_MAC_CTL_200BASE			0x1000 W
+#define MV88E6185_PORT_MAC_CTL_AN_EN			0x0400 W
+#define MV88E6185_PORT_MAC_CTL_AN_RESTART		0x0200 W /* ^^ reserved */
+#define MV88E6185_PORT_MAC_CTL_AN_DONE			0x0100 W /* reserved on 6065 */
+#define MV88E6XXX_PORT_MAC_CTL_FC			0x0080 /* ok vv */
 #define MV88E6XXX_PORT_MAC_CTL_FORCE_FC			0x0040
 #define MV88E6XXX_PORT_MAC_CTL_LINK_UP			0x0020
 #define MV88E6XXX_PORT_MAC_CTL_FORCE_LINK		0x0010
@@ -76,15 +76,15 @@
 #define MV88E6065_PORT_MAC_CTL_SPEED_200		0x0002
 #define MV88E6XXX_PORT_MAC_CTL_SPEED_1000		0x0002
 #define MV88E6390_PORT_MAC_CTL_SPEED_10000		0x0003
-#define MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED		0x0003
+#define MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED		0x0003 /* ok ^^ */
 
 /* Offset 0x02: Jamming Control Register */
-#define MV88E6097_PORT_JAM_CTL			0x02
+#define MV88E6097_PORT_JAM_CTL			0x02 W /* Not on 6065 */
 #define MV88E6097_PORT_JAM_CTL_LIMIT_OUT_MASK	0xff00
 #define MV88E6097_PORT_JAM_CTL_LIMIT_IN_MASK	0x00ff
 
 /* Offset 0x02: Flow Control Register */
-#define MV88E6390_PORT_FLOW_CTL			0x02
+#define MV88E6390_PORT_FLOW_CTL			0x02 W
 #define MV88E6390_PORT_FLOW_CTL_UPDATE		0x8000
 #define MV88E6390_PORT_FLOW_CTL_PTR_MASK	0x7f00
 #define MV88E6390_PORT_FLOW_CTL_LIMIT_IN	0x0000
@@ -92,8 +92,10 @@
 #define MV88E6390_PORT_FLOW_CTL_DATA_MASK	0x00ff
 
 /* Offset 0x03: Switch Identifier Register */
-#define MV88E6XXX_PORT_SWITCH_ID		0x03
+#define MV88E6XXX_PORT_SWITCH_ID		0x03 /* ok */
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_MASK	0xfff0
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6035	0x0350 /* very similar to 6065 */
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6065	0x0650
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6085	0x04a0
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6095	0x0950
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6097	0x0990
@@ -124,132 +126,133 @@
 
 /* Offset 0x04: Port Control Register */
 #define MV88E6XXX_PORT_CTL0					0x04
-#define MV88E6XXX_PORT_CTL0_USE_CORE_TAG			0x8000
-#define MV88E6XXX_PORT_CTL0_DROP_ON_LOCK			0x4000
-#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK			0x3000
+#define MV88E6XXX_PORT_CTL0_USE_CORE_TAG			0x8000 W /* not on 6065, unused */
+#define MV88E6XXX_PORT_CTL0_DROP_ON_LOCK			0x4000 /* ...but this matches? */ 
+#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK			0x3000 /* ok, matches 6065 */
 #define MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED		0x0000
 #define MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED		0x1000
 #define MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED			0x2000
-#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA		0x3000
-#define MV88E6XXX_PORT_CTL0_HEADER				0x0800
-#define MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP			0x0400
-#define MV88E6XXX_PORT_CTL0_DOUBLE_TAG				0x0200
+#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA		0x3000 W /* not on 6065, unused */
+#define MV88E6XXX_PORT_CTL0_HEADER				0x0800 /* ok, matches 6065 */
+#define MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP			0x0400 /* ok */
+#define MV88E6XXX_PORT_CTL0_DOUBLE_TAG				0x0200 W /* not on 6065, unused */
 #define MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK			0x0300
 #define MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL			0x0000
-#define MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA			0x0100
-#define MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER			0x0200
+#define MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA			0x0100 
+#define MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER			0x0200 W /* not on 6065, not used  */
 #define MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA		0x0300
-#define MV88E6XXX_PORT_CTL0_DSA_TAG				0x0100
-#define MV88E6XXX_PORT_CTL0_VLAN_TUNNEL				0x0080
-#define MV88E6XXX_PORT_CTL0_TAG_IF_BOTH				0x0040
-#define MV88E6185_PORT_CTL0_USE_IP				0x0020
-#define MV88E6185_PORT_CTL0_USE_TAG				0x0010
+#define MV88E6XXX_PORT_CTL0_DSA_TAG				0x0100 W /* not on 6065, unused */
+#define MV88E6XXX_PORT_CTL0_VLAN_TUNNEL				0x0080 /* ok */
+#define MV88E6XXX_PORT_CTL0_TAG_IF_BOTH				0x0040 /* ok */
+#define MV88E6185_PORT_CTL0_USE_IP				0x0020 /* ok */
+#define MV88E6185_PORT_CTL0_USE_TAG				0x0010 /* ok */
 #define MV88E6185_PORT_CTL0_FORWARD_UNKNOWN			0x0004
-#define MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK			0x000c
+#define MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK			0x000c /* ok */
 #define MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA		0x0000
 #define MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA	0x0004
 #define MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA	0x0008
 #define MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA	0x000c
-#define MV88E6XXX_PORT_CTL0_STATE_MASK				0x0003
+#define MV88E6XXX_PORT_CTL0_STATE_MASK				0x0003 /* ok */
 #define MV88E6XXX_PORT_CTL0_STATE_DISABLED			0x0000
 #define MV88E6XXX_PORT_CTL0_STATE_BLOCKING			0x0001
 #define MV88E6XXX_PORT_CTL0_STATE_LEARNING			0x0002
 #define MV88E6XXX_PORT_CTL0_STATE_FORWARDING			0x0003
 
 /* Offset 0x05: Port Control 1 */
-#define MV88E6XXX_PORT_CTL1			0x05
+#define MV88E6XXX_PORT_CTL1			0x05 W /* undocumented / reserved */
 #define MV88E6XXX_PORT_CTL1_MESSAGE_PORT	0x8000
 #define MV88E6XXX_PORT_CTL1_FID_11_4_MASK	0x00ff
 
 /* Offset 0x06: Port Based VLAN Map */
 #define MV88E6XXX_PORT_BASE_VLAN		0x06
-#define MV88E6XXX_PORT_BASE_VLAN_FID_3_0_MASK	0xf000
+#define MV88E6XXX_PORT_BASE_VLAN_FID_3_0_MASK	0xf000 W /* 6065 has dbum there */
+/* ...and more bits below */
 
 /* Offset 0x07: Default Port VLAN ID & Priority */
 #define MV88E6XXX_PORT_DEFAULT_VLAN		0x07
-#define MV88E6XXX_PORT_DEFAULT_VLAN_MASK	0x0fff
+#define MV88E6XXX_PORT_DEFAULT_VLAN_MASK	0x0fff /* ok */
 
 /* Offset 0x08: Port Control 2 Register */
 #define MV88E6XXX_PORT_CTL2				0x08
-#define MV88E6XXX_PORT_CTL2_IGNORE_FCS			0x8000
+#define MV88E6XXX_PORT_CTL2_IGNORE_FCS			0x8000 /* ok vv */
 #define MV88E6XXX_PORT_CTL2_VTU_PRI_OVERRIDE		0x4000
 #define MV88E6XXX_PORT_CTL2_SA_PRIO_OVERRIDE		0x2000
-#define MV88E6XXX_PORT_CTL2_DA_PRIO_OVERRIDE		0x1000
-#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK		0x3000
-#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522		0x0000
-#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048		0x1000
-#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240		0x2000
-#define MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK		0x0c00
+#define MV88E6XXX_PORT_CTL2_DA_PRIO_OVERRIDE		0x1000 /* ok ?? */
+#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK		0x3000 W /* vv: incompatible */
+#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522		0x0000 W
+#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048		0x1000 W
+#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240		0x2000 W /* ^^ */
+#define MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK		0x0c00 /* ok vv */
 #define MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED		0x0000
 #define MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK		0x0400
 #define MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK		0x0800
 #define MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE		0x0c00
 #define MV88E6XXX_PORT_CTL2_DISCARD_TAGGED		0x0200
 #define MV88E6XXX_PORT_CTL2_DISCARD_UNTAGGED		0x0100
-#define MV88E6XXX_PORT_CTL2_MAP_DA			0x0080
-#define MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD		0x0040
-#define MV88E6XXX_PORT_CTL2_EGRESS_MONITOR		0x0020
-#define MV88E6XXX_PORT_CTL2_INGRESS_MONITOR		0x0010
-#define MV88E6095_PORT_CTL2_CPU_PORT_MASK		0x000f
+#define MV88E6XXX_PORT_CTL2_MAP_DA			0x0080 /* ok %% */
+#define MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD		0x0040 W /* reserved on 6065 */
+#define MV88E6XXX_PORT_CTL2_EGRESS_MONITOR		0x0020 W /* reserved on 6065 */
+#define MV88E6XXX_PORT_CTL2_INGRESS_MONITOR		0x0010 W /* reserved on 6065 */
+#define MV88E6095_PORT_CTL2_CPU_PORT_MASK		0x000f W /* 6065 has qpri overrides here */
 
 /* Offset 0x09: Egress Rate Control */
-#define MV88E6XXX_PORT_EGRESS_RATE_CTL1		0x09
+#define MV88E6XXX_PORT_EGRESS_RATE_CTL1		0x09 W /*  we have ingress control here */
 
 /* Offset 0x0A: Egress Rate Control 2 */
-#define MV88E6XXX_PORT_EGRESS_RATE_CTL2		0x0a
+#define MV88E6XXX_PORT_EGRESS_RATE_CTL2		0x0a W /* so this may not be compatible */
 
 /* Offset 0x0B: Port Association Vector */
 #define MV88E6XXX_PORT_ASSOC_VECTOR			0x0b
-#define MV88E6XXX_PORT_ASSOC_VECTOR_HOLD_AT_1		0x8000
-#define MV88E6XXX_PORT_ASSOC_VECTOR_INT_AGE_OUT		0x4000
-#define MV88E6XXX_PORT_ASSOC_VECTOR_LOCKED_PORT		0x2000
-#define MV88E6XXX_PORT_ASSOC_VECTOR_IGNORE_WRONG	0x1000
-#define MV88E6XXX_PORT_ASSOC_VECTOR_REFRESH_LOCKED	0x0800
+#define MV88E6XXX_PORT_ASSOC_VECTOR_HOLD_AT_1		0x8000 W /* 6065 is different -- Ingress monitor */
+#define MV88E6XXX_PORT_ASSOC_VECTOR_INT_AGE_OUT		0x4000 W /* portsched on 6065 */
+#define MV88E6XXX_PORT_ASSOC_VECTOR_LOCKED_PORT		0x2000 /* ok */
+#define MV88E6XXX_PORT_ASSOC_VECTOR_IGNORE_WRONG	0x1000 /* ok */
+#define MV88E6XXX_PORT_ASSOC_VECTOR_REFRESH_LOCKED	0x0800 W /* 6065 has agenten */
 
 /* Offset 0x0C: Port ATU Control */
-#define MV88E6XXX_PORT_ATU_CTL		0x0c
+#define MV88E6XXX_PORT_ATU_CTL		0x0c W /* not on 6065? */
 
 /* Offset 0x0D: Priority Override Register */
-#define MV88E6XXX_PORT_PRI_OVERRIDE	0x0d
+#define MV88E6XXX_PORT_PRI_OVERRIDE	0x0d W /* not on 6065? */
 
 /* Offset 0x0E: Policy Control Register */
-#define MV88E6XXX_PORT_POLICY_CTL	0x0e
+#define MV88E6XXX_PORT_POLICY_CTL	0x0e W /* not on 6065? */
 
 /* Offset 0x0F: Port Special Ether Type */
-#define MV88E6XXX_PORT_ETH_TYPE		0x0f
+#define MV88E6XXX_PORT_ETH_TYPE		0x0f W  /* not on 6065? */
 #define MV88E6XXX_PORT_ETH_TYPE_DEFAULT	0x9100
 
 /* Offset 0x10: InDiscards Low Counter */
-#define MV88E6XXX_PORT_IN_DISCARD_LO	0x10
+#define MV88E6XXX_PORT_IN_DISCARD_LO	0x10 W /* different counter on 6065 */
 
 /* Offset 0x11: InDiscards High Counter */
-#define MV88E6XXX_PORT_IN_DISCARD_HI	0x11
+#define MV88E6XXX_PORT_IN_DISCARD_HI	0x11 W /* different counter on 6065 */
 
 /* Offset 0x12: InFiltered Counter */
-#define MV88E6XXX_PORT_IN_FILTERED	0x12
+#define MV88E6XXX_PORT_IN_FILTERED	0x12 W /* ok, depending on other bit? */
 
 /* Offset 0x13: OutFiltered Counter */
-#define MV88E6XXX_PORT_OUT_FILTERED	0x13
+#define MV88E6XXX_PORT_OUT_FILTERED	0x13 W /* not on 6065 */
 
 /* Offset 0x18: IEEE Priority Mapping Table */
 #define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE			0x18
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE		0x8000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_MASK			0x7000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP		0x0000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP	0x1000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP	0x2000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP	0x3000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_DSCP	0x5000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_DSCP	0x6000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_DSCP	0x7000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK		0x0e00
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK		0x01ff
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE		0x8000 W /* reserved on 6065 */
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_MASK			0x7000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP		0x0000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP	0x1000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP	0x2000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP	0x3000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_DSCP	0x5000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_DSCP	0x6000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_DSCP	0x7000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK		0x0e00 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK		0x01ff W /* ^^ looks different on 6065 */
 
 /* Offset 0x18: Port IEEE Priority Remapping Registers (0-3) */
-#define MV88E6095_PORT_IEEE_PRIO_REMAP_0123	0x18
+#define MV88E6095_PORT_IEEE_PRIO_REMAP_0123	0x18 W
 
 /* Offset 0x19: Port IEEE Priority Remapping Registers (4-7) */
-#define MV88E6095_PORT_IEEE_PRIO_REMAP_4567	0x19
+#define MV88E6095_PORT_IEEE_PRIO_REMAP_4567	0x19 W
 
 int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
 			u16 *val);
@@ -289,6 +292,8 @@ int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port);
 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port);
 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
 				   enum mv88e6xxx_egress_mode mode);
+int mv88e6065_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
+				  enum mv88e6xxx_frame_mode mode);
 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
 				  enum mv88e6xxx_frame_mode mode);
 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply related

* Re: [PATCH net] vhost: fix OOB in get_rx_bufs()
From: Michael S. Tsirkin @ 2019-01-29 22:54 UTC (permalink / raw)
  To: David Miller
  Cc: jasowang, stefanha, kvm, virtualization, netdev, linux-kernel
In-Reply-To: <20190128.225444.1929870241029842289.davem@davemloft.net>

On Mon, Jan 28, 2019 at 10:54:44PM -0800, David Miller wrote:
> From: Jason Wang <jasowang@redhat.com>
> Date: Mon, 28 Jan 2019 15:05:05 +0800
> 
> > After batched used ring updating was introduced in commit e2b3b35eb989
> > ("vhost_net: batch used ring update in rx"). We tend to batch heads in
> > vq->heads for more than one packet. But the quota passed to
> > get_rx_bufs() was not correctly limited, which can result a OOB write
> > in vq->heads.
> > 
> >         headcount = get_rx_bufs(vq, vq->heads + nvq->done_idx,
> >                     vhost_len, &in, vq_log, &log,
> >                     likely(mergeable) ? UIO_MAXIOV : 1);
> > 
> > UIO_MAXIOV was still used which is wrong since we could have batched
> > used in vq->heads, this will cause OOB if the next buffer needs more
> > than 960 (1024 (UIO_MAXIOV) - 64 (VHOST_NET_BATCH)) heads after we've
> > batched 64 (VHOST_NET_BATCH) heads:
>  ...
> > Fixing this by allocating UIO_MAXIOV + VHOST_NET_BATCH iovs for
> > vhost-net. This is done through set the limitation through
> > vhost_dev_init(), then set_owner can allocate the number of iov in a
> > per device manner.
> > 
> > This fixes CVE-2018-16880.
> > 
> > Fixes: e2b3b35eb989 ("vhost_net: batch used ring update in rx")
> > Signed-off-by: Jason Wang <jasowang@redhat.com>
> 
> Applied and queued up for -stable, thanks!

Wow it seems we are down to hours round time post to queue.
It would be hard to keep up that rate generally.
However, I am guessing this was already in downstreams, and it's a CVE,
so I guess it's a no brainer and review wasn't really necessary - was
that the idea? Just checking.

-- 
MST

^ permalink raw reply

* Re: [PATCH v2 net 7/7] virtio_net: Differentiate sk_buff and xdp_frame on freeing
From: Michael S. Tsirkin @ 2019-01-29 22:51 UTC (permalink / raw)
  To: Toshiaki Makita; +Cc: David S. Miller, Jason Wang, netdev, virtualization
In-Reply-To: <1548722759-2470-8-git-send-email-makita.toshiaki@lab.ntt.co.jp>

On Tue, Jan 29, 2019 at 09:45:59AM +0900, Toshiaki Makita wrote:
> We do not reset or free up unused buffers when enabling/disabling XDP,
> so it can happen that xdp_frames are freed after disabling XDP or
> sk_buffs are freed after enabling XDP on xdp tx queues.
> Thus we need to handle both forms (xdp_frames and sk_buffs) regardless
> of XDP setting.
> One way to trigger this problem is to disable XDP when napi_tx is
> enabled. In that case, virtnet_xdp_set() calls virtnet_napi_enable()
> which kicks NAPI. The NAPI handler will call virtnet_poll_cleantx()
> which invokes free_old_xmit_skbs() for queues which have been used by
> XDP.
> 
> Note that even with this change we need to keep skipping
> free_old_xmit_skbs() from NAPI handlers when XDP is enabled, because XDP
> tx queues do not aquire queue locks.
> 
> - v2: Use napi_consume_skb() instead of dev_consume_skb_any()
> 
> Fixes: 4941d472bf95 ("virtio-net: do not reset during XDP set")
> Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>

Acked-by: Michael S. Tsirkin <mst@redhat.com>

> ---
> NOTE: Dropped Acked-by because of the v2 change.
> 
>  drivers/net/virtio_net.c | 54 +++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 42 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 1d454ce..2594481 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -57,6 +57,8 @@
>  #define VIRTIO_XDP_TX		BIT(0)
>  #define VIRTIO_XDP_REDIR	BIT(1)
>  
> +#define VIRTIO_XDP_FLAG	BIT(0)
> +
>  /* RX packet size EWMA. The average packet size is used to determine the packet
>   * buffer size when refilling RX rings. As the entire RX ring may be refilled
>   * at once, the weight is chosen so that the EWMA will be insensitive to short-
> @@ -252,6 +254,21 @@ struct padded_vnet_hdr {
>  	char padding[4];
>  };
>  
> +static bool is_xdp_frame(void *ptr)
> +{
> +	return (unsigned long)ptr & VIRTIO_XDP_FLAG;
> +}
> +
> +static void *xdp_to_ptr(struct xdp_frame *ptr)
> +{
> +	return (void *)((unsigned long)ptr | VIRTIO_XDP_FLAG);
> +}
> +
> +static struct xdp_frame *ptr_to_xdp(void *ptr)
> +{
> +	return (struct xdp_frame *)((unsigned long)ptr & ~VIRTIO_XDP_FLAG);
> +}
> +
>  /* Converting between virtqueue no. and kernel tx/rx queue no.
>   * 0:rx0 1:tx0 2:rx1 3:tx1 ... 2N:rxN 2N+1:txN 2N+2:cvq
>   */
> @@ -462,7 +479,8 @@ static int __virtnet_xdp_xmit_one(struct virtnet_info *vi,
>  
>  	sg_init_one(sq->sg, xdpf->data, xdpf->len);
>  
> -	err = virtqueue_add_outbuf(sq->vq, sq->sg, 1, xdpf, GFP_ATOMIC);
> +	err = virtqueue_add_outbuf(sq->vq, sq->sg, 1, xdp_to_ptr(xdpf),
> +				   GFP_ATOMIC);
>  	if (unlikely(err))
>  		return -ENOSPC; /* Caller handle free/refcnt */
>  
> @@ -482,13 +500,13 @@ static int virtnet_xdp_xmit(struct net_device *dev,
>  {
>  	struct virtnet_info *vi = netdev_priv(dev);
>  	struct receive_queue *rq = vi->rq;
> -	struct xdp_frame *xdpf_sent;
>  	struct bpf_prog *xdp_prog;
>  	struct send_queue *sq;
>  	unsigned int len;
>  	int drops = 0;
>  	int kicks = 0;
>  	int ret, err;
> +	void *ptr;
>  	int i;
>  
>  	/* Only allow ndo_xdp_xmit if XDP is loaded on dev, as this
> @@ -507,8 +525,12 @@ static int virtnet_xdp_xmit(struct net_device *dev,
>  	}
>  
>  	/* Free up any pending old buffers before queueing new ones. */
> -	while ((xdpf_sent = virtqueue_get_buf(sq->vq, &len)) != NULL)
> -		xdp_return_frame(xdpf_sent);
> +	while ((ptr = virtqueue_get_buf(sq->vq, &len)) != NULL) {
> +		if (likely(is_xdp_frame(ptr)))
> +			xdp_return_frame(ptr_to_xdp(ptr));
> +		else
> +			napi_consume_skb(ptr, false);
> +	}
>  
>  	for (i = 0; i < n; i++) {
>  		struct xdp_frame *xdpf = frames[i];
> @@ -1329,18 +1351,26 @@ static int virtnet_receive(struct receive_queue *rq, int budget,
>  
>  static void free_old_xmit_skbs(struct send_queue *sq, bool in_napi)
>  {
> -	struct sk_buff *skb;
>  	unsigned int len;
>  	unsigned int packets = 0;
>  	unsigned int bytes = 0;
> +	void *ptr;
>  
> -	while ((skb = virtqueue_get_buf(sq->vq, &len)) != NULL) {
> -		pr_debug("Sent skb %p\n", skb);
> +	while ((ptr = virtqueue_get_buf(sq->vq, &len)) != NULL) {
> +		if (likely(!is_xdp_frame(ptr))) {
> +			struct sk_buff *skb = ptr;
>  
> -		bytes += skb->len;
> -		packets++;
> +			pr_debug("Sent skb %p\n", skb);
>  
> -		napi_consume_skb(skb, in_napi);
> +			bytes += skb->len;
> +			napi_consume_skb(skb, in_napi);
> +		} else {
> +			struct xdp_frame *frame = ptr_to_xdp(ptr);
> +
> +			bytes += frame->len;
> +			xdp_return_frame(frame);
> +		}
> +		packets++;
>  	}
>  
>  	/* Avoid overhead when no packets have been processed
> @@ -2666,10 +2696,10 @@ static void free_unused_bufs(struct virtnet_info *vi)
>  	for (i = 0; i < vi->max_queue_pairs; i++) {
>  		struct virtqueue *vq = vi->sq[i].vq;
>  		while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
> -			if (!is_xdp_raw_buffer_queue(vi, i))
> +			if (!is_xdp_frame(buf))
>  				dev_kfree_skb(buf);
>  			else
> -				xdp_return_frame(buf);
> +				xdp_return_frame(ptr_to_xdp(buf));
>  		}
>  	}
>  
> -- 
> 1.8.3.1
> 

^ permalink raw reply

* Re: [PATCH v2 net 5/7] virtio_net: Don't process redirected XDP frames when XDP is disabled
From: Michael S. Tsirkin @ 2019-01-29 22:50 UTC (permalink / raw)
  To: Toshiaki Makita
  Cc: David S. Miller, Jason Wang, netdev, virtualization,
	Jesper Dangaard Brouer
In-Reply-To: <1548722759-2470-6-git-send-email-makita.toshiaki@lab.ntt.co.jp>

On Tue, Jan 29, 2019 at 09:45:57AM +0900, Toshiaki Makita wrote:
> Commit 8dcc5b0ab0ec ("virtio_net: fix ndo_xdp_xmit crash towards dev not
> ready for XDP") tried to avoid access to unexpected sq while XDP is
> disabled, but was not complete.
> 
> There was a small window which causes out of bounds sq access in
> virtnet_xdp_xmit() while disabling XDP.
> 
> An example case of
>  - curr_queue_pairs = 6 (2 for SKB and 4 for XDP)
>  - online_cpu_num = xdp_queue_paris = 4
> when XDP is enabled:
> 
> CPU 0                         CPU 1
> (Disabling XDP)               (Processing redirected XDP frames)
> 
>                               virtnet_xdp_xmit()
> virtnet_xdp_set()
>  _virtnet_set_queues()
>   set curr_queue_pairs (2)
>                                check if rq->xdp_prog is not NULL
>                                virtnet_xdp_sq(vi)
>                                 qp = curr_queue_pairs -
>                                      xdp_queue_pairs +
>                                      smp_processor_id()
>                                    = 2 - 4 + 1 = -1
>                                 sq = &vi->sq[qp] // out of bounds access
>   set xdp_queue_pairs (0)
>   rq->xdp_prog = NULL
> 
> Basically we should not change curr_queue_pairs and xdp_queue_pairs
> while someone can read the values. Thus, when disabling XDP, assign NULL
> to rq->xdp_prog first, and wait for RCU grace period, then change
> xxx_queue_pairs.
> Note that we need to keep the current order when enabling XDP though.
> 
> - v2: Make rcu_assign_pointer/synchronize_net conditional instead of
>       _virtnet_set_queues.
> 
> Fixes: 186b3c998c50 ("virtio-net: support XDP_REDIRECT")
> Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>

Acked-by: Michael S. Tsirkin <mst@redhat.com>

> ---
>  drivers/net/virtio_net.c | 33 ++++++++++++++++++++++++++-------
>  1 file changed, 26 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 669b65c..cea52e4 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -2410,6 +2410,10 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
>  		return -ENOMEM;
>  	}
>  
> +	old_prog = rtnl_dereference(vi->rq[0].xdp_prog);
> +	if (!prog && !old_prog)
> +		return 0;
> +
>  	if (prog) {
>  		prog = bpf_prog_add(prog, vi->max_queue_pairs - 1);
>  		if (IS_ERR(prog))
> @@ -2424,21 +2428,30 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
>  		}
>  	}
>  
> +	if (!prog) {
> +		for (i = 0; i < vi->max_queue_pairs; i++) {
> +			rcu_assign_pointer(vi->rq[i].xdp_prog, prog);
> +			if (i == 0)
> +				virtnet_restore_guest_offloads(vi);
> +		}
> +		synchronize_net();
> +	}
> +
>  	err = _virtnet_set_queues(vi, curr_qp + xdp_qp);
>  	if (err)
>  		goto err;
>  	netif_set_real_num_rx_queues(dev, curr_qp + xdp_qp);
>  	vi->xdp_queue_pairs = xdp_qp;
>  
> -	for (i = 0; i < vi->max_queue_pairs; i++) {
> -		old_prog = rtnl_dereference(vi->rq[i].xdp_prog);
> -		rcu_assign_pointer(vi->rq[i].xdp_prog, prog);
> -		if (i == 0) {
> -			if (!old_prog)
> +	if (prog) {
> +		for (i = 0; i < vi->max_queue_pairs; i++) {
> +			rcu_assign_pointer(vi->rq[i].xdp_prog, prog);
> +			if (i == 0 && !old_prog)
>  				virtnet_clear_guest_offloads(vi);
> -			if (!prog)
> -				virtnet_restore_guest_offloads(vi);
>  		}
> +	}
> +
> +	for (i = 0; i < vi->max_queue_pairs; i++) {
>  		if (old_prog)
>  			bpf_prog_put(old_prog);
>  		if (netif_running(dev)) {
> @@ -2451,6 +2464,12 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
>  	return 0;
>  
>  err:
> +	if (!prog) {
> +		virtnet_clear_guest_offloads(vi);
> +		for (i = 0; i < vi->max_queue_pairs; i++)
> +			rcu_assign_pointer(vi->rq[i].xdp_prog, old_prog);
> +	}
> +
>  	if (netif_running(dev)) {
>  		for (i = 0; i < vi->max_queue_pairs; i++) {
>  			virtnet_napi_enable(vi->rq[i].vq, &vi->rq[i].napi);
> -- 
> 1.8.3.1
> 

^ permalink raw reply

* Re: [PATCH iproute2-next v2] netns: add subcommand to attach an existing network namespace
From: Andrea Claudi @ 2019-01-29 22:42 UTC (permalink / raw)
  To: Matteo Croce; +Cc: netdev, David Ahern, Stephen Hemminger
In-Reply-To: <20190129150115.19965-1-mcroce@redhat.com>

On Tue, Jan 29, 2019 at 4:01 PM Matteo Croce <mcroce@redhat.com> wrote:
>
> ip tracks namespaces with dummy files in /var/run/netns/, but can't see
> namespaces created with other tools.
> Creating the dummy file and bind mounting the correct procfs entry will
> make ip aware of that namespace.
> Add an ip netns subcommand to automate this task.
>
> Signed-off-by: Matteo Croce <mcroce@redhat.com>
> ---
>  ip/ipnetns.c        | 62 ++++++++++++++++++++++++++++++++++-----------
>  man/man8/ip-netns.8 | 10 ++++++++
>  2 files changed, 57 insertions(+), 15 deletions(-)
>
> diff --git a/ip/ipnetns.c b/ip/ipnetns.c
> index 03879b49..430d8844 100644
> --- a/ip/ipnetns.c
> +++ b/ip/ipnetns.c
> @@ -28,6 +28,7 @@ static int usage(void)
>  {
>         fprintf(stderr, "Usage: ip netns list\n");
>         fprintf(stderr, "       ip netns add NAME\n");
> +       fprintf(stderr, "       ip netns attach NAME PID\n");
>         fprintf(stderr, "       ip netns set NAME NETNSID\n");
>         fprintf(stderr, "       ip [-all] netns delete [NAME]\n");
>         fprintf(stderr, "       ip netns identify [PID]\n");
> @@ -632,24 +633,40 @@ static int create_netns_dir(void)
>         return 0;
>  }
>
> -static int netns_add(int argc, char **argv)
> +static int netns_add(int argc, char **argv, bool create)
>  {
>         /* This function creates a new network namespace and
>          * a new mount namespace and bind them into a well known
>          * location in the filesystem based on the name provided.
>          *
> +        * If create is true, a new namespace will be created,
> +        * otherwise an existing one will be attached to the file.
> +        *
>          * The mount namespace is created so that any necessary
>          * userspace tweaks like remounting /sys, or bind mounting
> -        * a new /etc/resolv.conf can be shared between uers.
> +        * a new /etc/resolv.conf can be shared between users.
>          */
> -       char netns_path[PATH_MAX];
> +       char netns_path[PATH_MAX], proc_path[PATH_MAX];
>         const char *name;
> +       pid_t pid;
>         int fd;
>         int made_netns_run_dir_mount = 0;
>
> -       if (argc < 1) {
> -               fprintf(stderr, "No netns name specified\n");
> -               return -1;
> +       if (create) {
> +               if (argc < 1) {
> +                       fprintf(stderr, "No netns name specified\n");
> +                       return -1;
> +               }
> +       } else {
> +               if (argc < 2) {
> +                       fprintf(stderr, "No netns name and PID specified\n");
> +                       return -1;
> +               }
> +
> +               if (get_s32(&pid, argv[1], 0) || !pid) {
> +                       fprintf(stderr, "Invalid PID: %s\n", argv[1]);
> +                       return -1;
> +               }
>         }
>         name = argv[0];
>
> @@ -689,21 +706,33 @@ static int netns_add(int argc, char **argv)
>                 return -1;
>         }
>         close(fd);
> -       if (unshare(CLONE_NEWNET) < 0) {
> -               fprintf(stderr, "Failed to create a new network namespace \"%s\": %s\n",
> -                       name, strerror(errno));
> -               goto out_delete;
> +
> +       if (create) {
> +               if (unshare(CLONE_NEWNET) < 0) {
> +                       fprintf(stderr, "Failed to create a new network namespace \"%s\": %s\n",
> +                               name, strerror(errno));
> +                       goto out_delete;
> +               }
> +
> +               strcpy(proc_path, "/proc/self/ns/net");
> +       } else {
> +               snprintf(proc_path, sizeof(proc_path), "/proc/%d/ns/net", pid);
>         }
>
>         /* Bind the netns last so I can watch for it */
> -       if (mount("/proc/self/ns/net", netns_path, "none", MS_BIND, NULL) < 0) {
> -               fprintf(stderr, "Bind /proc/self/ns/net -> %s failed: %s\n",
> -                       netns_path, strerror(errno));
> +       if (mount(proc_path, netns_path, "none", MS_BIND, NULL) < 0) {
> +               fprintf(stderr, "Bind %s -> %s failed: %s\n",
> +                       proc_path, netns_path, strerror(errno));
>                 goto out_delete;
>         }
>         return 0;
>  out_delete:
> -       netns_delete(argc, argv);
> +       if (create) {
> +               netns_delete(argc, argv);
> +       } else if (unlink(netns_path) < 0) {
> +               fprintf(stderr, "Cannot remove namespace file \"%s\": %s\n",
> +                       netns_path, strerror(errno));
> +       }
>         return -1;
>  }
>
> @@ -846,7 +875,7 @@ int do_netns(int argc, char **argv)
>                 return usage();
>
>         if (matches(*argv, "add") == 0)
> -               return netns_add(argc-1, argv+1);
> +               return netns_add(argc-1, argv+1, true);
>
>         if (matches(*argv, "set") == 0)
>                 return netns_set(argc-1, argv+1);
> @@ -866,6 +895,9 @@ int do_netns(int argc, char **argv)
>         if (matches(*argv, "monitor") == 0)
>                 return netns_monitor(argc-1, argv+1);
>
> +       if (matches(*argv, "attach") == 0)
> +               return netns_add(argc-1, argv+1, false);
> +
>         fprintf(stderr, "Command \"%s\" is unknown, try \"ip netns help\".\n", *argv);
>         exit(-1);
>  }
> diff --git a/man/man8/ip-netns.8 b/man/man8/ip-netns.8
> index d539f18b..39a10e76 100644
> --- a/man/man8/ip-netns.8
> +++ b/man/man8/ip-netns.8
> @@ -19,6 +19,10 @@ ip-netns \- process network namespace management
>  .B ip netns add
>  .I NETNSNAME
>
> +.ti -8
> +.B ip netns attach
> +.I NETNSNAME PID
> +
>  .ti -8
>  .B ip [-all] netns del
>  .RI "[ " NETNSNAME " ]"
> @@ -89,6 +93,12 @@ This command displays all of the network namespaces in /var/run/netns
>  If NAME is available in /var/run/netns/ this command creates a new
>  network namespace and assigns NAME.
>
> +.TP
> +.B ip netns attach NAME PID - create a new named network namespace
> +.sp
> +If NAME is available in /var/run/netns/ this command attaches the network
> +namespace of the process PID to NAME as if it were created with ip netns.
> +
>  .TP
>  .B ip [-all] netns delete [ NAME ] - delete the name of a network namespace(s)
>  .sp
> --
> 2.20.1
>

Reviewed-by: Andrea Claudi <aclaudi@redhat.com>
Tested-by: Andrea Claudi <aclaudi@redhat.com>

^ permalink raw reply

* Re: Kernel memory corruption in CIPSO labeled TCP packets processing.
From: Paul Moore @ 2019-01-29 22:42 UTC (permalink / raw)
  To: Nazarov Sergey
  Cc: linux-security-module@vger.kernel.org, selinux@vger.kernel.org,
	netdev@vger.kernel.org, Casey Schaufler
In-Reply-To: <3499451548746609@myt4-929fb874f3f2.qloud-c.yandex.net>

On Tue, Jan 29, 2019 at 2:23 AM Nazarov Sergey <s-nazarov@yandex.ru> wrote:
> 29.01.2019, 01:18, "Paul Moore" <paul@paul-moore.com>:
> > If we don't pass a skb into ip_options_compile(), meaning both "skb"
> > and "rt" will be NULL, then I don't believe the option data will
> > change. Am I missing something?
>
> I mean, in cipso_v4_error we copy option data from skb before ip_options_compile call:
> +       memcpy(opt->__data, (unsigned char *)&(ip_hdr(skb)[1]), opt->optlen);
> But skb IP header data could be already changed by first call of ip_options_compile
> when packet received.

There are several cases where the stack ends up calling icmp_send()
after the skb has been through ip_options_compile(), that should be
okay.

-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* Re: [PATCH net v3] net: l2tp: fix reading optional fields of L2TPv3
From: Guillaume Nault @ 2019-01-29 22:37 UTC (permalink / raw)
  To: Jacob Wen; +Cc: netdev, eric.dumazet
In-Reply-To: <20190129061813.8097-1-jian.w.wen@oracle.com>

On Tue, Jan 29, 2019 at 02:18:13PM +0800, Jacob Wen wrote:
> Use pskb_may_pull() to make sure the optional fields are in skb linear
> parts, so we can safely read them in l2tp_recv_common.
> 
Looks fine to me. Just a few nitpicks. Not sure if they're worth a repost.
But if you send a v4, you can:
  * Add the proper Fixes tag.
  * Drop 'net:' from the subsystem prefix ('l2tp:' is enough).
  * Move your patch history inside the commit description.
  * Keep my Acked-by tag.

> diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
> index 26f1d435696a..82c28008b438 100644
> --- a/net/l2tp/l2tp_core.c
> +++ b/net/l2tp/l2tp_core.c
> @@ -884,6 +884,10 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)
>  		goto error;
>  	}
>  
> +	if (tunnel->version != L2TP_HDR_VER_2 &&
> 
Using tunnel->version == L2TP_HDR_VER_3 would have been clearer.

> diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
> index 9c9afe94d389..870f8ccf95f7 100644
> --- a/net/l2tp/l2tp_core.h
> +++ b/net/l2tp/l2tp_core.h
> @@ -301,6 +301,27 @@ static inline bool l2tp_tunnel_uses_xfrm(const struct l2tp_tunnel *tunnel)
>  }
>  #endif
>  
> +/* Pull optional fields of L2TPv3 */
> +static inline int l2tp_v3_pull_opt(struct l2tp_session *session, struct sk_buff *skb,
> 
The comment and function name are a bit misleading: nothing is pulled
here.

> +				   unsigned char **ptr, unsigned char **optr)
> +{
> +	int opt_len = session->peer_cookie_len + l2tp_get_l2specific_len(session);
> +
> +	if (opt_len > 0) {
> +		int off = *ptr - *optr;
> +
> +		if (!pskb_may_pull(skb, off + opt_len))
> +			return -1;
> +
> +		if (skb->data != *optr) {
> +			*optr = skb->data;
> +			*ptr = skb->data + off;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  #define l2tp_printk(ptr, type, func, fmt, ...)				\
>  do {									\
>  	if (((ptr)->debug) & (type))					\

Fixes: f7faffa3ff8e ("l2tp: Add L2TPv3 protocol support")
Fixes: 0d76751fad77 ("l2tp: Add L2TPv3 IP encapsulation (no UDP) support")
Fixes: a32e0eec7042 ("l2tp: introduce L2TPv3 IP encapsulation support for IPv6")

Acked-by: Guillaume Nault <gnault@redhat.com>

Thanks for reporting and fixing this.

BTW, Do you plan to also fix L2TPv2?
It looks like defining L2TP_HDR_SIZE_MAX to 14 (size of L2TPv2 header
with all optional fields) and using it in place of L2TP_HDR_SIZE_SEQ in
l2tp_udp_recv_core() should be enough.

^ permalink raw reply

* Re: [PATCH net v5 2/2] net/mlx5e: Don't overwrite pedit action when multiple pedit used
From: Saeed Mahameed @ 2019-01-29 22:21 UTC (permalink / raw)
  To: davem@davemloft.net, xiangxia.m.yue@gmail.com,
	gerlitz.or@gmail.com
  Cc: netdev@vger.kernel.org, Or Gerlitz
In-Reply-To: <1548718086-20924-2-git-send-email-xiangxia.m.yue@gmail.com>

On Mon, 2019-01-28 at 15:28 -0800, xiangxia.m.yue@gmail.com wrote:
> From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> 
> In some case, we may use multiple pedit actions to modify packets.
> The command shown as below: the last pedit action is effective.
> 
> $ tc filter add dev netdev_rep parent ffff: protocol ip prio 1    \
> 	flower skip_sw ip_proto icmp dst_ip 3.3.3.3        \
> 	action pedit ex munge ip dst set 192.168.1.100 pipe    \
> 	action pedit ex munge eth src set 00:00:00:00:00:01 pipe    \
> 	action pedit ex munge eth dst set 00:00:00:00:00:02 pipe    \
> 	action csum ip pipe    \
> 	action tunnel_key set src_ip 1.1.1.100 dst_ip 1.1.1.200
> dst_port 4789 id 100 \
> 	action mirred egress redirect dev vxlan0
> 
> To fix it, we add max_mod_hdr_actions to mlx5e_tc_flow_parse_attr
> struction,
> max_mod_hdr_actions will store the max pedit action number we support
> and
> num_mod_hdr_actions indicates how many pedit action we used, and
> store all
> pedit action to mod_hdr_actions.
> 
> Fixes: d79b6df6b10a ("net/mlx5e: Add parsing of TC pedit actions to
> HW format")
> Cc: Or Gerlitz <ogerlitz@mellanox.com>
> Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
> ---
> v3: Remove the unnecessary init.
> v2: Fix comment message and change tag from net-next to net.
> ---


Thank you Tonghao and Or.

Acked-by: Saeed Mahameed <saeedm@mellanox.com>

^ permalink raw reply

* Re: [PATCH net v5 1/2] net/mlx5e: Update hw flows when encap source mac changed
From: Saeed Mahameed @ 2019-01-29 22:20 UTC (permalink / raw)
  To: davem@davemloft.net, xiangxia.m.yue@gmail.com,
	gerlitz.or@gmail.com
  Cc: netdev@vger.kernel.org, Hadar Hen Zion
In-Reply-To: <1548718086-20924-1-git-send-email-xiangxia.m.yue@gmail.com>

On Mon, 2019-01-28 at 15:28 -0800, xiangxia.m.yue@gmail.com wrote:
> From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> 
> When we offload tc filters to hardware, hardware flows can
> be updated when mac of encap destination ip is changed.
> But we ignore one case, that the mac of local encap ip can
> be changed too, so we should also update them.
> 
> To fix it, add route_dev in mlx5e_encap_entry struct to save
> the local encap netdevice, and when mac changed, kernel will
> flush all the neighbour on the netdevice and send
> NETEVENT_NEIGH_UPDATE
> event. The mlx5 driver will delete the flows and add them when
> neighbour
> available again.
> 
> Fixes: 232c001398ae ("net/mlx5e: Add support to neighbour update
> flow")
> Cc: Hadar Hen Zion <hadarh@mellanox.com>
> Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
> 
> 

Thank you Tonghao and Or.

Acked-by: Saeed Mahameed <saeedm@mellanox.com>

^ permalink raw reply

* Re: [PATCH] kernel/bpf/core.c - fix bitrotted kerneldoc.
From: Song Liu @ 2019-01-29 22:12 UTC (permalink / raw)
  To: Valdis Kletnieks
  Cc: Alexei Starovoitov, Daniel Borkmann, Networking, open list
In-Reply-To: <30924.1548734686@turing-police.cc.vt.edu>

On Mon, Jan 28, 2019 at 8:06 PM <valdis.kletnieks@vt.edu> wrote:
>
> Over the years, the function signature has changed, the kerneldoc block hasn't.
>
> Signed-off-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>
Acked-by: Song Liu <songliubraving@fb.com>

>
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index 2a81b8af3748..2728b6247091 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -1216,8 +1216,9 @@ bool bpf_opcode_in_insntable(u8 code)
>  #ifndef CONFIG_BPF_JIT_ALWAYS_ON
>  /**
>   *     __bpf_prog_run - run eBPF program on a given context
> - *     @ctx: is the data we are operating on
> + *     @regs: is the array of MAX_BPF_EXT_REG eBPF pseudo-registers
>   *     @insn: is the array of eBPF instructions
> + *     @stack: is the eBPF storage stack
>   *
>   * Decode and execute eBPF instructions.
>   */
>

^ permalink raw reply

* Re: [PATCH net-next 02/24] sctp: use SCTP_FUTURE_ASSOC for SCTP_PEER_ADDR_PARAMS sockopt
From: Neil Horman @ 2019-01-29 21:25 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, Marcelo Ricardo Leitner, davem
In-Reply-To: <bf66a45aa6763646c07e1b8be102466f07fc1648.1548659198.git.lucien.xin@gmail.com>

On Mon, Jan 28, 2019 at 03:08:24PM +0800, Xin Long wrote:
> Check with SCTP_FUTURE_ASSOC instead in
> sctp_/setgetsockopt_peer_addr_params, it's compatible with 0.
> 
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
>  net/sctp/socket.c | 18 ++++++++++--------
>  1 file changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index a52d132..4c43b95 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -2750,12 +2750,13 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
>  			return -EINVAL;
>  	}
>  
> -	/* Get association, if assoc_id != 0 and the socket is a one
> -	 * to many style socket, and an association was not found, then
> -	 * the id was invalid.
> +	/* Get association, if assoc_id != SCTP_FUTURE_ASSOC and the
> +	 * socket is a one to many style socket, and an association
> +	 * was not found, then the id was invalid.
>  	 */
>  	asoc = sctp_id2assoc(sk, params.spp_assoc_id);
> -	if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP))
> +	if (!asoc && params.spp_assoc_id != SCTP_FUTURE_ASSOC &&
Sorry to follow up, but I misspoke in my previous email, I should have said, why
do we only allow future associations as the only special case association id
here?  Since the function is meant to set a specific association id, it seems to
me that you would want to:

a) allow setting of a specific id
b) allow setting of all association ids on the socket
(SCTP_CURRENT_ASSOC)
c) allow recording of a set of params to apply to all current and future
associations (FUTURE/ALL).

(a) is already handled clearly, but (b) and (c) require more work on this
function than just checking association id on entry.

I think this comment may apply to all the socket option functions
 
> +	    sctp_style(sk, UDP))
>  		return -EINVAL;
>  
>  	/* Heartbeat demand can only be sent on a transport or
> @@ -5676,12 +5677,13 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
>  		}
>  	}
>  
> -	/* Get association, if assoc_id != 0 and the socket is a one
> -	 * to many style socket, and an association was not found, then
> -	 * the id was invalid.
> +	/* Get association, if assoc_id != SCTP_FUTURE_ASSOC and the
> +	 * socket is a one to many style socket, and an association
> +	 * was not found, then the id was invalid.
>  	 */
>  	asoc = sctp_id2assoc(sk, params.spp_assoc_id);
> -	if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP)) {
> +	if (!asoc && params.spp_assoc_id != SCTP_FUTURE_ASSOC &&
> +	    sctp_style(sk, UDP)) {
>  		pr_debug("%s: failed no association\n", __func__);
>  		return -EINVAL;
>  	}
> -- 
> 2.1.0
> 
> 

^ permalink raw reply

* Re: WoL broken in r8169.c since kernel 4.19
From: Heiner Kallweit @ 2019-01-29 21:20 UTC (permalink / raw)
  To: Marc Haber; +Cc: netdev@vger.kernel.org
In-Reply-To: <20190129153553.GL27062@torres.zugschlus.de>

Hi Marc,

one more attempt, could you please test the following with 4.19 or 4.20
(w/o the other debug patches) ?

Rgds, Heiner


---
 drivers/net/ethernet/realtek/r8169.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 3e650bd9e..2dab28115 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -1371,6 +1371,8 @@ static void rtl_link_chg_patch(struct rtl8169_private *tp)
 
 #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
 
+/* Don't delete it completely, in case we need to re-enable it */
+#if 0
 static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
 {
 	u8 options;
@@ -1405,6 +1407,7 @@ static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
 
 	return wolopts;
 }
+#endif
 
 static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
@@ -4284,7 +4287,7 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
 
 static bool rtl_wol_pll_power_down(struct rtl8169_private *tp)
 {
-	if (!__rtl8169_get_wol(tp))
+	if (!device_may_wakeup(tp_to_dev(tp)))
 		return false;
 
 	phy_speed_down(tp->phydev, false);
@@ -7441,8 +7444,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		return rc;
 	}
 
-	tp->saved_wolopts = __rtl8169_get_wol(tp);
-
 	mutex_init(&tp->wk.mutex);
 	INIT_WORK(&tp->wk.work, rtl_task);
 	u64_stats_init(&tp->rx_stats.syncp);
-- 
2.20.1



On 29.01.2019 16:35, Marc Haber wrote:
> Hi,
> 
> after having a good night's sleep over that, it's obviously a merge
> commit which cannot easily be reverted. How would I continue after
> identifying a merge commit as the culprit?
> 
> On Tue, Jan 29, 2019 at 08:32:53AM +0100, Marc Haber wrote:
>> According to bisect, the first bad commit is
>> 19725496da5602b401eae389736ab00d1817e264
>>
>> commit 19725496da5602b401eae389736ab00d1817e264
>> Merge: aea5f654e6b7 9981b4fb8684
> 
> git diff aea5f654e6b7..19725496da5602b401eae389736ab00d1817e264,
> filtered for r8169 looks manageable:
> 
> --- a/drivers/net/ethernet/realtek/r8169.c
> +++ b/drivers/net/ethernet/realtek/r8169.c
> @@ -7396,8 +7396,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struc
>                 return rc;
>         }
>  
> -       /* override BIOS settings, use userspace tools to enable WOL */
> -       __rtl8169_set_wol(tp, 0);
> +       tp->saved_wolopts = __rtl8169_get_wol(tp);
>  
>         mutex_init(&tp->wk.mutex);
>         u64_stats_init(&tp->rx_stats.syncp);
> 
> but the other one seems unmanageably big:
> 
> [18/5009]mh@fan:~/linux/git/linux (master % u=) $ git diff 9981b4fb8684..19725496da5602b401eae389736ab00d1817e264 -- drivers/net/ethernet/realtek/r8169.c | diffstat
>  r8169.c |  815 ++++++++++++++++++----------------------------------------------
>  1 file changed, 234 insertions(+), 581 deletions(-)
> [19/5009]mh@fan:~/linux/git/linux (master % u=) $ 
> 
> -------
> But, indeed, adding the call to __rtl8169_set_wol(tp, 0) fixes the issue
> for me and the machine now wakes up from StR on a magic packet without
> having to go through strange ethtool motions.
> -------
> 
> Would that code change be suitable for the official kernel cod?
> 
> Greetings
> Marc
> 


^ permalink raw reply related

* Re: [PATCH net-next 02/24] sctp: use SCTP_FUTURE_ASSOC for SCTP_PEER_ADDR_PARAMS sockopt
From: Neil Horman @ 2019-01-29 21:17 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, Marcelo Ricardo Leitner, davem
In-Reply-To: <bf66a45aa6763646c07e1b8be102466f07fc1648.1548659198.git.lucien.xin@gmail.com>

On Mon, Jan 28, 2019 at 03:08:24PM +0800, Xin Long wrote:
> Check with SCTP_FUTURE_ASSOC instead in
> sctp_/setgetsockopt_peer_addr_params, it's compatible with 0.
> 
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
>  net/sctp/socket.c | 18 ++++++++++--------
>  1 file changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index a52d132..4c43b95 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -2750,12 +2750,13 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
>  			return -EINVAL;
>  	}
>  
> -	/* Get association, if assoc_id != 0 and the socket is a one
> -	 * to many style socket, and an association was not found, then
> -	 * the id was invalid.
> +	/* Get association, if assoc_id != SCTP_FUTURE_ASSOC and the
> +	 * socket is a one to many style socket, and an association
> +	 * was not found, then the id was invalid.
>  	 */
>  	asoc = sctp_id2assoc(sk, params.spp_assoc_id);
> -	if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP))
> +	if (!asoc && params.spp_assoc_id != SCTP_FUTURE_ASSOC &&
If we are disallowing SCTP_FUTURE_ASSOC here, why would we allow SCTP_ALL_ASSOC
(which, as noted by patch 0, includes future associations)?

> +	    sctp_style(sk, UDP))
>  		return -EINVAL;
>  
>  	/* Heartbeat demand can only be sent on a transport or
> @@ -5676,12 +5677,13 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
>  		}
>  	}
>  
> -	/* Get association, if assoc_id != 0 and the socket is a one
> -	 * to many style socket, and an association was not found, then
> -	 * the id was invalid.
> +	/* Get association, if assoc_id != SCTP_FUTURE_ASSOC and the
> +	 * socket is a one to many style socket, and an association
> +	 * was not found, then the id was invalid.
>  	 */
>  	asoc = sctp_id2assoc(sk, params.spp_assoc_id);
> -	if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP)) {
> +	if (!asoc && params.spp_assoc_id != SCTP_FUTURE_ASSOC &&
Same question as above, shouldn't both of these be restricted to specific
associations or to CURRENT associations?

> +	    sctp_style(sk, UDP)) {
>  		pr_debug("%s: failed no association\n", __func__);
>  		return -EINVAL;
>  	}
> -- 
> 2.1.0
> 
> 

^ permalink raw reply

* Re: ethtool - manual changes in ethtool-copy.h
From: John W. Linville @ 2019-01-29 20:47 UTC (permalink / raw)
  To: Michal Kubecek; +Cc: Maciej Żenczykowski, netdev
In-Reply-To: <20190129202842.GI24651@unicorn.suse.cz>

On Tue, Jan 29, 2019 at 09:28:42PM +0100, Michal Kubecek wrote:
> Hello,
> 
> I'm sorry I didn't notice earlier but ethtool commit 4df55c81996d
> ("ethtool: change to new sane powerpc64 kernel headers") adds changes to
> ethtool-copy.h which are not in sync with kernel file it is generated
> from.
> 
> This file is supposed to be a copy of the sanitized kernel UAPI header,
> i.e. what you get as include/linux/ethtool.h by "make headers_install"
> in kernel tree. (The copy in ethtool git is currently a bit behind but
> the missing recent changes only modify comments so that it's not really
> a problem.)
> 
> Modifying this file manually would mean that anyone who would update it
> in the future (to sync with kernel changes) could not simply copy the
> sanitized kernel header but would have to make sure to add your fragment
> to it.
> 
> As you only need to define the __SANE_USERSPACE_TYPES__ macro (on
> ppc64), it might be possible to achieve the same goal in Makefile.
> 
> Michal Kubecek

Ooops -- thanks for noticing that Michal!

Maciej, how soon might you be able to address this? What is the effect
of simply reverting it? Just warnings on ppc64 builds?

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* [GIT] Networking
From: David Miller @ 2019-01-29 20:55 UTC (permalink / raw)
  To: torvalds; +Cc: akpm, netdev, linux-kernel


1) Need to save away the IV across tls async operations, from Dave
   Watson.

2) Upon successful packet processing, we should liberate the SKB with
   dev_consume_skb{_irq}().  From Yang Wei.

3) Only apply RX hang workaround on effected macb chips, from Harini
   Katakam.

4) Dummy netdev need a proper namespace assigned to them, from Josh
   Elsasser.

5) Some paths of nft_compat run lockless now, and thus we need to use
   a proper refcnt_t.  From Florian Westphal.

6) Avoid deadlock in mlx5 by doing IRQ locking, from Moni Shoua.

7) netrom does not refcount sockets properly wrt. timers, fix that
   by using the sock timer API.  From Cong Wang.

8) Fix locking of inexact inserts of xfrm policies, from Florian
   Westphal.

9) Missing xfrm hash generation bump, also from Florian.

10) Missing of_node_put() in hns driver, from Yonglong Liu.

11) Fix DN_IFREQ_SIZE, from Johannes Berg.

12) ip6mr notifier is invoked during traversal of wrong table,
    from Nir Dotan.

13) TX promisc settings not performed correctly in qed, from Manish
    Chopra.

14) Fix OOB access in vhost, from Jason Wang.

Please pull, thanks a lot!

The following changes since commit 1fc7f56db7a7c467e46a5d2e2a009d2f337e0338:

  Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm (2019-01-27 09:21:00 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 

for you to fetch changes up to d07e1e0febe10b65eecd3205ad3bd1e999754887:

  MAINTAINERS: Add entry for XDP (eXpress Data Path) (2019-01-29 11:40:51 -0800)

----------------------------------------------------------------
Alexey Khoroshilov (1):
      net: stmmac: dwmac-rk: fix error handling in rk_gmac_powerup()

Anders Roxell (1):
      netfilter: ipt_CLUSTERIP: fix warning unused variable cn

Andrew Lunn (1):
      net: dsa: mv88e6xxx: Fix serdes irq setup going recursive

Aya Levin (1):
      net/mlx5e: Allow MAC invalidation while spoofchk is ON

Benedict Wong (1):
      xfrm: Make set-mark default behavior backward compatible

Bernard Pidoux (1):
      net/rose: fix NULL ax25_cb kernel panic

Bodong Wang (1):
      Revert "net/mlx5e: E-Switch, Initialize eswitch only if eswitch manager"

Cong Wang (1):
      netrom: switch to sock timer API

Dave Watson (2):
      net: tls: Save iv in tls_rec for async crypto requests
      net: tls: Fix deadlock in free_resources tx

David S. Miller (5):
      Merge branch 'master' of git://git.kernel.org/.../klassert/ipsec
      Merge tag 'mlx5-fixes-2019-01-25' of git://git.kernel.org/.../saeed/linux
      Merge branch 'hns-fixes'
      Merge git://git.kernel.org/.../pablo/nf
      Merge branch 'qed-Bug-fixes'

Fernando Fernandez Mancera (1):
      netfilter: nfnetlink_osf: add missing fmatch check

Florian Westphal (12):
      selftests: xfrm: add block rules with adjacent/overlapping subnets
      xfrm: policy: use hlist rcu variants on inexact insert, part 2
      xfrm: policy: increment xfrm_hash_generation on hash rebuild
      xfrm: policy: delete inexact policies from inexact list on hash rebuild
      xfrm: policy: fix reinsertion on node merge
      selftests: xfrm: alter htresh to trigger move of policies to hash table
      xfrm: policy: fix infinite loop when merging src-nodes
      xfrm: refine validation of template and selector families
      netfilter: nft_compat: use refcnt_t type for nft_xt reference count
      netfilter: nft_compat: make lists per netns
      netfilter: nft_compat: destroy function must not have side effects
      netfilter: ebtables: compat: un-break 32bit setsockopt when no rules are present

Harini Katakam (1):
      net: macb: Apply RXUBR workaround only to versions with errata

Jason Wang (1):
      vhost: fix OOB in get_rx_bufs()

Jesper Dangaard Brouer (1):
      MAINTAINERS: Add entry for XDP (eXpress Data Path)

Johannes Berg (1):
      decnet: fix DN_IFREQ_SIZE

Josh Elsasser (1):
      net: set default network namespace in init_dummy_netdev()

Manish Chopra (5):
      qed: Fix bug in tx promiscuous mode settings
      qed: Fix LACP pdu drops for VFs
      qed: Fix VF probe failure while FLR
      qed: Fix system crash in ll2 xmit
      qed: Fix stack out of bounds bug

Moni Shoua (1):
      net/mlx5: Take lock with IRQs disabled to avoid deadlock

Nir Dotan (1):
      ip6mr: Fix notifiers call on mroute_clean_tables()

Or Gerlitz (2):
      net/mlx5e: Move to use common phys port names for vport representors
      net/mlx5e: Unblock setting vid 0 for VFs through the uplink rep

Shay Agroskin (1):
      net/mlx5e: Fix wrong private flag usage causing checksum disable

Su Yanjun (1):
      vti4: Fix a ipip packet processing bug in 'IPCOMP' virtual tunnel

Tomonori Sakita (1):
      net: altera_tse: fix msgdma_tx_completion on non-zero fill_level case

Yang Wei (8):
      net: i825xx: replace dev_kfree_skb_irq by dev_consume_skb_irq for drop profiles
      net: alteon: replace dev_kfree_skb_irq by dev_consume_skb_irq
      net: amd8111e: replace dev_kfree_skb_irq by dev_consume_skb_irq
      net: apple: replace dev_kfree_skb_irq by dev_consume_skb_irq for drop profiles
      net: ti: replace dev_kfree_skb_irq by dev_consume_skb_irq for drop profiles
      net: 8139cp: replace dev_kfree_skb_irq by dev_consume_skb_irq for drop profiles
      net: caif: call dev_consume_skb_any when skb xmit done
      net: b44: replace dev_kfree_skb_xxx by dev_consume_skb_xxx for drop profiles

Yonglong Liu (3):
      net: hns: Fix for missing of_node_put() after of_parse_phandle()
      net: hns: Restart autoneg need return failed when autoneg off
      net: hns: Fix wrong read accesses via Clause 45 MDIO protocol

ZhangXiaoxu (1):
      ipvs: Fix signed integer overflow when setsockopt timeout

 MAINTAINERS                                         |  18 ++++++++++
 drivers/net/caif/caif_serial.c                      |   5 +--
 drivers/net/dsa/mv88e6xxx/serdes.c                  |   2 +-
 drivers/net/ethernet/alteon/acenic.c                |   2 +-
 drivers/net/ethernet/altera/altera_msgdma.c         |   3 +-
 drivers/net/ethernet/amd/amd8111e.c                 |   2 +-
 drivers/net/ethernet/apple/bmac.c                   |   2 +-
 drivers/net/ethernet/broadcom/b44.c                 |   4 +--
 drivers/net/ethernet/cadence/macb.h                 |   3 ++
 drivers/net/ethernet/cadence/macb_main.c            |  28 +++++++++------
 drivers/net/ethernet/hisilicon/hns/hns_enet.c       |   5 +++
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c    |  16 +++++----
 drivers/net/ethernet/hisilicon/hns_mdio.c           |   2 +-
 drivers/net/ethernet/i825xx/82596.c                 |   2 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c   |   2 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_rep.c    |  25 +++++++++++--
 drivers/net/ethernet/mellanox/mlx5/core/eswitch.c   |  22 +++++-------
 drivers/net/ethernet/mellanox/mlx5/core/lag.c       |  21 +++++++++++
 drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h |   2 ++
 drivers/net/ethernet/mellanox/mlx5/core/qp.c        |   5 +--
 drivers/net/ethernet/qlogic/qed/qed_dev.c           |   8 ++---
 drivers/net/ethernet/qlogic/qed/qed_l2.c            |  12 ++++++-
 drivers/net/ethernet/qlogic/qed/qed_l2.h            |   3 ++
 drivers/net/ethernet/qlogic/qed/qed_ll2.c           |  20 ++++++++---
 drivers/net/ethernet/qlogic/qed/qed_sriov.c         |  10 ++++--
 drivers/net/ethernet/qlogic/qed/qed_vf.c            |  10 ++++++
 drivers/net/ethernet/realtek/8139cp.c               |   2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c      |   4 ++-
 drivers/net/ethernet/ti/cpmac.c                     |   2 +-
 drivers/vhost/net.c                                 |   3 +-
 drivers/vhost/scsi.c                                |   2 +-
 drivers/vhost/vhost.c                               |   7 ++--
 drivers/vhost/vhost.h                               |   4 ++-
 drivers/vhost/vsock.c                               |   2 +-
 include/net/tls.h                                   |   2 ++
 net/bridge/netfilter/ebtables.c                     |   9 +++--
 net/core/dev.c                                      |   3 ++
 net/decnet/dn_dev.c                                 |   2 +-
 net/ipv4/ip_vti.c                                   |  50 ++++++++++++++++++++++++++
 net/ipv4/netfilter/ipt_CLUSTERIP.c                  |   2 +-
 net/ipv6/ip6mr.c                                    |   7 ++--
 net/netfilter/ipvs/ip_vs_ctl.c                      |  12 +++++++
 net/netfilter/nfnetlink_osf.c                       |   4 +++
 net/netfilter/nft_compat.c                          | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
 net/netrom/nr_timer.c                               |  20 +++++------
 net/rose/rose_route.c                               |   5 +++
 net/tls/tls_sw.c                                    |   6 +++-
 net/xfrm/xfrm_policy.c                              |  63 +++++++++++++++++----------------
 net/xfrm/xfrm_user.c                                |  13 ++++---
 tools/testing/selftests/net/xfrm_policy.sh          | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
 50 files changed, 605 insertions(+), 195 deletions(-)

^ permalink raw reply

* linux-next: Fixes tags need some work in the net tree
From: Stephen Rothwell @ 2019-01-29 20:49 UTC (permalink / raw)
  To: David Miller, Networking
  Cc: Linux Next Mailing List, Linux Kernel Mailing List, Dave Watson

[-- Attachment #1: Type: text/plain, Size: 546 bytes --]

Hi all,

In commit

  1023121375c6 ("net: tls: Fix deadlock in free_resources tx")

Fixes tag

  Fixes: a42055e8d2c30 ("Add support for async encryption of records...")

has these problem(s):

  - Subject does not match target commit subject

In commit

  32eb67b93c9e ("net: tls: Save iv in tls_rec for async crypto requests")

Fixes tag

  Fixes: a42055e8d2c30 ("Add support for async encryption of records...")

has these problem(s):

  - Subject does not match target commit subject

-- 
Cheers,
Stephen Rothwell

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* ethtool - manual changes in ethtool-copy.h
From: Michal Kubecek @ 2019-01-29 20:28 UTC (permalink / raw)
  To: Maciej Żenczykowski; +Cc: John W. Linville, netdev

Hello,

I'm sorry I didn't notice earlier but ethtool commit 4df55c81996d
("ethtool: change to new sane powerpc64 kernel headers") adds changes to
ethtool-copy.h which are not in sync with kernel file it is generated
from.

This file is supposed to be a copy of the sanitized kernel UAPI header,
i.e. what you get as include/linux/ethtool.h by "make headers_install"
in kernel tree. (The copy in ethtool git is currently a bit behind but
the missing recent changes only modify comments so that it's not really
a problem.)

Modifying this file manually would mean that anyone who would update it
in the future (to sync with kernel changes) could not simply copy the
sanitized kernel header but would have to make sure to add your fragment
to it.

As you only need to define the __SANE_USERSPACE_TYPES__ macro (on
ppc64), it might be possible to achieve the same goal in Makefile.

Michal Kubecek


^ permalink raw reply

* Re: [PATCH net-next] net: udp Allow CHECKSUM_UNNECESSARY packets to do GRO.
From: Tom Herbert @ 2019-01-29 20:24 UTC (permalink / raw)
  To: maowenan; +Cc: Linux Kernel Network Developers, David S. Miller, Eric Dumazet
In-Reply-To: <f19946e5-d76d-ca75-d558-44dc8f738764@huawei.com>

On Tue, Jan 29, 2019 at 12:08 AM maowenan <maowenan@huawei.com> wrote:
>
>
>
> On 2019/1/29 14:24, Tom Herbert wrote:
> > On Mon, Jan 28, 2019 at 10:04 PM maowenan <maowenan@huawei.com> wrote:
> >>
> >>
> >>
> >> On 2019/1/29 12:01, Tom Herbert wrote:
> >>> On Mon, Jan 28, 2019 at 7:00 PM maowenan <maowenan@huawei.com> wrote:
> >>>>
> >>>> Hi all,
> >>>> Do you have any comments about this change?
> >>>>
> >>>>
> >>>> On 2019/1/23 11:33, Mao Wenan wrote:
> >>>>> When udp4_gro_receive() get one packet that uh->check=0,
> >>>>> skb_gro_checksum_validate_zero_check() will set the
> >>>>> skb->ip_summed = CHECKSUM_UNNECESSARY;
> >>>>> skb->csum_level = 0;
> >>>>> Then udp_gro_receive() will flush the packet which is not CHECKSUM_PARTIAL,
> >>>>> It is not our expect,  because check=0 in udp header indicates this
> >>>>> packet is no need to caculate checksum, we should go further to do GRO.
> >>>>>
> >>>>> This patch changes the value of csum_cnt according to skb->csum_level.
> >>>>> ---
> >>>>>  include/linux/netdevice.h | 1 +
> >>>>>  1 file changed, 1 insertion(+)
> >>>>>
> >>>>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> >>>>> index 1377d08..9c819f1 100644
> >>>>> --- a/include/linux/netdevice.h
> >>>>> +++ b/include/linux/netdevice.h
> >>>>> @@ -2764,6 +2764,7 @@ static inline void skb_gro_incr_csum_unnecessary(struct sk_buff *skb)
> >>>>>                * during GRO. This saves work if we fallback to normal path.
> >>>>>                */
> >>>>>               __skb_incr_checksum_unnecessary(skb);
> >>>>> +             NAPI_GRO_CB(skb)->csum_cnt = skb->csum_level + 1;
> >>>
> >>> That doesn't look right. This would be reinitializing the GRO
> >>> checksums from the beginning.
> >>>
> >>>>>       }
> >>>>>  }
> >>>>>
> >>>>>
> >>>>
> >>> I assume the code is bailing on this conditional:
> >>>
> >>> if (NAPI_GRO_CB(skb)->encap_mark ||
> >>>             (skb->ip_summed != CHECKSUM_PARTIAL &&
> >>>              NAPI_GRO_CB(skb)->csum_cnt == 0 &&
> >>>              !NAPI_GRO_CB(skb)->csum_valid) ||
> >>>             !udp_sk(sk)->gro_receive)
> >>>                 goto out_unlock;
> >>>
> >>> I am trying to remember why this needs to check csum_cnt. If there was
> >>> a csum_cnt for the UDP csum being zero from checksum-unnecessary, it
> >>> was consumed by skb_gro_checksum_validate_zero_check in UDP4 GRO
> >>> received.
> >>
> >> We have met the scene about two VMs in different host with vxlan packets, when udp4_gro_receive receives
> >> one packet with ip_summed=CHECKSUM_NONE,csum_cnt=0,csum_valid=0,and udp->check=0, then skb_gro_checksum_validate_zero_check()->
> >> skb_gro_incr_csum_unnecessary() validate it and set ip_summed=CHECKSUM_UNNECESSARY,csum_level=0, but csum_cnt and csum_valid
> >> keep zero value. Then it will be flushed in udp_gro_receive(), the codes as you have showed.
> >>
> >> so I think it forgets to modify csum_cnt since csum_level is changed in skb_gro_incr_csum_unnecessary()->__skb_incr_checksum_unnecessary().
> >>
> > Yes, but the csum_level is changing since we've gone beyond the
> > checksums initially reported inc checksum-unnecessary. GRO csum_cnt is
> > initialized to skb->csum_level + 1 at the start of GRO processing.
> >
> > If I recall, the rule is that UDP GRO requires at least one non-zero
> > checksum to be verified. The idea is that if we end up computing
> > packet checksums on the host for inner checksums like TCP during GRO,
> > then that's negating the performance benefits of GRO. Had UDP check
> > not been zero then we would do checksum unnecessary conversion and so
> > csum_valid would be set for the remainded of GRO processing. The
> > existing code is following the rule I believe, so this may be working
> > as intended.
>
> Do you have any suggestion if I need do GRO as udp->check is zero?
> My previous modification which works fine as below:
>         if (NAPI_GRO_CB(skb)->encap_mark ||
>             (skb->ip_summed != CHECKSUM_PARTIAL &&
> +            skb->ip_summed != CHECKSUM_UNNECESSARY &&

That's effectively disabling the rule that we need a real checksum
calculation to proceed with GRO. Besides that, the device returning
one checksum-unnecessary level because UDP csum is zero is pretty
pointelss; we can just as easily deduce get to same state just by
looking at the field with CHECKSUM_NONE. What we really want to see
for GRO is a real checksum computation being done on the packet.

A few questions:

What type of packets are being GROed? Are these TCP? What performance
difference do you see with our patch? Can you try enabling UDP
checksums, and even RCO with VXLAN? With UDP encapsulation we
generally see better performance with checksum enabled since UDP
checksum offload is ubiquitous and we can easily convert
checksum-unnecessary (with non-zero csum) to checksum-complete.

Tom




>              NAPI_GRO_CB(skb)->csum_cnt == 0 &&
>              !NAPI_GRO_CB(skb)->csum_valid) ||
>             !udp_sk(sk)->gro_receive)
>                 goto out_unlock;
>
>
> >
> > Tom
> >
> >>>
> >>> .
> >>>
> >>
> >
> > .
> >
>

^ permalink raw reply

* Re: [PATCH net v5 2/2] net/mlx5e: Don't overwrite pedit action when multiple pedit used
From: Or Gerlitz @ 2019-01-29 20:17 UTC (permalink / raw)
  To: David Miller, Saeed Mahameed; +Cc: Linux Netdev List, Tonghao Zhang
In-Reply-To: <1548718086-20924-2-git-send-email-xiangxia.m.yue@gmail.com>

On Tue, Jan 29, 2019 at 8:05 PM <xiangxia.m.yue@gmail.com> wrote:
> From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
>
> In some case, we may use multiple pedit actions to modify packets.
> The command shown as below: the last pedit action is effective.
>
> $ tc filter add dev netdev_rep parent ffff: protocol ip prio 1    \
>         flower skip_sw ip_proto icmp dst_ip 3.3.3.3        \
>         action pedit ex munge ip dst set 192.168.1.100 pipe    \
>         action pedit ex munge eth src set 00:00:00:00:00:01 pipe    \
>         action pedit ex munge eth dst set 00:00:00:00:00:02 pipe    \
>         action csum ip pipe    \
>         action tunnel_key set src_ip 1.1.1.100 dst_ip 1.1.1.200 dst_port 4789 id 100 \
>         action mirred egress redirect dev vxlan0
>
> To fix it, we add max_mod_hdr_actions to mlx5e_tc_flow_parse_attr struction,
> max_mod_hdr_actions will store the max pedit action number we support and
> num_mod_hdr_actions indicates how many pedit action we used, and store all
> pedit action to mod_hdr_actions.
>
> Fixes: d79b6df6b10a ("net/mlx5e: Add parsing of TC pedit actions to HW format")
> Cc: Or Gerlitz <ogerlitz@mellanox.com>
> Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
> ---
> v3: Remove the unnecessary init.
> v2: Fix comment message and change tag from net-next to net.

Same here, this is good to go upstream, well done Tonghao!

^ permalink raw reply

* Re: [PATCH net v5 1/2] net/mlx5e: Update hw flows when encap source mac changed
From: Or Gerlitz @ 2019-01-29 20:16 UTC (permalink / raw)
  To: David Miller, Saeed Mahameed
  Cc: Linux Netdev List, Tonghao Zhang, Hadar Hen Zion
In-Reply-To: <1548718086-20924-1-git-send-email-xiangxia.m.yue@gmail.com>

On Tue, Jan 29, 2019 at 8:05 PM <xiangxia.m.yue@gmail.com> wrote:
>
> From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
>
> When we offload tc filters to hardware, hardware flows can
> be updated when mac of encap destination ip is changed.
> But we ignore one case, that the mac of local encap ip can
> be changed too, so we should also update them.
>
> To fix it, add route_dev in mlx5e_encap_entry struct to save
> the local encap netdevice, and when mac changed, kernel will
> flush all the neighbour on the netdevice and send NETEVENT_NEIGH_UPDATE
> event. The mlx5 driver will delete the flows and add them when neighbour
> available again.
>
> Fixes: 232c001398ae ("net/mlx5e: Add support to neighbour update flow")
> Cc: Hadar Hen Zion <hadarh@mellanox.com>
> Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>

This is good to go upstream, well done Tonghao!

^ permalink raw reply

* Re: [PATCH] ucc_geth: Reset BQL queue when stopping device
From: Li Yang @ 2019-01-29 19:50 UTC (permalink / raw)
  To: Mathias Thore
  Cc: Christophe Leroy, netdev@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org, David Gounaris, Joakim Tjernlund
In-Reply-To: <DM6PR10MB3721D7BA109A3823D9DACF1984970@DM6PR10MB3721.namprd10.prod.outlook.com>

On Tue, Jan 29, 2019 at 2:09 AM Mathias Thore
<Mathias.Thore@infinera.com> wrote:
>
> Is there a scenario where we are clearing the TX ring but don't want to reset the BQL TX queue?

Right now the function is also used on interface open/close, driver
removal and driver resumption besides the timeout situation. I think
the reseting BQL queue is either not neccessary or already called
explicitly for the other scenarios.

>
> I think it makes sense to keep it in ucc_geth_free_tx since the reason it is needed isn't the timeout per se, but rather the clearing of the TX ring. This way, it will be performed no matter why the driver ends up calling this function.

I don't see a consensus on when netdev_reset_queue() should be called
among existing drivers.  Doing it on buffer ring cleanup probably can
be future-proofing.  But if we want to use this approach, we can
remove the redundent netdev_reset_queue() calls in open/close
functions.

Regards,
Leo

>
> -----Original Message-----
> From: Li Yang [mailto:leoyang.li@nxp.com]
> Sent: Monday, 28 January 2019 22:37
> To: Mathias Thore <Mathias.Thore@infinera.com>
> Cc: Christophe Leroy <christophe.leroy@c-s.fr>; netdev@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; David Gounaris <David.Gounaris@infinera.com>; Joakim Tjernlund <Joakim.Tjernlund@infinera.com>
> Subject: Re: [PATCH] ucc_geth: Reset BQL queue when stopping device
>
> On Mon, Jan 28, 2019 at 8:37 AM Mathias Thore <Mathias.Thore@infinera.com> wrote:
> >
> > Hi,
> >
> >
> > This is what we observed: there was a storm on the medium so that our controller could not do its TX, resulting in timeout. When timeout occurs, the driver clears all descriptors from the TX queue. The function called in this patch is used to reflect this clearing also in the BQL layer. Without it, the controller would get stuck, unable to perform TX, even several minutes after the storm had ended. Bringing the device down and then up again would solve the problem, but this patch also solves it automatically.
>
> The explanation makes sense.  So this should only be required in the timeout scenario instead of other clean up scenarios like device shutdown?  If so, it probably it will be better to be done in ucc_geth_timeout_work()?
>
> >
> >
> > Some other drivers do the same, for example e1000e driver calls netdev_reset_queue in its e1000_clean_tx_ring function. It is possible that other drivers should do the same; I have no way of verifying this.
> >
> >
> > Regards,
> >
> > Mathias
> >
> > --
> >
> >
> > From: Christophe Leroy <christophe.leroy@c-s.fr>
> > Sent: Monday, January 28, 2019 10:48 AM
> > To: Mathias Thore; leoyang.li@nxp.com; netdev@vger.kernel.org;
> > linuxppc-dev@lists.ozlabs.org; David Gounaris; Joakim Tjernlund
> > Subject: Re: [PATCH] ucc_geth: Reset BQL queue when stopping device
> >
> >
> > CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
> >
> >
> > Hi,
> >
> > Le 28/01/2019 à 10:07, Mathias Thore a écrit :
> > > After a timeout event caused by for example a broadcast storm, when
> > > the MAC and PHY are reset, the BQL TX queue needs to be reset as
> > > well. Otherwise, the device will exhibit severe performance issues
> > > even after the storm has ended.
> >
> > What are the symptomns ?
> >
> > Is this reset needed on any network driver in that case, or is it
> > something particular for the ucc_geth ?
> > For instance, the freescale fs_enet doesn't have that reset. Should it
> > have it too ?
> >
> > Christophe
> >
> > >
> > > Co-authored-by: David Gounaris <david.gounaris@infinera.com>
> > > Signed-off-by: Mathias Thore <mathias.thore@infinera.com>
> > > ---
> > >   drivers/net/ethernet/freescale/ucc_geth.c | 2 ++
> > >   1 file changed, 2 insertions(+)
> > >
> > > diff --git a/drivers/net/ethernet/freescale/ucc_geth.c
> > > b/drivers/net/ethernet/freescale/ucc_geth.c
> > > index c3d539e209ed..eb3e65e8868f 100644
> > > --- a/drivers/net/ethernet/freescale/ucc_geth.c
> > > +++ b/drivers/net/ethernet/freescale/ucc_geth.c
> > > @@ -1879,6 +1879,8 @@ static void ucc_geth_free_tx(struct ucc_geth_private *ugeth)
> > >       u16 i, j;
> > >       u8 __iomem *bd;
> > >
> > > +     netdev_reset_queue(ugeth->ndev);
> > > +
> > >       ug_info = ugeth->ug_info;
> > >       uf_info = &ug_info->uf_info;
> > >
> > >
> >

^ permalink raw reply

* Re: [PATCH net] net: set default network namespace in init_dummy_netdev()
From: David Miller @ 2019-01-29 19:30 UTC (permalink / raw)
  To: jelsasser
  Cc: josh, ecree, ktkhai, jiri, petrm, edumazet, amritha.nambiar,
	alexander.h.duyck, lirongqing, netdev, linux-kernel
In-Reply-To: <20190126223835.14613-1-jelsasser@appneta.com>

From: Josh Elsasser <jelsasser@appneta.com>
Date: Sat, 26 Jan 2019 14:38:33 -0800

> Assign a default net namespace to netdevs created by init_dummy_netdev().
> Fixes a NULL pointer dereference caused by busy-polling a socket bound to
> an iwlwifi wireless device, which bumps the per-net BUSYPOLLRXPACKETS stat
> if napi_poll() received packets:
> 
>   BUG: unable to handle kernel NULL pointer dereference at 0000000000000190
>   IP: napi_busy_loop+0xd6/0x200
>   Call Trace:
>     sock_poll+0x5e/0x80
>     do_sys_poll+0x324/0x5a0
>     SyS_poll+0x6c/0xf0
>     do_syscall_64+0x6b/0x1f0
>     entry_SYSCALL_64_after_hwframe+0x3d/0xa2
> 
> Fixes: 7db6b048da3b ("net: Commonize busy polling code to focus on napi_id instead of socket")
> Signed-off-by: Josh Elsasser <jelsasser@appneta.com>

Applied and queued up for -stable.

^ permalink raw reply

* Re: [PATCH v4 4/4] can: tcan4x5x: Add tcan4x5x driver to the kernel
From: Dan Murphy @ 2019-01-29 19:27 UTC (permalink / raw)
  To: Wolfgang Grandegger, mkl, davem, b29396; +Cc: linux-can, netdev, linux-kernel
In-Reply-To: <037720c9-4846-eb11-1d6a-b99d647d21d6@grandegger.com>

Wolfgang

Sorry for the late reply

On 1/22/19 4:03 AM, Wolfgang Grandegger wrote:
> Hello,
> 
> Am 17.01.19 um 21:06 schrieb Dan Murphy:
>> Add the TCAN4x5x SPI CAN driver.  This device
>> uses the Bosch MCAN IP core along with a SPI
>> interface map.  Leverage the MCAN common core
>> code to manage the MCAN IP.
>>
>> This device has a special method to indicate a
>> write/read operation on the data payload.
>>
>> Signed-off-by: Dan Murphy <dmurphy@ti.com>
>> ---
>>  drivers/net/can/m_can/Kconfig    |   6 +
>>  drivers/net/can/m_can/tcan4x5x.c | 529 +++++++++++++++++++++++++++++++
>>  2 files changed, 535 insertions(+)
>>  create mode 100644 drivers/net/can/m_can/tcan4x5x.c
>>
>> diff --git a/drivers/net/can/m_can/Kconfig b/drivers/net/can/m_can/Kconfig
>> index b1a9358b7660..b38959b3b8f1 100644
>> --- a/drivers/net/can/m_can/Kconfig
>> +++ b/drivers/net/can/m_can/Kconfig
>> @@ -15,3 +15,9 @@ config CAN_M_CAN_PLATFORM
>>  	tristate "Bosch M_CAN devices"
>>  	---help---
>>  	  Say Y here if you want to support for Bosch M_CAN controller.
>> +
>> +config CAN_M_CAN_TCAN4X5X
>> +	depends on CAN_M_CAN
>> +	tristate "TCAN4X5X M_CAN device"
>> +	---help---
>> +	  Say Y here if you want to support for TI M_CAN controller.
>> diff --git a/drivers/net/can/m_can/tcan4x5x.c b/drivers/net/can/m_can/tcan4x5x.c
>> new file mode 100644
>> index 000000000000..3cd6cd5052b6
>> --- /dev/null
>> +++ b/drivers/net/can/m_can/tcan4x5x.c
>> @@ -0,0 +1,529 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// SPI to CAN driver for the Texas Instruments TCAN4x5x
>> +// Copyright (C) 2018-19 Texas Instruments Incorporated - http://www.ti.com/
>> +
>> +#include <linux/regmap.h>
>> +#include <linux/spi/spi.h>
>> +
>> +#include <linux/regulator/consumer.h>
>> +#include <linux/gpio/consumer.h>
>> +
>> +#include "m_can_platform.h"
>> +
>> +#define DEVICE_NAME "tcan4x5x"
>> +#define TCAN4X5X_EXT_CLK_DEF	40000000
>> +
>> +#define TCAN4X5X_DEV_ID0	0x00
>> +#define TCAN4X5X_DEV_ID1	0x04
>> +#define TCAN4X5X_REV		0x08
>> +#define TCAN4X5X_STATUS		0x0C
>> +#define TCAN4X5X_ERROR_STATUS	0x10
>> +#define TCAN4X5X_CONTROL	0x14
>> +
>> +#define TCAN4X5X_CONFIG		0x800
>> +#define TCAN4X5X_TS_PRESCALE	0x804
>> +#define TCAN4X5X_TEST_REG	0x808
>> +#define TCAN4X5X_INT_FLAGS	0x820
>> +#define TCAN4X5X_MCAN_INT_REG	0x824
>> +#define TCAN4X5X_INT_EN		0x830
>> +
>> +
>> +/* Interrupt bits */
>> +#define TCAN4X5X_CANBUSTERMOPEN_INT_EN	BIT(30)
>> +#define TCAN4X5X_CANHCANL_INT_EN	BIT(29)
>> +#define TCAN4X5X_CANHBAT_INT_EN		BIT(28)
>> +#define TCAN4X5X_CANLGND_INT_EN		BIT(27)
>> +#define TCAN4X5X_CANBUSOPEN_INT_EN	BIT(26)
>> +#define TCAN4X5X_CANBUSGND_INT_EN	BIT(25)
>> +#define TCAN4X5X_CANBUSBAT_INT_EN	BIT(24)
>> +#define TCAN4X5X_UVSUP_INT_EN		BIT(22)
>> +#define TCAN4X5X_UVIO_INT_EN		BIT(21)
>> +#define TCAN4X5X_TSD_INT_EN		BIT(19)
>> +#define TCAN4X5X_ECCERR_INT_EN		BIT(16)
>> +#define TCAN4X5X_CANINT_INT_EN		BIT(15)
>> +#define TCAN4X5X_LWU_INT_EN		BIT(14)
>> +#define TCAN4X5X_CANSLNT_INT_EN		BIT(10)
>> +#define TCAN4X5X_CANDOM_INT_EN		BIT(8)
>> +#define TCAN4X5X_CANBUS_ERR_INT_EN	BIT(5)
>> +#define TCAN4X5X_BUS_FAULT		BIT(4)
>> +#define TCAN4X5X_MCAN_INT		BIT(1)
>> +#define TCAN4X5X_ENABLE_TCAN_INT	(TCAN4X5X_MCAN_INT | \
>> +					TCAN4X5X_BUS_FAULT | \
>> +					TCAN4X5X_CANBUS_ERR_INT_EN | \
>> +					TCAN4X5X_CANINT_INT_EN)
>> +
>> +/* MCAN Interrupt bits */
>> +#define TCAN4X5X_MCAN_IR_ARA		BIT(29)
>> +#define TCAN4X5X_MCAN_IR_PED		BIT(28)
>> +#define TCAN4X5X_MCAN_IR_PEA		BIT(27)
>> +#define TCAN4X5X_MCAN_IR_WD		BIT(26)
>> +#define TCAN4X5X_MCAN_IR_BO		BIT(25)
>> +#define TCAN4X5X_MCAN_IR_EW		BIT(24)
>> +#define TCAN4X5X_MCAN_IR_EP		BIT(23)
>> +#define TCAN4X5X_MCAN_IR_ELO		BIT(22)
>> +#define TCAN4X5X_MCAN_IR_BEU		BIT(21)
>> +#define TCAN4X5X_MCAN_IR_BEC		BIT(20)
>> +#define TCAN4X5X_MCAN_IR_DRX		BIT(19)
>> +#define TCAN4X5X_MCAN_IR_TOO		BIT(18)
>> +#define TCAN4X5X_MCAN_IR_MRAF		BIT(17)
>> +#define TCAN4X5X_MCAN_IR_TSW		BIT(16)
>> +#define TCAN4X5X_MCAN_IR_TEFL		BIT(15)
>> +#define TCAN4X5X_MCAN_IR_TEFF		BIT(14)
>> +#define TCAN4X5X_MCAN_IR_TEFW		BIT(13)
>> +#define TCAN4X5X_MCAN_IR_TEFN		BIT(12)
>> +#define TCAN4X5X_MCAN_IR_TFE		BIT(11)
>> +#define TCAN4X5X_MCAN_IR_TCF		BIT(10)
>> +#define TCAN4X5X_MCAN_IR_TC		BIT(9)
>> +#define TCAN4X5X_MCAN_IR_HPM		BIT(8)
>> +#define TCAN4X5X_MCAN_IR_RF1L		BIT(7)
>> +#define TCAN4X5X_MCAN_IR_RF1F		BIT(6)
>> +#define TCAN4X5X_MCAN_IR_RF1W		BIT(5)
>> +#define TCAN4X5X_MCAN_IR_RF1N		BIT(4)
>> +#define TCAN4X5X_MCAN_IR_RF0L		BIT(3)
>> +#define TCAN4X5X_MCAN_IR_RF0F		BIT(2)
>> +#define TCAN4X5X_MCAN_IR_RF0W		BIT(1)
>> +#define TCAN4X5X_MCAN_IR_RF0N		BIT(0)
> 
> These bits are already defined in the common header file.
> 

These are TCAN specific interrupt enable bits there are not in the Bosch register set

>> +#define TCAN4X5X_ENABLE_MCAN_INT	(TCAN4X5X_MCAN_IR_TC | \
>> +					TCAN4X5X_MCAN_IR_RF0N | \
>> +					TCAN4X5X_MCAN_IR_RF1N | \
>> +					TCAN4X5X_MCAN_IR_RF0F | \
>> +					TCAN4X5X_MCAN_IR_RF1F)
>> +#define TCAN4X5X_MRAM_START	0x8000
>> +#define TCAN4X5X_MCAN_OFFSET	0x1000
>> +#define TCAN4X5X_MAX_REGISTER	0x8fff
>> +
>> +#define TCAN4X5X_CLEAR_ALL_INT	0xffffffff
>> +#define TCAN4X5X_SET_ALL_INT	0xffffffff
>> +
>> +#define TCAN4X5X_WRITE_CMD	(0x61 << 24)
>> +#define TCAN4X5X_READ_CMD	(0x41 << 24)
>> +
>> +#define TCAN4X5X_MODE_SEL_MASK		(BIT(7) | BIT(6))
>> +#define TCAN4X5X_MODE_SLEEP		0x00
>> +#define TCAN4X5X_MODE_STANDBY		BIT(6)
>> +#define TCAN4X5X_MODE_NORMAL		BIT(7)
>> +
>> +#define TCAN4X5X_SW_RESET	BIT(2)
>> +
>> +#define TCAN4X5X_MCAN_CONFIGURED	BIT(5)
>> +#define TCAN4X5X_WATCHDOG_EN		BIT(3)
>> +#define TCAN4X5X_WD_60_MS_TIMER		0
>> +#define TCAN4X5X_WD_600_MS_TIMER	BIT(28)
>> +#define TCAN4X5X_WD_3_S_TIMER		BIT(29)
>> +#define TCAN4X5X_WD_6_S_TIMER		(BIT(28) | BIT(29))
>> +
>> +struct tcan4x5x_priv {
>> +	struct regmap *regmap;
>> +	struct spi_device *spi;
>> +	struct mutex tcan4x5x_lock; /* SPI device lock */
>> +
>> +	struct m_can_classdev *mcan_dev;
>> +
>> +	struct gpio_desc *reset_gpio;
>> +	struct gpio_desc *interrupt_gpio;
>> +	struct gpio_desc *device_wake_gpio;
>> +	struct gpio_desc *device_state_gpio;
>> +	struct regulator *power;
>> +
>> +	/* Register based ip */
>> +	int mram_start;
>> +	int reg_offset;
>> +};
>> +
>> +static struct can_bittiming_const tcan4x5x_bittiming_const = {
>> +	.name = DEVICE_NAME,
>> +	.tseg1_min = 2,
>> +	.tseg1_max = 31,
>> +	.tseg2_min = 2,
>> +	.tseg2_max = 16,
>> +	.sjw_max = 16,
>> +	.brp_min = 1,
>> +	.brp_max = 32,
>> +	.brp_inc = 1,
>> +};
>> +
>> +static struct can_bittiming_const tcan4x5x_data_bittiming_const = {
>> +	.name = DEVICE_NAME,
>> +	.tseg1_min = 1,
>> +	.tseg1_max = 32,
>> +	.tseg2_min = 1,
>> +	.tseg2_max = 16,
>> +	.sjw_max = 16,
>> +	.brp_min = 1,
>> +	.brp_max = 32,
>> +	.brp_inc = 1,
>> +};
>> +
>> +static void tcan4x5x_check_wake(struct tcan4x5x_priv *priv)
>> +{
>> +	int wake_state = 0;
>> +
>> +	if (priv->device_state_gpio)
>> +		wake_state = gpiod_get_value(priv->device_state_gpio);
>> +
>> +	if (priv->device_wake_gpio && wake_state) {
>> +		gpiod_set_value(priv->device_wake_gpio, 1);
>> +		udelay(100);
>> +		gpiod_set_value(priv->device_wake_gpio, 0);
>> +		udelay(100);
>> +		gpiod_set_value(priv->device_wake_gpio, 1);
>> +	}
>> +}
>> +
>> +static int regmap_spi_gather_write(void *context, const void *reg,
>> +				   size_t reg_len, const void *val,
>> +				   size_t val_len)
>> +{
>> +	struct device *dev = context;
>> +	struct spi_device *spi = to_spi_device(dev);
>> +	struct spi_message m;
>> +	u32 addr;
>> +	struct spi_transfer t[2] = {{ .tx_buf = &addr, .len = reg_len, .cs_change = 0,},
>> +				   { .tx_buf = val, .len = val_len, },};
>> +
>> +	addr = TCAN4X5X_WRITE_CMD | (*((u16 *)reg) << 8) | val_len >> 3;
>> +
>> +	spi_message_init(&m);
>> +	spi_message_add_tail(&t[0], &m);
>> +	spi_message_add_tail(&t[1], &m);
>> +
>> +	return spi_sync(spi, &m);
>> +}
>> +
>> +static int tcan4x5x_regmap_write(void *context, const void *data, size_t count)
>> +{
>> +	u16 *reg = (u16 *)(data);
>> +	const u32 *val = data + 4;
>> +
>> +	return regmap_spi_gather_write(context, reg, 4, val, count);
>> +}
>> +
>> +static int regmap_spi_async_write(void *context,
>> +				  const void *reg, size_t reg_len,
>> +				  const void *val, size_t val_len,
>> +				  struct regmap_async *a)
>> +{
>> +	return -ENOTSUPP;
>> +}
>> +
>> +static struct regmap_async *regmap_spi_async_alloc(void)
>> +{
>> +	return NULL;
>> +}
>> +
>> +static int tcan4x5x_regmap_read(void *context,
>> +				const void *reg, size_t reg_size,
>> +				void *val, size_t val_size)
>> +{
>> +	struct device *dev = context;
>> +	struct spi_device *spi = to_spi_device(dev);
>> +
>> +	u32 addr = TCAN4X5X_READ_CMD | (*((u16 *)reg) << 8) | val_size >> 2;
>> +
>> +	return spi_write_then_read(spi, &addr, reg_size, (u32 *)val, val_size);
>> +}
>> +
>> +static struct regmap_bus tcan4x5x_bus = {
>> +	.write = tcan4x5x_regmap_write,
>> +	.gather_write = regmap_spi_gather_write,
>> +	.async_write = regmap_spi_async_write,
>> +	.async_alloc = regmap_spi_async_alloc,
>> +	.read = tcan4x5x_regmap_read,
>> +	.read_flag_mask = 0x00,
>> +	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
>> +	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
>> +};
>> +
>> +static u32 tcan4x5x_read_reg(struct m_can_classdev *m_can_class, int reg)
>> +{
>> +	struct tcan4x5x_priv *priv = (struct tcan4x5x_priv *)m_can_class->device_data;
>> +	u32 val;
>> +
>> +	tcan4x5x_check_wake(priv);
>> +
>> +	regmap_read(priv->regmap, priv->reg_offset + reg, &val);
>> +
>> +	return val;
>> +}
>> +
>> +static u32 tcan4x5x_read_fifo(struct m_can_classdev *m_can_class,
>> +			      int addr_offset)
>> +{
>> +	struct tcan4x5x_priv *priv = (struct tcan4x5x_priv *)m_can_class->device_data;
>> +	u32 val;
>> +
>> +	tcan4x5x_check_wake(priv);
>> +
>> +	regmap_read(priv->regmap, priv->mram_start + addr_offset, &val);
>> +
>> +	return val;
>> +}
>> +
>> +static int tcan4x5x_write_reg(struct m_can_classdev *m_can_class,
>> +			      int reg, int val)
>> +{
>> +	struct tcan4x5x_priv *priv = (struct tcan4x5x_priv *)m_can_class->device_data;
>> +
>> +	tcan4x5x_check_wake(priv);
>> +
>> +	return regmap_write(priv->regmap, priv->reg_offset + reg, val);
>> +}
>> +
>> +static int tcan4x5x_write_fifo(struct m_can_classdev *m_can_class,
>> +			       int addr_offset, int val)
>> +{
>> +	struct tcan4x5x_priv *priv = (struct tcan4x5x_priv *)m_can_class->device_data;
>> +
>> +	tcan4x5x_check_wake(priv);
>> +
>> +	return regmap_write(priv->regmap, priv->mram_start + addr_offset, val);
>> +}
>> +
>> +static int tcan4x5x_power_enable(struct regulator *reg, int enable)
>> +{
>> +	if (IS_ERR_OR_NULL(reg))
>> +		return 0;
>> +
>> +	if (enable)
>> +		return regulator_enable(reg);
>> +	else
>> +		return regulator_disable(reg);
>> +}
>> +
>> +static int tcan4x5x_write_tcan_reg(struct m_can_classdev *m_can_class,
>> +				   int reg, int val)
>> +{
>> +	struct tcan4x5x_priv *priv = (struct tcan4x5x_priv *)m_can_class->device_data;
>> +
>> +	tcan4x5x_check_wake(priv);
>> +
>> +	return regmap_write(priv->regmap, reg, val);
>> +}
>> +
>> +static int tcan4x5x_clear_interrupts(struct m_can_classdev *class_dev)
>> +{
>> +	struct tcan4x5x_priv *tcan4x5x = (struct tcan4x5x_priv *)class_dev->device_data;
>> +	int ret;
>> +
>> +	tcan4x5x_check_wake(tcan4x5x);
>> +
>> +	ret = tcan4x5x_write_tcan_reg(class_dev, TCAN4X5X_STATUS,
>> +				      TCAN4X5X_CLEAR_ALL_INT);
>> +	if (ret)
>> +		return -EIO;
>> +
>> +	ret = tcan4x5x_write_tcan_reg(class_dev, TCAN4X5X_MCAN_INT_REG,
>> +				      TCAN4X5X_ENABLE_MCAN_INT);
>> +	if (ret)
>> +		return -EIO;
>> +
>> +	ret = tcan4x5x_write_tcan_reg(class_dev, TCAN4X5X_INT_FLAGS,
>> +				      TCAN4X5X_CLEAR_ALL_INT);
>> +	if (ret)
>> +		return -EIO;
>> +
>> +
>> +	ret = tcan4x5x_write_tcan_reg(class_dev, TCAN4X5X_ERROR_STATUS,
>> +				      TCAN4X5X_CLEAR_ALL_INT);
>> +	if (ret)
>> +		return -EIO;
>> +
>> +	return ret;
>> +}
>> +
>> +static int tcan4x5x_init(struct m_can_classdev *class_dev)
>> +{
>> +	struct tcan4x5x_priv *tcan4x5x = (struct tcan4x5x_priv *)class_dev->device_data;
>> +	int ret;
>> +
>> +	tcan4x5x_check_wake(tcan4x5x);
>> +
>> +	ret = tcan4x5x_clear_interrupts(class_dev);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = tcan4x5x_write_tcan_reg(class_dev, TCAN4X5X_INT_EN,
>> +				      TCAN4X5X_ENABLE_TCAN_INT);
>> +	if (ret)
>> +		return -EIO;
>> +
>> +	ret = regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG,
>> +				 TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_NORMAL);
>> +	if (ret)
>> +		return -EIO;
>> +
>> +	/* Zero out the MCAN buffers */
>> +	m_can_init_ram(class_dev);
>> +
>> +	return ret;
>> +}
>> +
>> +static int tcan4x5x_parse_config(struct m_can_classdev *class_dev)
>> +{
>> +	struct tcan4x5x_priv *tcan4x5x = (struct tcan4x5x_priv *)class_dev->device_data;
>> +
>> +	tcan4x5x->reset_gpio = devm_gpiod_get_optional(class_dev->dev,
>> +						       "reset", GPIOD_OUT_LOW);
>> +	if (IS_ERR(tcan4x5x->reset_gpio))
>> +		tcan4x5x->reset_gpio = NULL;
>> +
>> +	tcan4x5x->device_wake_gpio = devm_gpiod_get_optional(class_dev->dev,
>> +							     "device-wake",
>> +							     GPIOD_OUT_HIGH);
>> +	if (IS_ERR(tcan4x5x->device_wake_gpio))
>> +		tcan4x5x->device_wake_gpio = NULL;
>> +
>> +	tcan4x5x->device_state_gpio = devm_gpiod_get_optional(class_dev->dev,
>> +							      "device-state",
>> +							      GPIOD_IN);
>> +	if (IS_ERR(tcan4x5x->device_state_gpio))
>> +		tcan4x5x->device_state_gpio = NULL;
>> +
>> +	tcan4x5x->interrupt_gpio = devm_gpiod_get(class_dev->dev,
>> +						  "data-ready", GPIOD_IN);
>> +	if (IS_ERR(tcan4x5x->interrupt_gpio)) {
>> +		dev_err(class_dev->dev, "data-ready gpio not defined\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	class_dev->net->irq = gpiod_to_irq(tcan4x5x->interrupt_gpio);
>> +
>> +	tcan4x5x->power = devm_regulator_get_optional(class_dev->dev,
>> +						      "vsup");
>> +	if (PTR_ERR(tcan4x5x->power) == -EPROBE_DEFER)
>> +		return -EPROBE_DEFER;
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct regmap_config tcan4x5x_regmap = {
>> +	.reg_bits = 32,
>> +	.val_bits = 32,
>> +	.cache_type = REGCACHE_NONE,
>> +	.max_register = TCAN4X5X_MAX_REGISTER,
>> +};
>> +
>> +static int tcan4x5x_can_probe(struct spi_device *spi)
>> +{
>> +	struct tcan4x5x_priv *priv;
>> +	struct m_can_classdev *mcan_class;
>> +	int freq, ret;
>> +
>> +	mcan_class = m_can_core_allocate_dev(&spi->dev);
>> +	priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
>> +	if (!priv)
>> +		return -ENOMEM;
>> +
>> +	mcan_class->device_data = priv;
>> +
>> +	m_can_core_get_clocks(mcan_class);
>> +	if (IS_ERR(mcan_class->cclk)) {
>> +		dev_err(&spi->dev, "no CAN clock source defined\n");
>> +		freq = TCAN4X5X_EXT_CLK_DEF;
>> +	} else {
>> +		freq = clk_get_rate(mcan_class->cclk);
>> +	}
>> +
>> +	/* Sanity check */
>> +	if (freq < 20000000 || freq > TCAN4X5X_EXT_CLK_DEF)
>> +		return -ERANGE;
>> +
>> +	priv->reg_offset = TCAN4X5X_MCAN_OFFSET;
>> +	priv->mram_start = TCAN4X5X_MRAM_START;
>> +	priv->spi = spi;
>> +	priv->mcan_dev = mcan_class;
>> +
>> +	mcan_class->pm_clock_support = 0;
>> +	mcan_class->can.clock.freq = freq;
>> +	mcan_class->dev = &spi->dev;
>> +
>> +	mcan_class->device_init = &tcan4x5x_init;
>> +	mcan_class->read_reg = &tcan4x5x_read_reg;
>> +	mcan_class->write_reg = &tcan4x5x_write_reg;
>> +	mcan_class->write_fifo = &tcan4x5x_write_fifo;
>> +	mcan_class->read_fifo = &tcan4x5x_read_fifo;
>> +	mcan_class->clr_dev_interrupts = &tcan4x5x_clear_interrupts;
>> +	mcan_class->is_peripherial = true;
>> +
>> +	mcan_class->bit_timing = &tcan4x5x_bittiming_const;
>> +	mcan_class->data_timing = &tcan4x5x_data_bittiming_const;
>> +
>> +	spi_set_drvdata(spi, priv);
>> +
>> +	ret = tcan4x5x_parse_config(mcan_class);
>> +	if (ret)
>> +		goto out_clk;
>> +
>> +	/* Configure the SPI bus */
>> +	spi->bits_per_word = 32;
>> +	ret = spi_setup(spi);
>> +	if (ret)
>> +		goto out_clk;
>> +
>> +	priv->regmap = devm_regmap_init(&spi->dev, &tcan4x5x_bus,
>> +					&spi->dev, &tcan4x5x_regmap);
>> +
>> +	mutex_init(&priv->tcan4x5x_lock);
>> +
>> +	tcan4x5x_power_enable(priv->power, 1);
>> +
>> +	ret = m_can_core_register(mcan_class);
>> +	if (ret)
>> +		goto reg_err;
>> +
>> +	netdev_info(mcan_class->net, "TCAN4X5X successfully initialized.\n");
>> +	return 0;
>> +
>> +reg_err:
>> +	tcan4x5x_power_enable(priv->power, 0);
>> +out_clk:
>> +	if (!IS_ERR(mcan_class->cclk)) {
>> +		clk_disable_unprepare(mcan_class->cclk);
>> +		clk_disable_unprepare(mcan_class->hclk);
>> +	}
>> +
>> +	dev_err(&spi->dev, "Probe failed, err=%d\n", -ret);
>> +	return ret;
>> +}
>> +
>> +static int tcan4x5x_can_remove(struct spi_device *spi)
>> +{
>> +	struct tcan4x5x_priv *priv = spi_get_drvdata(spi);
>> +
>> +	tcan4x5x_power_enable(priv->power, 0);
>> +
>> +	m_can_core_unregister(priv->mcan_dev);
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct of_device_id tcan4x5x_of_match[] = {
>> +	{ .compatible = "ti,tcan4x5x", },
>> +	{ }
>> +};
>> +MODULE_DEVICE_TABLE(of, tcan4x5x_of_match);
>> +
>> +static const struct spi_device_id tcan4x5x_id_table[] = {
>> +	{
>> +		.name		= "tcan4x5x",
>> +		.driver_data	= 0,
>> +	},
>> +	{ }
>> +};
>> +MODULE_DEVICE_TABLE(spi, tcan4x5x_id_table);
>> +
>> +static struct spi_driver tcan4x5x_can_driver = {
>> +	.driver = {
>> +		.name = DEVICE_NAME,
>> +		.of_match_table = tcan4x5x_of_match,
>> +		.pm = NULL,
>> +	},
>> +	.id_table = tcan4x5x_id_table,
>> +	.probe = tcan4x5x_can_probe,
>> +	.remove = tcan4x5x_can_remove,
>> +};
>> +module_spi_driver(tcan4x5x_can_driver);
>> +
>> +MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
>> +MODULE_DESCRIPTION("Texas Instruments TCAN4x5x CAN driver");
>> +MODULE_LICENSE("GPL v2");
> 
> Curious to hear about the performance of M_CAN connected via SPI. Does
> it miss or drop messages?
> 

Here is some cangen data we have.

We can probably speed it up but we want to get the code functional first.

/home/root/can/ip link set can0 up type can bitrate 1000000 dbitrate 10000000 fd on
root@am335x-evm:~/can# cat /proc/net/can/stats 
     5681 transmitted frames (TXF)
     5681 received frames (RXF)
        0 matched frames (RXMF)

        0 % total match ratio (RXMR)
      167 frames/s total tx rate (TXR)
      167 frames/s total rx rate (RXR)

        0 % current match ratio (CRXMR)
        0 frames/s current tx rate (CTXR)
        0 frames/s current rx rate (CRXR)

        0 % max match ratio (MRXMR)
      224 frames/s max tx rate (MTXR)
      222 frames/s max rx rate (MRXR)

> Thanks for your patience,
> 
> Wolfgang.
> 


-- 
------------------
Dan Murphy

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox