This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

am335x mdio Linux

Hi

we use a  Marvell switch on our Sitara custom board . With u-boot  mdio access to the switch works.

For using the dsdt tool from Marvell mdio access from userspace is nesessary . The example in  http://e2e.ti.com/support/embedded/linux/f/354/t/199983.aspx doesn't  work because the CPSW driver doesn't support mdio access with iocts.

Can someone give me a hint how to realize the mdio access ?

Thanks in advance.

Rainer

  • What variant and version of kernel are you using?  I would guess all newer kernels support ioctl access to the MDIO bus. Most userspace network tools will use the ioctl interface. There is not much alternative to the ioctl as the network/phy driver control the the MDIO bus. To access it outside those drivers might confuse those drivers. Do you build your own kernel? You might be able to modify your kernel to allow of fix the MDIO access.

  • Hi Norman,

    thanks for your quick response. At the moment we use kernel 3.2 from SDK 6 and  I didn't found a hint inside the kernel config or driver code to enable the mdio ioctl.

    Of cours i can add this in the driver but i want to avoid it if possible.

    Rainer

  • Version 3.2 sounds new enough. I vaguely remember I had problems with really old kernels, eg 2.6.28. The kernel config for the AM335X has CONFIG_TI_CPSW and CONFIG_TI_DAVINCI_MDIO enabled. The driver framework should pass down ioctl commands SIOCGMIIREG and SIOCSMIIREG down to the mdio code. What is the exact error when you try to use the ioctl?

  • The error code of my program and mii-diag (with or without eth0 ) is: ioctl[SIOCGMIIPHY]: Operation not supported.

    The cpsw driver offer ioctl only for modifing the switch config. Davinci_mdio doesn't offer any ioctl only read and write and i don't no how to use them in a  user program.

  • My background is mainly on the OMAP-Lxxx. No CPSW there. Some guesses on my part.

    Seems to me that MII access is pretty essential. I checked the v3.15-rc8 at kernel.org and that cpsw.c does support ioctl and looks to pass down ioctl commands to the phy driver. Oddly the linux-omap3 project (2.6.37) at the Arago GIT also has ioctl support in cpsw.c. But that one does not pass down the ioctl cmds to the phy driver. I suspect that TI did some mods to their version.

    Unfortunately I think this means you might have to back-port the ioctl code in cpsw.c. Or switch to the mainline kernel is hopes that TI has pushed all the AM335x stuff back into the mainline.

    Writing your own driver that exposes the MII interface but that is quite a lot of work and steep learning curve.

  • My guess at a minimal hack to support MII ioctls in cpsw.c:

    static void cpsw_ndo_do_ioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd)
    {
      struct cpsw_priv *priv = netdev_priv(ndev);
      int slave_no = priv->hostport;

      if (!(netif_running(ndev)))
        return -EINVAL;

      if (!priv->slaves[slave_no].phy)
        return -EOPNOTSUPP;
      return phy_mii_ioctl(priv->slaves[slave_no].phy, ifrq, cmd);;
    }

    static const struct net_device_ops cpsw_netdev_ops = {
    ...
        .ndo_do_ioctl        = cpsw_ndo_do_ioctl,
    ...
    };

  • Hi Norman,

    thank you very much for you help.

    In the meantime I had a look at the cpsw function in the "offical" kernel source. Together with your hints it now runs.

    The function cpsw_ndo_do_ioctl is already part of the driver cpsw.c and hostport is no element of cpsw_priv.
    I used  int slave_no = cpsw_slave_phy_index(priv); instead.

    In the default section of  switch(cmd)  I used your code:

      if (!priv->slaves[slave_no].phy)
        return -EOPNOTSUPP;
      return phy_mii_ioctl(priv->slaves[slave_no].phy, ifrq, cmd);

     

    Rainer