All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH net-next 3/3] net: dsa: mv88e6xxx: add support for 88E6393X from Amethyst family
@ 2020-08-27 15:19 kernel test robot
  0 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2020-08-27 15:19 UTC (permalink / raw)
  To: kbuild

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

CC: kbuild-all(a)lists.01.org
In-Reply-To: <20200819153816.30834-4-marek.behun@nic.cz>
References: <20200819153816.30834-4-marek.behun@nic.cz>
TO: "Marek Behún" <marek.behun@nic.cz>
TO: netdev(a)vger.kernel.org
CC: Russell King <rmk+kernel@armlinux.org.uk>
CC: Andrew Lunn <andrew@lunn.ch>
CC: Florian Fainelli <f.fainelli@gmail.com>
CC: Vivien Didelot <vivien.didelot@gmail.com>
CC: "Marek Behún" <marek.behun@nic.cz>

Hi "Marek,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Marek-Beh-n/net-dsa-mv88e6xxx-Add-Amethyst-88E6393X/20200819-234008
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git e3ec1e8ca02b7e6c935bba3f9b6da86c2e57d2eb
:::::: branch date: 8 days ago
:::::: commit date: 8 days ago
config: openrisc-randconfig-m031-20200827 (attached as .config)
compiler: or1k-linux-gcc (GCC) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

New smatch warnings:
drivers/net/dsa/mv88e6xxx/serdes.c:547 mv88e6393x_serdes_get_lane() warn: impossible condition '(*lane == -1) => (0-255 == (-1))'

Old smatch warnings:
drivers/net/dsa/mv88e6xxx/serdes.c:428 mv88e6341_serdes_get_lane() warn: impossible condition '(*lane == -1) => (0-255 == (-1))'
drivers/net/dsa/mv88e6xxx/serdes.c:451 mv88e6390_serdes_get_lane() warn: impossible condition '(*lane == -1) => (0-255 == (-1))'
drivers/net/dsa/mv88e6xxx/serdes.c:526 mv88e6390x_serdes_get_lane() warn: impossible condition '(*lane == -1) => (0-255 == (-1))'

# https://github.com/0day-ci/linux/commit/ec03405fdc7e66a29e2fdec65eadc261b10d441d
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Marek-Beh-n/net-dsa-mv88e6xxx-Add-Amethyst-88E6393X/20200819-234008
git checkout ec03405fdc7e66a29e2fdec65eadc261b10d441d
vim +547 drivers/net/dsa/mv88e6xxx/serdes.c

a8c01c0d941d2f Andrew Lunn 2018-08-09  528  
ec03405fdc7e66 Marek Behún 2020-08-19  529  int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
ec03405fdc7e66 Marek Behún 2020-08-19  530  {
ec03405fdc7e66 Marek Behún 2020-08-19  531  	u8 cmode = chip->ports[port].cmode;
ec03405fdc7e66 Marek Behún 2020-08-19  532  
ec03405fdc7e66 Marek Behún 2020-08-19  533  	*lane = -1;
ec03405fdc7e66 Marek Behún 2020-08-19  534  	switch (port) {
ec03405fdc7e66 Marek Behún 2020-08-19  535  	case 0:
ec03405fdc7e66 Marek Behún 2020-08-19  536  	case 9:
ec03405fdc7e66 Marek Behún 2020-08-19  537  	case 10:
ec03405fdc7e66 Marek Behún 2020-08-19  538  		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
ec03405fdc7e66 Marek Behún 2020-08-19  539  		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
ec03405fdc7e66 Marek Behún 2020-08-19  540  		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
ec03405fdc7e66 Marek Behún 2020-08-19  541  		    cmode == MV88E6393_PORT_STS_CMODE_5GBASER ||
ec03405fdc7e66 Marek Behún 2020-08-19  542  		    cmode == MV88E6393_PORT_STS_CMODE_10GBASER ||
ec03405fdc7e66 Marek Behún 2020-08-19  543  		    cmode == MV88E6393_PORT_STS_CMODE_USXGMII)
ec03405fdc7e66 Marek Behún 2020-08-19  544  			*lane = port;
ec03405fdc7e66 Marek Behún 2020-08-19  545  	}
ec03405fdc7e66 Marek Behún 2020-08-19  546  
ec03405fdc7e66 Marek Behún 2020-08-19 @547  	return *lane == -1 ? -ENODEV : 0;
ec03405fdc7e66 Marek Behún 2020-08-19  548  }
ec03405fdc7e66 Marek Behún 2020-08-19  549  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 28496 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next 3/3] net: dsa: mv88e6xxx: add support for 88E6393X from Amethyst family
  2020-08-22 16:49   ` Andrew Lunn
@ 2020-08-22 18:55     ` Russell King - ARM Linux admin
  0 siblings, 0 replies; 5+ messages in thread
From: Russell King - ARM Linux admin @ 2020-08-22 18:55 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: Marek Behún, netdev, Florian Fainelli, Vivien Didelot

On Sat, Aug 22, 2020 at 06:49:46PM +0200, Andrew Lunn wrote:
> > --- a/drivers/net/dsa/mv88e6xxx/port.c
> > +++ b/drivers/net/dsa/mv88e6xxx/port.c
> > @@ -187,11 +187,16 @@ static int mv88e6xxx_port_set_speed_duplex(struct mv88e6xxx_chip *chip,
> >  		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
> >  		break;
> >  	case 2500:
> > -		if (alt_bit)
> > -			ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
> > -				MV88E6390_PORT_MAC_CTL_ALTSPEED;
> > +		if (chip->info->family == MV88E6XXX_FAMILY_6393)
> > +			ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
> >  		else
> >  			ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000;
> > +		if (alt_bit)
> > +			ctrl |= MV88E6390_PORT_MAC_CTL_ALTSPEED;
> > +		break;
> > +	case 5000:
> > +		ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
> > +			MV88E6390_PORT_MAC_CTL_ALTSPEED;
> >  		break;
> >  	case 10000:
> >  		/* all bits set, fall through... */
> 
> This is getting more and more complex. Maybe it is time to refactor it?

However, please note that the speed/duplex that is passed through
phylink from phylib is the _media_ speed.  If you are using RXAUI
(for example) then the link should be running at 10G speed,
especially if the PHY is doing rate matching.  The only other thing
is if rate matching is in use but no flow control, then limiting the
egress rate is needed.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next 3/3] net: dsa: mv88e6xxx: add support for 88E6393X from Amethyst family
  2020-08-19 15:38 ` [PATCH net-next 3/3] net: dsa: mv88e6xxx: add support for 88E6393X from Amethyst family Marek Behún
  2020-08-22 16:48   ` Andrew Lunn
@ 2020-08-22 16:49   ` Andrew Lunn
  2020-08-22 18:55     ` Russell King - ARM Linux admin
  1 sibling, 1 reply; 5+ messages in thread
From: Andrew Lunn @ 2020-08-22 16:49 UTC (permalink / raw)
  To: Marek Behún; +Cc: netdev, Russell King, Florian Fainelli, Vivien Didelot

> --- a/drivers/net/dsa/mv88e6xxx/port.c
> +++ b/drivers/net/dsa/mv88e6xxx/port.c
> @@ -187,11 +187,16 @@ static int mv88e6xxx_port_set_speed_duplex(struct mv88e6xxx_chip *chip,
>  		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
>  		break;
>  	case 2500:
> -		if (alt_bit)
> -			ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
> -				MV88E6390_PORT_MAC_CTL_ALTSPEED;
> +		if (chip->info->family == MV88E6XXX_FAMILY_6393)
> +			ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
>  		else
>  			ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000;
> +		if (alt_bit)
> +			ctrl |= MV88E6390_PORT_MAC_CTL_ALTSPEED;
> +		break;
> +	case 5000:
> +		ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
> +			MV88E6390_PORT_MAC_CTL_ALTSPEED;
>  		break;
>  	case 10000:
>  		/* all bits set, fall through... */

This is getting more and more complex. Maybe it is time to refactor it?

     Andrew

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next 3/3] net: dsa: mv88e6xxx: add support for 88E6393X from Amethyst family
  2020-08-19 15:38 ` [PATCH net-next 3/3] net: dsa: mv88e6xxx: add support for 88E6393X from Amethyst family Marek Behún
@ 2020-08-22 16:48   ` Andrew Lunn
  2020-08-22 16:49   ` Andrew Lunn
  1 sibling, 0 replies; 5+ messages in thread
From: Andrew Lunn @ 2020-08-22 16:48 UTC (permalink / raw)
  To: Marek Behún; +Cc: netdev, Russell King, Florian Fainelli, Vivien Didelot

>  /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
>  static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
>  				      bool up)
> @@ -678,8 +699,8 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
>  	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
>  		err = mv88e6390_serdes_power_sgmii(chip, lane, up);
>  		break;
> -	case MV88E6XXX_PORT_STS_CMODE_XAUI:
> -	case MV88E6XXX_PORT_STS_CMODE_RXAUI:
> +	case MV88E6XXX_PORT_STS_CMODE_XAUI: /* also MV88E6393_PORT_STS_CMODE_5GBASER */
> +	case MV88E6XXX_PORT_STS_CMODE_RXAUI: /* also MV88E6393_PORT_STS_CMODE_10GBASER */
>  		err = mv88e6390_serdes_power_10g(chip, lane, up);
>  		break;
>  	}

Not so nice. Maybe add a m88e6393_serdes_power() function to avoid
this?

	Andrew
	

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH net-next 3/3] net: dsa: mv88e6xxx: add support for 88E6393X from Amethyst family
  2020-08-19 15:38 [PATCH net-next 0/3] net: dsa: mv88e6xxx: Add Amethyst 88E6393X Marek Behún
@ 2020-08-19 15:38 ` Marek Behún
  2020-08-22 16:48   ` Andrew Lunn
  2020-08-22 16:49   ` Andrew Lunn
  0 siblings, 2 replies; 5+ messages in thread
From: Marek Behún @ 2020-08-19 15:38 UTC (permalink / raw)
  To: netdev
  Cc: Russell King, Andrew Lunn, Florian Fainelli, Vivien Didelot,
	Marek Behún

This adds support for 88E6393X, which differs from Peridot (6390 family)
in that instead of XAUI and RXAUI it supports 5GBASE-R, 10GBASE-R and
USXGMII modes and these modes are supported on ports 0, 9 and 10.

The USXGMII is not supported yet, since I couldn't find information
about the corresponding PHY registers.

The SERDES stats counters are not implemented, because they work
differently from Peridot and I couldn't get them to work.

The SERDES register dumps are not implemented.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
---
 drivers/net/dsa/mv88e6xxx/chip.c   |  97 ++++++++++++++++++++++
 drivers/net/dsa/mv88e6xxx/chip.h   |   4 +-
 drivers/net/dsa/mv88e6xxx/port.c   |  77 +++++++++++++++++-
 drivers/net/dsa/mv88e6xxx/port.h   |   9 +++
 drivers/net/dsa/mv88e6xxx/serdes.c | 126 ++++++++++++++++++++++++++++-
 drivers/net/dsa/mv88e6xxx/serdes.h |   8 ++
 6 files changed, 314 insertions(+), 7 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 0a5e2740a79db..d97b898312e20 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -637,6 +637,21 @@ static void mv88e6390x_phylink_validate(struct mv88e6xxx_chip *chip, int port,
 	mv88e6390_phylink_validate(chip, port, mask, state);
 }
 
+static void mv88e6393x_phylink_validate(struct mv88e6xxx_chip *chip, int port,
+					unsigned long *mask,
+					struct phylink_link_state *state)
+{
+	if (port == 0 || port == 9 || port == 10) {
+		phylink_set(mask, 2500baseX_Full);
+		phylink_set(mask, 2500baseT_Full);
+		phylink_set(mask, 5000baseT_Full);
+		phylink_set(mask, 10000baseT_Full);
+		phylink_set(mask, 10000baseKR_Full);
+	}
+
+	mv88e6390_phylink_validate(chip, port, mask, state);
+}
+
 static void mv88e6xxx_validate(struct dsa_switch *ds, int port,
 			       unsigned long *supported,
 			       struct phylink_link_state *state)
@@ -4705,6 +4720,63 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
 	.phylink_validate = mv88e6390x_phylink_validate,
 };
 
+static const struct mv88e6xxx_ops mv88e6393x_ops = {
+	/* MV88E6XXX_FAMILY_6393 */
+	.setup_errata = mv88e6390_setup_errata,
+	.irl_init_all = mv88e6390_g2_irl_init_all,
+	.get_eeprom = mv88e6xxx_g2_get_eeprom8,
+	.set_eeprom = mv88e6xxx_g2_set_eeprom8,
+	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
+	.phy_read = mv88e6xxx_g2_smi_phy_read,
+	.phy_write = mv88e6xxx_g2_smi_phy_write,
+	.port_set_link = mv88e6xxx_port_set_link,
+	.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
+	.port_set_speed_duplex = mv88e6393x_port_set_speed_duplex,
+	.port_max_speed_mode = mv88e6393x_port_max_speed_mode,
+	.port_tag_remap = mv88e6390_port_tag_remap,
+	.port_set_policy = mv88e6352_port_set_policy,
+	.port_set_frame_mode = mv88e6351_port_set_frame_mode,
+	.port_set_egress_floods = mv88e6352_port_set_egress_floods,
+	.port_set_ether_type = mv88e6351_port_set_ether_type,
+	.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
+	.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+	.port_pause_limit = mv88e6390_port_pause_limit,
+	.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
+	.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
+	.port_get_cmode = mv88e6352_port_get_cmode,
+	.port_set_cmode = mv88e6393x_port_set_cmode,
+	.port_setup_message_port = mv88e6xxx_setup_message_port,
+	.stats_snapshot = mv88e6390_g1_stats_snapshot,
+	.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
+	.stats_get_sset_count = mv88e6320_stats_get_sset_count,
+	.stats_get_strings = mv88e6320_stats_get_strings,
+	.stats_get_stats = mv88e6390_stats_get_stats,
+	.set_cpu_port = mv88e6390_g1_set_cpu_port,
+	.set_egress_port = mv88e6390_g1_set_egress_port,
+	.watchdog_ops = &mv88e6390_watchdog_ops,
+	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
+	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.reset = mv88e6352_g1_reset,
+	.rmu_disable = mv88e6390_g1_rmu_disable,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
+	.vtu_getnext = mv88e6390_g1_vtu_getnext,
+	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
+	.serdes_power = mv88e6390_serdes_power,
+	.serdes_get_lane = mv88e6393x_serdes_get_lane,
+	.serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
+	.serdes_pcs_config = mv88e6390_serdes_pcs_config,
+	.serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
+	.serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
+	.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
+	.serdes_irq_enable = mv88e6393x_serdes_irq_enable,
+	.serdes_irq_status = mv88e6393x_serdes_irq_status,
+	.gpio_ops = &mv88e6352_gpio_ops,
+	.avb_ops = &mv88e6390_avb_ops,
+	.ptp_ops = &mv88e6352_ptp_ops,
+	.phylink_validate = mv88e6393x_phylink_validate,
+};
+
 static const struct mv88e6xxx_info mv88e6xxx_table[] = {
 	[MV88E6085] = {
 		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6085,
@@ -5366,6 +5438,31 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
 		.ptp_support = true,
 		.ops = &mv88e6390x_ops,
 	},
+
+	[MV88E6393X] = {
+		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6393X,
+		.family = MV88E6XXX_FAMILY_6393,
+		.name = "Marvell 88E6393X",
+		.num_databases = 4096,
+		.num_macs = 16384,
+		.num_ports = 11,	/* 10 + Z80 */
+		.num_internal_phys = 9,
+		.num_gpio = 16,
+		.max_vid = 8191,
+		.port_base_addr = 0x0,
+		.phy_base_addr = 0x0,
+		.global1_addr = 0x1b,
+		.global2_addr = 0x1c,
+		.age_time_coeff = 3750,
+		.g1_irqs = 9,
+		.g2_irqs = 14,
+		.atu_move_port_mask = 0x1f,
+		.pvt = true,
+		.multi_chip = true,
+		.tag_protocol = DSA_TAG_PROTO_DSA,
+		.ptp_support = true,
+		.ops = &mv88e6393x_ops,
+	},
 };
 
 static const struct mv88e6xxx_info *mv88e6xxx_lookup_info(unsigned int prod_num)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index cc23810438dfe..9b36c7a21365b 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -75,6 +75,7 @@ enum mv88e6xxx_model {
 	MV88E6352,
 	MV88E6390,
 	MV88E6390X,
+	MV88E6393X,
 };
 
 enum mv88e6xxx_family {
@@ -89,7 +90,8 @@ enum mv88e6xxx_family {
 	MV88E6XXX_FAMILY_6341,	/* 6141 6341 */
 	MV88E6XXX_FAMILY_6351,	/* 6171 6175 6350 6351 */
 	MV88E6XXX_FAMILY_6352,	/* 6172 6176 6240 6352 */
-	MV88E6XXX_FAMILY_6390,  /* 6190 6190X 6191 6290 6390 6390X */
+	MV88E6XXX_FAMILY_6390,	/* 6190 6190X 6191 6290 6390 6390X */
+	MV88E6XXX_FAMILY_6393,	/* 6393X */
 };
 
 struct mv88e6xxx_ops;
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 9d5189f2474ce..8e974bc1b858e 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -187,11 +187,16 @@ static int mv88e6xxx_port_set_speed_duplex(struct mv88e6xxx_chip *chip,
 		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
 		break;
 	case 2500:
-		if (alt_bit)
-			ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
-				MV88E6390_PORT_MAC_CTL_ALTSPEED;
+		if (chip->info->family == MV88E6XXX_FAMILY_6393)
+			ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
 		else
 			ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000;
+		if (alt_bit)
+			ctrl |= MV88E6390_PORT_MAC_CTL_ALTSPEED;
+		break;
+	case 5000:
+		ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
+			MV88E6390_PORT_MAC_CTL_ALTSPEED;
 		break;
 	case 10000:
 		/* all bits set, fall through... */
@@ -390,6 +395,31 @@ phy_interface_t mv88e6390x_port_max_speed_mode(int port)
 	return PHY_INTERFACE_MODE_NA;
 }
 
+/* Support 10, 100, 200, 1000, 2500, 5000, 10000 Mbps (e.g. 88E6393X) */
+int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
+				     int speed, int duplex)
+{
+	if (speed == SPEED_MAX)
+		speed = (port > 0 && port < 9) ? 1000 : 10000;
+
+	if (speed == 200 && port != 0)
+		return -EOPNOTSUPP;
+
+	if (speed >= 2500 && (port > 0 && port < 9))
+		return -EOPNOTSUPP;
+
+	return mv88e6xxx_port_set_speed_duplex(chip, port, speed, true, true,
+					       duplex);
+}
+
+phy_interface_t mv88e6393x_port_max_speed_mode(int port)
+{
+	if (port == 0 || port == 9 || port == 10)
+		return PHY_INTERFACE_MODE_10GBASER;
+
+	return PHY_INTERFACE_MODE_NA;
+}
+
 static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 				    phy_interface_t mode, bool force)
 {
@@ -414,6 +444,9 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 	case PHY_INTERFACE_MODE_2500BASEX:
 		cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
 		break;
+	case PHY_INTERFACE_MODE_5GBASER:
+		cmode = MV88E6393_PORT_STS_CMODE_5GBASER;
+		break;
 	case PHY_INTERFACE_MODE_XGMII:
 	case PHY_INTERFACE_MODE_XAUI:
 		cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
@@ -421,6 +454,9 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 	case PHY_INTERFACE_MODE_RXAUI:
 		cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI;
 		break;
+	case PHY_INTERFACE_MODE_10GBASER:
+		cmode = MV88E6393_PORT_STS_CMODE_10GBASER;
+		break;
 	default:
 		cmode = 0;
 	}
@@ -482,6 +518,15 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 	if (port != 9 && port != 10)
 		return -EOPNOTSUPP;
 
+	switch (mode) {
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_USXGMII:
+		return -EINVAL;
+	default:
+		break;
+	}
+
 	return mv88e6xxx_port_set_cmode(chip, port, mode, false);
 }
 
@@ -491,6 +536,29 @@ int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 	if (port != 9 && port != 10)
 		return -EOPNOTSUPP;
 
+	switch (mode) {
+	case PHY_INTERFACE_MODE_NA:
+		return 0;
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_XGMII:
+	case PHY_INTERFACE_MODE_XAUI:
+	case PHY_INTERFACE_MODE_RXAUI:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_USXGMII:
+		return -EINVAL;
+	default:
+		break;
+	}
+
+	return mv88e6xxx_port_set_cmode(chip, port, mode, false);
+}
+
+int mv88e6393x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
+			      phy_interface_t mode)
+{
+	if (port != 9 && port != 10)
+		return -EOPNOTSUPP;
+
 	switch (mode) {
 	case PHY_INTERFACE_MODE_NA:
 		return 0;
@@ -541,9 +609,12 @@ int mv88e6341_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 	switch (mode) {
 	case PHY_INTERFACE_MODE_NA:
 		return 0;
+	case PHY_INTERFACE_MODE_5GBASER:
 	case PHY_INTERFACE_MODE_XGMII:
 	case PHY_INTERFACE_MODE_XAUI:
 	case PHY_INTERFACE_MODE_RXAUI:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_USXGMII:
 		return -EINVAL;
 	default:
 		break;
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index 44d76ac973f62..040b691b07eff 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -59,6 +59,9 @@
 #define MV88E6185_PORT_STS_CMODE_1000BASE_X	0x0005
 #define MV88E6185_PORT_STS_CMODE_PHY		0x0006
 #define MV88E6185_PORT_STS_CMODE_DISABLED	0x0007
+#define MV88E6393_PORT_STS_CMODE_5GBASER	0x000c
+#define MV88E6393_PORT_STS_CMODE_10GBASER	0x000d
+#define MV88E6393_PORT_STS_CMODE_USXGMII	0x000e
 
 /* Offset 0x01: MAC (or PCS or Physical) Control Register */
 #define MV88E6XXX_PORT_MAC_CTL				0x01
@@ -129,6 +132,7 @@
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6350	0x3710
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6351	0x3750
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6390	0x3900
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6393X	0x3930
 #define MV88E6XXX_PORT_SWITCH_ID_REV_MASK	0x000f
 
 /* Offset 0x04: Port Control Register */
@@ -312,10 +316,13 @@ int mv88e6390_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 				    int speed, int duplex);
 int mv88e6390x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 				     int speed, int duplex);
+int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
+				     int speed, int duplex);
 
 phy_interface_t mv88e6341_port_max_speed_mode(int port);
 phy_interface_t mv88e6390_port_max_speed_mode(int port);
 phy_interface_t mv88e6390x_port_max_speed_mode(int port);
