* [PATCH] drivers/net/: ll_temac_main.c & ll_temac.h: Adding ethtool interface
@ 2010-08-26 18:13 Ville Sundell
2010-08-26 19:26 ` Grant Likely
0 siblings, 1 reply; 2+ messages in thread
From: Ville Sundell @ 2010-08-26 18:13 UTC (permalink / raw)
To: davem, grant.likely
Cc: john.linn, dkirjanov, jpirko, netdev, linux-kernel,
devicetree-discuss, Joshua Pederson
This patch adds an interface to the ethtool subsystem and
implements read/write functionality for handling settings with the
ethtool_cmd structure. "Speed" is the only setting implemented so far.
Other settings (like reading the duplex value) can be easily implemented
later on.
One can read the speed of the link by reading /sys/class/net/eth0/speed.
It seems that you can't write to /sys/class/net/eth0/speed, so the
"ethtool" command line utility must be used to set the speed.
So far, it is tested only in the DMA mode, since I don't have hardware
with DCR available.
Signed-off-by: Ville Sundell <ville.sundell@digilent.ro>
---
When using a non-static PHY and 100Mbit connection in Temac, the speed
is not changed and stays at the reset value (1000Mbit). This leads to a
situation where data is not sent or received correctly since
temac_adjust_link() is not called due to lack of static PHY. Therefore
the link speed retains the reset value.
There is also no possibility to read or set the link speed from the user
space.
The patch is done against the newest version of ll_temac_main.cc and
ll_temac.h of the linux-next tree.
Thanks to Michal Simek for his feedback on this patch!
Regards,
Ville Sundell
Digilent Inc.
drivers/net/ll_temac.h | 3 ++
drivers/net/ll_temac_main.c | 76 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h
index 522abe2..ddd00cc 100644
--- a/drivers/net/ll_temac.h
+++ b/drivers/net/ll_temac.h
@@ -247,6 +247,9 @@ This option defaults to enabled (set) */
#define XTE_EMCFG_LINKSPD_10 0x00000000 /* 10 Mbit LINKSPD_MASK */
#define XTE_EMCFG_LINKSPD_100 (1 << 30) /* 100 Mbit LINKSPD_MASK */
#define XTE_EMCFG_LINKSPD_1000 (1 << 31) /* 1000 Mbit LINKSPD_MASK */
+#define XTE_EMCFG_LINKSPD_NA 0xC0000000 /* For undefined speed */
+
+#define TEMAC_SPEED_NA 0 /* To indicate XTE_EMCFG_LINKSPD_NA */
#define XTE_GMIC_OFFSET 0x00000320 /* RGMII/SGMII config */
#define XTE_MC_OFFSET 0x00000340 /* MDIO configuration */
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
index bdf2149..ae08fd4 100644
--- a/drivers/net/ll_temac_main.c
+++ b/drivers/net/ll_temac_main.c
@@ -951,6 +951,81 @@ static const struct attribute_group temac_attr_group = {
.attrs = temac_device_attrs,
};
+/* Ethtool interface implementation
+ * SETTINGS
+ * With the following functions below, you can
+ * read and set following settings:
+ * Speed:
+ * Speed of the TEMAC controller is indicated by two most significant bits
+ * in the XTE_EMCFG_OFFSET register in the follwoing way:
+ * 00 = 10 Mbit connection
+ * 01 = 100 Mbit connection
+ * 10 = 1000 Mbit connection
+ * 11 = Undefined connection speed
+*/
+
+static int temac_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ u32 reg = temac_indirect_in32(lp, XTE_EMCFG_OFFSET);
+
+ switch (reg & XTE_EMCFG_LINKSPD_MASK) {
+ case XTE_EMCFG_LINKSPD_10:
+ cmd->speed = SPEED_10;
+ break;
+ case XTE_EMCFG_LINKSPD_100:
+ cmd->speed = SPEED_100;
+ break;
+ case XTE_EMCFG_LINKSPD_1000:
+ cmd->speed = SPEED_1000;
+ break;
+ default:
+ cmd->speed = TEMAC_SPEED_NA; /* Undefined speed */
+ break;
+ }
+
+ /* TODO: Insert more setting reading code here */
+
+ return 0;
+}
+
+static int temac_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
+{
+ struct temac_local *lp = netdev_priv(ndev);
+ u32 reg = temac_indirect_in32(lp, XTE_EMCFG_OFFSET);
+
+ reg &= ~XTE_EMCFG_LINKSPD_MASK;
+ switch (cmd->speed) {
+ case SPEED_10:
+ reg |= XTE_EMCFG_LINKSPD_10;
+ break;
+ case SPEED_100:
+ reg |= XTE_EMCFG_LINKSPD_100;
+ break;
+ case SPEED_1000:
+ reg |= XTE_EMCFG_LINKSPD_1000;
+ break;
+ default:
+ reg |= XTE_EMCFG_LINKSPD_NA; /* Undefined speed */
+ break;
+ }
+
+ /* TODO: Insert more setting writing code here */
+
+ temac_indirect_out32(lp, XTE_EMCFG_OFFSET, reg);
+
+ return 0;
+}
+
+/*
+ * Defining the ethtool operations.
+ * This will be passed to the ethtool subsystem in the probe function
+ */
+static const struct ethtool_ops temac_ethtool_ops = {
+ .get_settings = temac_get_settings,
+ .set_settings = temac_set_settings,
+};
+
static int __init
temac_of_probe(struct platform_device *op, const struct of_device_id *match)
{
@@ -970,6 +1045,7 @@ temac_of_probe(struct platform_device *op, const struct of_device_id *match)
ether_setup(ndev);
dev_set_drvdata(&op->dev, ndev);
SET_NETDEV_DEV(ndev, &op->dev);
+ SET_ETHTOOL_OPS(ndev, &temac_ethtool_ops);
ndev->flags &= ~IFF_MULTICAST; /* clear multicast */
ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
ndev->netdev_ops = &temac_netdev_ops;
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] drivers/net/: ll_temac_main.c & ll_temac.h: Adding ethtool interface
2010-08-26 18:13 [PATCH] drivers/net/: ll_temac_main.c & ll_temac.h: Adding ethtool interface Ville Sundell
@ 2010-08-26 19:26 ` Grant Likely
0 siblings, 0 replies; 2+ messages in thread
From: Grant Likely @ 2010-08-26 19:26 UTC (permalink / raw)
To: Ville Sundell
Cc: jpirko-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Joshua Pederson,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
dkirjanov-DgEjT+Ai2ygdnm+yROfE0A, davem-fT/PcQaiUtIeIZ0/mPfg9Q
On Thu, Aug 26, 2010 at 12:13 PM, Ville Sundell
<ville.sundell-PRfGYHLb4FmhKNWrAYCRhA@public.gmane.org> wrote:
> This patch adds an interface to the ethtool subsystem and
> implements read/write functionality for handling settings with the
> ethtool_cmd structure. "Speed" is the only setting implemented so far.
> Other settings (like reading the duplex value) can be easily implemented
> later on.
>
> One can read the speed of the link by reading /sys/class/net/eth0/speed.
> It seems that you can't write to /sys/class/net/eth0/speed, so the
> "ethtool" command line utility must be used to set the speed.
>
> So far, it is tested only in the DMA mode, since I don't have hardware
> with DCR available.
>
> Signed-off-by: Ville Sundell <ville.sundell-PRfGYHLb4FmhKNWrAYCRhA@public.gmane.org>
The ll_temac driver uses phylib. The Ethtool ops should then also be
implemented using phylib and not by writing to the ll_temac registers
directly. Otherwise changes to the ll_temac speed will not be
reflected in the PHY.
g.
> ---
>
> When using a non-static PHY and 100Mbit connection in Temac, the speed
> is not changed and stays at the reset value (1000Mbit). This leads to a
> situation where data is not sent or received correctly since
> temac_adjust_link() is not called due to lack of static PHY. Therefore
> the link speed retains the reset value.
>
> There is also no possibility to read or set the link speed from the user
> space.
>
> The patch is done against the newest version of ll_temac_main.cc and
> ll_temac.h of the linux-next tree.
>
> Thanks to Michal Simek for his feedback on this patch!
>
> Regards,
> Ville Sundell
> Digilent Inc.
>
> drivers/net/ll_temac.h | 3 ++
> drivers/net/ll_temac_main.c | 76 +++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 79 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h
> index 522abe2..ddd00cc 100644
> --- a/drivers/net/ll_temac.h
> +++ b/drivers/net/ll_temac.h
> @@ -247,6 +247,9 @@ This option defaults to enabled (set) */
> #define XTE_EMCFG_LINKSPD_10 0x00000000 /* 10 Mbit LINKSPD_MASK */
> #define XTE_EMCFG_LINKSPD_100 (1 << 30) /* 100 Mbit LINKSPD_MASK */
> #define XTE_EMCFG_LINKSPD_1000 (1 << 31) /* 1000 Mbit LINKSPD_MASK */
> +#define XTE_EMCFG_LINKSPD_NA 0xC0000000 /* For undefined speed */
> +
> +#define TEMAC_SPEED_NA 0 /* To indicate XTE_EMCFG_LINKSPD_NA */
>
> #define XTE_GMIC_OFFSET 0x00000320 /* RGMII/SGMII config */
> #define XTE_MC_OFFSET 0x00000340 /* MDIO configuration */
> diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
> index bdf2149..ae08fd4 100644
> --- a/drivers/net/ll_temac_main.c
> +++ b/drivers/net/ll_temac_main.c
> @@ -951,6 +951,81 @@ static const struct attribute_group temac_attr_group = {
> .attrs = temac_device_attrs,
> };
>
> +/* Ethtool interface implementation
> + * SETTINGS
> + * With the following functions below, you can
> + * read and set following settings:
> + * Speed:
> + * Speed of the TEMAC controller is indicated by two most significant bits
> + * in the XTE_EMCFG_OFFSET register in the follwoing way:
> + * 00 = 10 Mbit connection
> + * 01 = 100 Mbit connection
> + * 10 = 1000 Mbit connection
> + * 11 = Undefined connection speed
> +*/
> +
> +static int temac_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
> +{
> + struct temac_local *lp = netdev_priv(ndev);
> + u32 reg = temac_indirect_in32(lp, XTE_EMCFG_OFFSET);
> +
> + switch (reg & XTE_EMCFG_LINKSPD_MASK) {
> + case XTE_EMCFG_LINKSPD_10:
> + cmd->speed = SPEED_10;
> + break;
> + case XTE_EMCFG_LINKSPD_100:
> + cmd->speed = SPEED_100;
> + break;
> + case XTE_EMCFG_LINKSPD_1000:
> + cmd->speed = SPEED_1000;
> + break;
> + default:
> + cmd->speed = TEMAC_SPEED_NA; /* Undefined speed */
> + break;
> + }
> +
> + /* TODO: Insert more setting reading code here */
> +
> + return 0;
> +}
> +
> +static int temac_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
> +{
> + struct temac_local *lp = netdev_priv(ndev);
> + u32 reg = temac_indirect_in32(lp, XTE_EMCFG_OFFSET);
> +
> + reg &= ~XTE_EMCFG_LINKSPD_MASK;
> + switch (cmd->speed) {
> + case SPEED_10:
> + reg |= XTE_EMCFG_LINKSPD_10;
> + break;
> + case SPEED_100:
> + reg |= XTE_EMCFG_LINKSPD_100;
> + break;
> + case SPEED_1000:
> + reg |= XTE_EMCFG_LINKSPD_1000;
> + break;
> + default:
> + reg |= XTE_EMCFG_LINKSPD_NA; /* Undefined speed */
> + break;
> + }
> +
> + /* TODO: Insert more setting writing code here */
> +
> + temac_indirect_out32(lp, XTE_EMCFG_OFFSET, reg);
> +
> + return 0;
> +}
> +
> +/*
> + * Defining the ethtool operations.
> + * This will be passed to the ethtool subsystem in the probe function
> + */
> +static const struct ethtool_ops temac_ethtool_ops = {
> + .get_settings = temac_get_settings,
> + .set_settings = temac_set_settings,
> +};
> +
> static int __init
> temac_of_probe(struct platform_device *op, const struct of_device_id *match)
> {
> @@ -970,6 +1045,7 @@ temac_of_probe(struct platform_device *op, const struct of_device_id *match)
> ether_setup(ndev);
> dev_set_drvdata(&op->dev, ndev);
> SET_NETDEV_DEV(ndev, &op->dev);
> + SET_ETHTOOL_OPS(ndev, &temac_ethtool_ops);
> ndev->flags &= ~IFF_MULTICAST; /* clear multicast */
> ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
> ndev->netdev_ops = &temac_netdev_ops;
>
>
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-08-26 19:26 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-26 18:13 [PATCH] drivers/net/: ll_temac_main.c & ll_temac.h: Adding ethtool interface Ville Sundell
2010-08-26 19:26 ` Grant Likely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox