Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1697359

Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface

From Andrew Lunn <andrew@lunn.ch>
Newsgroups linux.kernel
Subject Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface
Date 2017-07-26 19:00 +0200
Message-ID <u7xPb-2P1-5@gated-at.bofh.it> (permalink)
References <u7b2h-59O-13@gated-at.bofh.it> <u7bbZ-5du-31@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


On Tue, Jul 25, 2017 at 06:15:44PM +0200, Egil Hjelmeland wrote:
> Fixes after testing on actual HW:
> 
> - lan9303_mdio_write()/_read() must multiply register number
>   by 4 to get offset
> 
> - Indirect access (PMI) to phy register only work in I2C mode. In
>   MDIO mode phy registers must be accessed directly. Introduced
>   struct lan9303_phy_ops to handle the two modes. Renamed functions
>   to clarify.
> 
> - lan9303_detect_phy_setup() : Failed MDIO read return 0xffff.
>   Handle that.
> 
> Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
> ---
>  drivers/net/dsa/lan9303-core.c | 42 +++++++++++++++++++++++++++---------------
>  drivers/net/dsa/lan9303.h      | 11 +++++++++++
>  drivers/net/dsa/lan9303_i2c.c  |  2 ++
>  drivers/net/dsa/lan9303_mdio.c | 34 ++++++++++++++++++++++++++++++++++
>  4 files changed, 74 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
> index cd76e61f1fca..e622db586c3d 100644
> --- a/drivers/net/dsa/lan9303-core.c
> +++ b/drivers/net/dsa/lan9303-core.c
> @@ -20,6 +20,9 @@
>  
>  #include "lan9303.h"
>  
> +/* 13.2 System Control and Status Registers
> + * Multiply register number by 4 to get address offset.
> + */
>  #define LAN9303_CHIP_REV 0x14
>  # define LAN9303_CHIP_ID 0x9303
>  #define LAN9303_IRQ_CFG 0x15
> @@ -53,6 +56,9 @@
>  #define LAN9303_VIRT_PHY_BASE 0x70
>  #define LAN9303_VIRT_SPECIAL_CTRL 0x77
>  
> +/*13.4 Switch Fabric Control and Status Registers
> + * Accessed indirectly via SWITCH_CSR_CMD, SWITCH_CSR_DATA.
> + */
>  #define LAN9303_SW_DEV_ID 0x0000
>  #define LAN9303_SW_RESET 0x0001
>  #define LAN9303_SW_RESET_RESET BIT(0)
> @@ -242,7 +248,7 @@ static int lan9303_virt_phy_reg_write(struct lan9303 *chip, int regnum, u16 val)
>  	return regmap_write(chip->regmap, LAN9303_VIRT_PHY_BASE + regnum, val);
>  }
>  
> -static int lan9303_port_phy_reg_wait_for_completion(struct lan9303 *chip)
> +static int lan9303_indirect_phy_wait_for_completion(struct lan9303 *chip)
>  {
>  	int ret, i;
>  	u32 reg;
> @@ -262,7 +268,7 @@ static int lan9303_port_phy_reg_wait_for_completion(struct lan9303 *chip)
>  	return -EIO;
>  }
>  
> -static int lan9303_port_phy_reg_read(struct lan9303 *chip, int addr, int regnum)
> +static int lan9303_indirect_phy_read(struct lan9303 *chip, int addr, int regnum)
>  {
>  	int ret;
>  	u32 val;
> @@ -272,7 +278,7 @@ static int lan9303_port_phy_reg_read(struct lan9303 *chip, int addr, int regnum)
>  
>  	mutex_lock(&chip->indirect_mutex);
>  
> -	ret = lan9303_port_phy_reg_wait_for_completion(chip);
> +	ret = lan9303_indirect_phy_wait_for_completion(chip);
>  	if (ret)
>  		goto on_error;
>  
> @@ -281,7 +287,7 @@ static int lan9303_port_phy_reg_read(struct lan9303 *chip, int addr, int regnum)
>  	if (ret)
>  		goto on_error;
>  
> -	ret = lan9303_port_phy_reg_wait_for_completion(chip);
> +	ret = lan9303_indirect_phy_wait_for_completion(chip);
>  	if (ret)
>  		goto on_error;
>  
> @@ -299,8 +305,8 @@ static int lan9303_port_phy_reg_read(struct lan9303 *chip, int addr, int regnum)
>  	return ret;
>  }
>  
> -static int lan9303_phy_reg_write(struct lan9303 *chip, int addr, int regnum,
> -				 unsigned int val)
> +static int lan9303_indirect_phy_write(struct lan9303 *chip, int addr,
> +				      int regnum, u16 val)
>  {
>  	int ret;
>  	u32 reg;
> @@ -311,7 +317,7 @@ static int lan9303_phy_reg_write(struct lan9303 *chip, int addr, int regnum,
>  
>  	mutex_lock(&chip->indirect_mutex);
>  
> -	ret = lan9303_port_phy_reg_wait_for_completion(chip);
> +	ret = lan9303_indirect_phy_wait_for_completion(chip);
>  	if (ret)
>  		goto on_error;
>  
> @@ -328,6 +334,11 @@ static int lan9303_phy_reg_write(struct lan9303 *chip, int addr, int regnum,
>  	return ret;
>  }
>  
> +const struct lan9303_phy_ops lan9303_indirect_phy_ops = {
> +	.phy_read = lan9303_indirect_phy_read,
> +	.phy_write = lan9303_indirect_phy_write,
> +};
> +
>  static int lan9303_switch_wait_for_completion(struct lan9303 *chip)
>  {
>  	int ret, i;
> @@ -427,14 +438,15 @@ static int lan9303_detect_phy_setup(struct lan9303 *chip)
>  	 * Special reg 18 of phy 3 reads as 0x0000, if 'phy_addr_sel_strap' is 0
>  	 * and the IDs are 0-1-2, else it contains something different from
>  	 * 0x0000, which means 'phy_addr_sel_strap' is 1 and the IDs are 1-2-3.
> +	 * 0xffff is returned for failed MDIO access.

Hi Egil

0xffff is not really a failure. It just means there is nothing on the
bus at that address. The bus has a weak pull-up, so defaults to one.

>  	 */
> -	reg = lan9303_port_phy_reg_read(chip, 3, MII_LAN911X_SPECIAL_MODES);
> +	reg = chip->ops->phy_read(chip, 3, MII_LAN911X_SPECIAL_MODES);
>  	if (reg < 0) {
>  		dev_err(chip->dev, "Failed to detect phy config: %d\n", reg);
>  		return reg;
>  	}
>  
> -	if (reg != 0)
> +	if ((reg != 0) && (reg != 0xffff))
>  		chip->phy_addr_sel_strap = 1;
>  	else
>  		chip->phy_addr_sel_strap = 0;
> @@ -719,7 +731,7 @@ static int lan9303_phy_read(struct dsa_switch *ds, int phy, int regnum)
>  	if (phy > phy_base + 2)
>  		return -ENODEV;
>  
> -	return lan9303_port_phy_reg_read(chip, phy, regnum);
> +	return chip->ops->phy_read(chip, phy, regnum);
>  }
>  
>  static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum,
> @@ -733,7 +745,7 @@ static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum,
>  	if (phy > phy_base + 2)
>  		return -ENODEV;
>  
> -	return lan9303_phy_reg_write(chip, phy, regnum, val);
> +	return chip->ops->phy_write(chip, phy, regnum, val);
>  }
>  
>  static int lan9303_port_enable(struct dsa_switch *ds, int port,
> @@ -766,13 +778,13 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port,
>  	switch (port) {
>  	case 1:
>  		lan9303_disable_packet_processing(chip, LAN9303_PORT_1_OFFSET);
> -		lan9303_phy_reg_write(chip, chip->phy_addr_sel_strap + 1,
> -				      MII_BMCR, BMCR_PDOWN);
> +		lan9303_phy_write(ds, chip->phy_addr_sel_strap + 1,
> +				  MII_BMCR, BMCR_PDOWN);
>  		break;
>  	case 2:
>  		lan9303_disable_packet_processing(chip, LAN9303_PORT_2_OFFSET);
> -		lan9303_phy_reg_write(chip, chip->phy_addr_sel_strap + 2,
> -				      MII_BMCR, BMCR_PDOWN);
> +		lan9303_phy_write(ds, chip->phy_addr_sel_strap + 2,
> +				  MII_BMCR, BMCR_PDOWN);
>  		break;
>  	default:
>  		dev_dbg(chip->dev,
> diff --git a/drivers/net/dsa/lan9303.h b/drivers/net/dsa/lan9303.h
> index d1512dad2d90..444d00b460e1 100644
> --- a/drivers/net/dsa/lan9303.h
> +++ b/drivers/net/dsa/lan9303.h
> @@ -2,6 +2,15 @@
>  #include <linux/device.h>
>  #include <net/dsa.h>
>  
> +struct lan9303;
> +
> +struct lan9303_phy_ops {
> +	/* PHY 1 &2 access*/

A space would be nice here after the &.

> +	int	(*phy_read)(struct lan9303 *chip, int port, int regnum);
> +	int	(*phy_write)(struct lan9303 *chip, int port,
> +			     int regnum, u16 val);
> +};
> +
>  struct lan9303 {
>  	struct device *dev;
>  	struct regmap *regmap;
> @@ -11,9 +20,11 @@ struct lan9303 {
>  	bool phy_addr_sel_strap;
>  	struct dsa_switch *ds;
>  	struct mutex indirect_mutex; /* protect indexed register access */
> +	const struct lan9303_phy_ops *ops;
>  };
>  
>  extern const struct regmap_access_table lan9303_register_set;
> +extern const struct lan9303_phy_ops lan9303_indirect_phy_ops;
>  
>  int lan9303_probe(struct lan9303 *chip, struct device_node *np);
>  int lan9303_remove(struct lan9303 *chip);
> diff --git a/drivers/net/dsa/lan9303_i2c.c b/drivers/net/dsa/lan9303_i2c.c
> index ab3ce0da5071..24ec20f7f444 100644
> --- a/drivers/net/dsa/lan9303_i2c.c
> +++ b/drivers/net/dsa/lan9303_i2c.c
> @@ -63,6 +63,8 @@ static int lan9303_i2c_probe(struct i2c_client *client,
>  	i2c_set_clientdata(client, sw_dev);
>  	sw_dev->chip.dev = &client->dev;
>  
> +	sw_dev->chip.ops = &lan9303_indirect_phy_ops;
> +
>  	ret = lan9303_probe(&sw_dev->chip, client->dev.of_node);
>  	if (ret != 0)
>  		return ret;
> diff --git a/drivers/net/dsa/lan9303_mdio.c b/drivers/net/dsa/lan9303_mdio.c
> index 93c36c0541cf..94df12c5362f 100644
> --- a/drivers/net/dsa/lan9303_mdio.c
> +++ b/drivers/net/dsa/lan9303_mdio.c
> @@ -39,6 +39,7 @@ static void lan9303_mdio_real_write(struct mdio_device *mdio, int reg, u16 val)
>  static int lan9303_mdio_write(void *ctx, uint32_t reg, uint32_t val)
>  {
>  	struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx;
> +	reg <<= 2; /* reg num to offset */
>  
>  	mutex_lock(&sw_dev->device->bus->mdio_lock);
>  	lan9303_mdio_real_write(sw_dev->device, reg, val & 0xffff);
> @@ -56,6 +57,7 @@ static u16 lan9303_mdio_real_read(struct mdio_device *mdio, int reg)
>  static int lan9303_mdio_read(void *ctx, uint32_t reg, uint32_t *val)
>  {
>  	struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx;
> +	reg <<= 2; /* reg num to offset */
>  
>  	mutex_lock(&sw_dev->device->bus->mdio_lock);
>  	*val = lan9303_mdio_real_read(sw_dev->device, reg);
> @@ -65,6 +67,36 @@ static int lan9303_mdio_read(void *ctx, uint32_t reg, uint32_t *val)
>  	return 0;
>  }
>  
> +int lan9303_mdio_phy_write(struct lan9303 *chip, int phy, int regnum, u16 val)
> +{
> +	struct lan9303_mdio *sw_dev = dev_get_drvdata(chip->dev);
> +	struct mdio_device *mdio = sw_dev->device;
> +
> +	mutex_lock(&mdio->bus->mdio_lock);
> +	mdio->bus->write(mdio->bus, phy, regnum, val);
> +	mutex_unlock(&mdio->bus->mdio_lock);

It is better to use mdiobus_read/write or if you are nesting mdio
busses, mdiobus_read_nested/mdiobus_write_nested. Please test this
code with lockdep enabled.

And as others have pointed out, there are too many changes in this one
patch.

Thanks
	Andrew

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH net-next v2 00/10] net: dsa: lan9303: unicast offload, fdb,mdb,STP Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-25 18:40 +0200
  [PATCH net-next v2 07/10] net: dsa: lan9303: Added basic offloading of unicast traffic Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-25 18:50 +0200
    Re: [PATCH net-next v2 07/10] net: dsa: lan9303: Added basic  offloading of unicast traffic Andrew Lunn <andrew@lunn.ch> - 2017-07-26 19:30 +0200
      Re: [PATCH net-next v2 07/10] net: dsa: lan9303: Added basic  offloading of unicast traffic Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-27 13:30 +0200
        Re: [PATCH net-next v2 07/10] net: dsa: lan9303: Added basic  offloading of unicast traffic Andrew Lunn <andrew@lunn.ch> - 2017-07-27 15:40 +0200
          Re: [PATCH net-next v2 07/10] net: dsa: lan9303: Added basic  offloading of unicast traffic Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-27 16:10 +0200
  [PATCH net-next v2 03/10] net: dsa: lan9303: Refactor lan9303_enable_packet_processing() Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-25 18:50 +0200
  [PATCH net-next v2 04/10] net: dsa: lan9303: Added adjust_link() method Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-25 18:50 +0200
    Re: [PATCH net-next v2 04/10] net: dsa: lan9303: Added adjust_link()  method Andrew Lunn <andrew@lunn.ch> - 2017-07-26 19:10 +0200
      Re: [PATCH net-next v2 04/10] net: dsa: lan9303: Added adjust_link()  method Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-27 12:50 +0200
  [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-25 18:50 +0200
    Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface Vivien Didelot <vivien.didelot@savoirfairelinux.com> - 2017-07-25 21:20 +0200
      Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-26 14:20 +0200
        Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface Vivien Didelot <vivien.didelot@savoirfairelinux.com> - 2017-07-26 16:40 +0200
          Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-26 17:00 +0200
          Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface Andrew Lunn <andrew@lunn.ch> - 2017-07-26 20:00 +0200
            Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO  interface David Miller <davem@davemloft.net> - 2017-07-26 22:10 +0200
              Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-26 22:50 +0200
                Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface Andrew Lunn <andrew@lunn.ch> - 2017-07-26 23:50 +0200
    Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface Andrew Lunn <andrew@lunn.ch> - 2017-07-26 19:00 +0200
      Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-28 13:10 +0200
        Re: [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface Andrew Lunn <andrew@lunn.ch> - 2017-07-28 15:40 +0200
  [PATCH net-next v2 09/10] net: dsa: lan9303: Added Documentation/networking/dsa/lan9303.txt Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-25 19:20 +0200
  [PATCH net-next v2 10/10] net: dsa: lan9303: Only allocate 3 ports Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-25 19:20 +0200
  [PATCH net-next v2 08/10] net: dsa: lan9303: Added ALR/fdb/mdb handling Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-25 19:20 +0200
    Re: [PATCH net-next v2 08/10] net: dsa: lan9303: Added ALR/fdb/mdb  handling Andrew Lunn <andrew@lunn.ch> - 2017-07-26 19:50 +0200
      Re: [PATCH net-next v2 08/10] net: dsa: lan9303: Added ALR/fdb/mdb  handling Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-27 13:10 +0200
  [PATCH net-next v2 05/10] net: dsa: added dsa_net_device_to_dsa_port() Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-25 19:30 +0200
  [PATCH net-next v2 02/10] net: dsa: lan9303: Do not disable/enable switch fabric port 0 at startup Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-25 20:10 +0200
    Re: [PATCH net-next v2 02/10] net: dsa: lan9303: Do not  disable/enable switch fabric port 0 at startup Andrew Lunn <andrew@lunn.ch> - 2017-07-26 19:00 +0200
      Re: [PATCH net-next v2 02/10] net: dsa: lan9303: Do not  disable/enable switch fabric port 0 at startup Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-27 12:40 +0200
  [PATCH net-next v2 06/10] net: dsa: lan9303: added sysfs node swe_bcst_throt Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-25 20:20 +0200
    Re: [PATCH net-next v2 06/10] net: dsa: lan9303: added sysfs node  swe_bcst_throt Andrew Lunn <andrew@lunn.ch> - 2017-07-26 19:20 +0200
      Re: [PATCH net-next v2 06/10] net: dsa: lan9303: added sysfs node  swe_bcst_throt Egil Hjelmeland <privat@egil-hjelmeland.no> - 2017-07-27 13:00 +0200
        Re: [PATCH net-next v2 06/10] net: dsa: lan9303: added sysfs node  swe_bcst_throt Andrew Lunn <andrew@lunn.ch> - 2017-07-27 15:30 +0200
          Re: [PATCH net-next v2 06/10] net: dsa: lan9303: added sysfs node  swe_bcst_throt Jiri Pirko <jiri@resnulli.us> - 2017-07-27 15:40 +0200

csiph-web