+phy_interface_t mv88e6393x_port_max_speed_mode(int port);
 
 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state);
 
@@ -362,6 +369,8 @@ int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 			     phy_interface_t mode);
 int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 			      phy_interface_t mode);
+int mv88e6393x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
+			      phy_interface_t mode);
 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port);
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
index 9074d1097b614..e48057b366d51 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.c
+++ b/drivers/net/dsa/mv88e6xxx/serdes.c
@@ -526,6 +526,27 @@ int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
 	return *lane == -1 ? -ENODEV : 0;
 }
 
+int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
+{
+	u8 cmode = chip->ports[port].cmode;
+
+	*lane = -1;
+	switch (port) {
+	case 0:
+	case 9:
+	case 10:
+		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
+		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
+		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
+		    cmode == MV88E6393_PORT_STS_CMODE_5GBASER ||
+		    cmode == MV88E6393_PORT_STS_CMODE_10GBASER ||
+		    cmode == MV88E6393_PORT_STS_CMODE_USXGMII)
+			*lane = port;
+	}
+
+	return *lane == -1 ? -ENODEV : 0;
+}
+
 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
 				      bool up)
@@ -678,8 +699,8 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
 	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
 		err = mv88e6390_serdes_power_sgmii(chip, lane, up);
 		break;
