lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 29 Jan 2019 23:57:32 +0100
From:   Pavel Machek <pavel@....cz>
To:     Andrew Lunn <andrew@...n.ch>
Cc:     netdev@...r.kernel.org, f.fainelli@...il.com, buytenh@...vell.com,
        buytenh@...tstofly.org, nico@...vell.com
Subject: mv88e6xxx -- DSA support for Marvell 88e6065 switch (and maybe
 88e6060?)

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@...x.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

View attachment "delme2" of type "text/plain" (34455 bytes)

Download attachment "signature.asc" of type "application/pgp-signature" (182 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