-	case MV88E6XXX_PORT_STS_CMODE_XAUI:
-	case MV88E6XXX_PORT_STS_CMODE_RXAUI:
+	case MV88E6XXX_PORT_STS_CMODE_XAUI: /* also MV88E6393_PORT_STS_CMODE_5GBASER */
+	case MV88E6XXX_PORT_STS_CMODE_RXAUI: /* also MV88E6393_PORT_STS_CMODE_10GBASER */
 		err = mv88e6390_serdes_power_10g(chip, lane, up);
 		break;
 	}
@@ -785,7 +806,10 @@ static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
 
 	state->link = !!(status & MDIO_STAT1_LSTATUS);
 	if (state->link) {
-		state->speed = SPEED_10000;
+		if (state->interface == PHY_INTERFACE_MODE_5GBASER)
+			state->speed = SPEED_5000;
+		else
+			state->speed = SPEED_10000;
 		state->duplex = DUPLEX_FULL;
 	}
 
@@ -801,8 +825,10 @@ int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
 	case PHY_INTERFACE_MODE_2500BASEX:
 		return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
 							    state);
+	case PHY_INTERFACE_MODE_5GBASER:
 	case PHY_INTERFACE_MODE_XAUI:
 	case PHY_INTERFACE_MODE_RXAUI:
+	case PHY_INTERFACE_MODE_10GBASER:
 		return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane,
 							  state);
 
@@ -878,6 +904,23 @@ static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
 	dsa_port_phylink_mac_change(chip->ds, port, !!(bmsr & BMSR_LSTATUS));
 }
 
+static void mv88e6393x_serdes_irq_link_10g(struct mv88e6xxx_chip *chip,
+					   int port, u8 lane)
+{
+	u16 status;
+	int err;
+
+	/* If the link has dropped, we want to know about it. */
+	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
+				    MV88E6390_10G_STAT1, &status);
+	if (err) {
+		dev_err(chip->dev, "can't read Serdes STAT1: %d\n", err);
+		return;
+	}
+
+	dsa_port_phylink_mac_change(chip->ds, port, !!(status & MDIO_STAT1_LSTATUS));
+}
+
 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
 					     u8 lane, bool enable)
 {
@@ -906,6 +949,36 @@ int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
 	return 0;
 }
 
+static int mv88e6393x_serdes_irq_enable_10g(struct mv88e6xxx_chip *chip,
+					    u8 lane, bool enable)
+{
+	u16 val = 0;
+
+	if (enable)
+		val |= MV88E6393X_10G_INT_LINK_CHANGE;
+
+	return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
+				      MV88E6393X_10G_INT_ENABLE, val);
+}
+
+int mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
+				 bool enable)
+{
+	u8 cmode = chip->ports[port].cmode;
+
+	switch (cmode) {
+	case MV88E6XXX_PORT_STS_CMODE_SGMII:
+	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
+	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
+		return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
+	case MV88E6393_PORT_STS_CMODE_5GBASER:
+	case MV88E6393_PORT_STS_CMODE_10GBASER:
+		return mv88e6393x_serdes_irq_enable_10g(chip, lane, enable);
+	}
+
+	return 0;
+}
+
 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
 					     u8 lane, u16 *status)
 {
@@ -942,6 +1015,53 @@ irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
 	return ret;
 }
 
+static int mv88e6393x_serdes_irq_status_10g(struct mv88e6xxx_chip *chip,
+					    u8 lane, u16 *status)
+{
+	int err;
+
+	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
+				    MV88E6393X_10G_INT_STATUS, status);
+
+	return err;
+}
+
+irqreturn_t mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
+					 u8 lane)
+{
+	u8 cmode = chip->ports[port].cmode;
+	irqreturn_t ret = IRQ_NONE;
+	u16 status;
+	int err;
+
+	switch (cmode) {
+	case MV88E6XXX_PORT_STS_CMODE_SGMII:
+	case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
+	case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
+		err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
+		if (err)
+			return ret;
+		if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
+			      MV88E6390_SGMII_INT_LINK_UP)) {
+			ret = IRQ_HANDLED;
+			mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
+		}
+		break;
+	case MV88E6393_PORT_STS_CMODE_5GBASER:
+	case MV88E6393_PORT_STS_CMODE_10GBASER:
+		err = mv88e6393x_serdes_irq_status_10g(chip, lane, &status);
+		if (err)
+			return ret;
+		if (status & MV88E6393X_10G_INT_LINK_CHANGE) {
+			ret = IRQ_HANDLED;
+			mv88e6393x_serdes_irq_link_10g(chip, port, lane);
+		}
+		break;
+	}
+
+	return ret;
+}
+
 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
 {
 	return irq_find_mapping(chip->g2_irq.domain, port);
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h
index 95d04dab8d251..3999195caa62a 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.h
+++ b/drivers/net/dsa/mv88e6xxx/serdes.h
@@ -42,6 +42,9 @@
 /* 10GBASE-R and 10GBASE-X4/X2 */
 #define MV88E6390_10G_CTRL1		(0x1000 + MDIO_CTRL1)
 #define MV88E6390_10G_STAT1		(0x1000 + MDIO_STAT1)
+#define MV88E6393X_10G_INT_ENABLE	0x9000
+#define MV88E6393X_10G_INT_LINK_CHANGE	BIT(2)
+#define MV88E6393X_10G_INT_STATUS	0x9001
 
 /* 1000BASE-X and SGMII */
 #define MV88E6390_SGMII_BMCR		(0x2000 + MII_BMCR)
@@ -77,6 +80,7 @@ int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
 int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
 int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
 int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
+int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
 int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
 				u8 lane, unsigned int mode,
 				phy_interface_t interface,
@@ -109,10 +113,14 @@ int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
 				bool enable);
 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
 				bool enable);
+int mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
+				 bool enable);
 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
 					u8 lane);
 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
 					u8 lane);
+irqreturn_t mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
+					 u8 lane);
 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
 				 int port, uint8_t *data);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-08-27 15:19 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-27 15:19 [PATCH net-next 3/3] net: dsa: mv88e6xxx: add support for 88E6393X from Amethyst family kernel test robot
  -- strict thread matches above, loose matches on Subject: below --
2020-08-19 15:38 [PATCH net-next 0/3] net: dsa: mv88e6xxx: Add Amethyst 88E6393X Marek Behún
2020-08-19 15:38 ` [PATCH net-next 3/3] net: dsa: mv88e6xxx: add support for 88E6393X from Amethyst family Marek Behún
2020-08-22 16:48   ` Andrew Lunn
2020-08-22 16:49   ` Andrew Lunn
2020-08-22 18:55     ` Russell King - ARM Linux admin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.