netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 1/7] net: moxa: clear TX descriptor length bits between sends
@ 2014-01-20 11:13 Jonas Jensen
  2014-01-20 11:13 ` [PATCH v3 2/7] net: moxa: fix build_skb() memory corruption Jonas Jensen
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Jonas Jensen @ 2014-01-20 11:13 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, linux-kernel, davem, f.fainelli, bhutchings,
	Jonas Jensen

Add TX_DESC1_BUF_SIZE_MASK to bits that are cleared, before the TX buffer
length is set. Failing to do so can cause the controller to drop dead
i.e. all TX interrupts stop, resulting in complete communication failure.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69031

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Applies to next-20140120

 drivers/net/ethernet/moxa/moxart_ether.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index 5020fd4..aa45607 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -348,7 +348,8 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 
 	txdes1 = readl(desc + TX_REG_OFFSET_DESC1);
 	txdes1 |= TX_DESC1_LTS | TX_DESC1_FTS;
-	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE);
+	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE |
+		    TX_DESC1_BUF_SIZE_MASK);
 	txdes1 |= (len & TX_DESC1_BUF_SIZE_MASK);
 	writel(txdes1, desc + TX_REG_OFFSET_DESC1);
 	writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0);
-- 
1.8.2.1

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

* [PATCH v3 2/7] net: moxa: fix build_skb() memory corruption
  2014-01-20 11:13 [PATCH v3 1/7] net: moxa: clear TX descriptor length bits between sends Jonas Jensen
@ 2014-01-20 11:13 ` Jonas Jensen
  2014-01-20 11:13 ` [PATCH v3 3/7] net: moxa: connect to PHY Jonas Jensen
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Jonas Jensen @ 2014-01-20 11:13 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, linux-kernel, davem, f.fainelli, bhutchings,
	Jonas Jensen

DMA buffer memory must be synchronized and copied before passing skb to
napi_gro_receive(). The use of build_skb() can lead to memory corruption,
replace it with netdev_alloc_skb_ip_align() and memcpy().

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69041

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    This fixes the following error on wget download (or ncftp),
    usually after only a few seconds:
    
    "read error: Bad address"
    
    On receiving this error, wget exits. The download is not resumed (busybox default).
    
    Applies to next-20140120

 drivers/net/ethernet/moxa/moxart_ether.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index aa45607..17c9f0e 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -226,14 +226,21 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
 		if (len > RX_BUF_SIZE)
 			len = RX_BUF_SIZE;
 
-		skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
+		dma_sync_single_for_cpu(&ndev->dev,
+					priv->rx_mapping[rx_head],
+					priv->rx_buf_size, DMA_FROM_DEVICE);
+		skb = netdev_alloc_skb_ip_align(ndev, len);
 		if (unlikely(!skb)) {
-			net_dbg_ratelimited("build_skb failed\n");
+			net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
 			priv->stats.rx_dropped++;
 			priv->stats.rx_errors++;
 		}
-
+		memcpy(skb->data, priv->rx_buf[rx_head], len);
 		skb_put(skb, len);
+		dma_sync_single_for_device(&ndev->dev,
+					   priv->rx_mapping[rx_head],
+					   priv->rx_buf_size, DMA_FROM_DEVICE);
+
 		skb->protocol = eth_type_trans(skb, ndev);
 		napi_gro_receive(&priv->napi, skb);
 		rx++;
-- 
1.8.2.1

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

* [PATCH v3 3/7] net: moxa: connect to PHY
  2014-01-20 11:13 [PATCH v3 1/7] net: moxa: clear TX descriptor length bits between sends Jonas Jensen
  2014-01-20 11:13 ` [PATCH v3 2/7] net: moxa: fix build_skb() memory corruption Jonas Jensen
@ 2014-01-20 11:13 ` Jonas Jensen
       [not found]   ` <1390216399-27028-3-git-send-email-jonas.jensen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2014-01-20 11:13 ` [PATCH v3 4/7] net: moxa: add ethtool support Jonas Jensen
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: Jonas Jensen @ 2014-01-20 11:13 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, linux-kernel, davem, f.fainelli, bhutchings,
	Jonas Jensen

The kernel now has a MDIO bus driver and a phy_driver (RTL8201CP),
connect to this PHY using OF.

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Applies to next-20140120

 .../devicetree/bindings/net/moxa,moxart-mac.txt    | 47 ++++++++++-
 drivers/net/ethernet/moxa/moxart_ether.c           | 92 +++++++++++++++++++++-
 drivers/net/ethernet/moxa/moxart_ether.h           |  2 +
 3 files changed, 138 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt b/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt
index 583418b..94c1f3b 100644
--- a/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt
+++ b/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt
@@ -1,21 +1,64 @@
 MOXA ART Ethernet Controller
 
+Integrated MDIO bus node:
+
+- compatible: "moxa,moxart-mdio"
+- Inherits from MDIO bus node binding[1]
+
+[1] Documentation/devicetree/bindings/net/phy.txt
+
+
+Ethernet node:
+
 Required properties:
 
 - compatible : Must be "moxa,moxart-mac"
 - reg : Should contain register location and length
 - interrupts : Should contain the mac interrupt number
 
+Optional Properties:
+
+- phy-handle : the phandle to a PHY node
+
+
 Example:
 
+	mdio0: mdio@90900090 {
+		compatible = "moxa,moxart-mdio";
+		reg = <0x90900090 0x8>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy0: ethernet-phy@1 {
+			device_type = "ethernet-phy";
+			compatible = "moxa,moxart-rtl8201cp", "ethernet-phy-ieee802.3-c22";
+			reg = <1>;
+		};
+	};
+
+	mdio1: mdio@92000090 {
+		compatible = "moxa,moxart-mdio";
+		reg = <0x92000090 0x8>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy1: ethernet-phy@1 {
+			device_type = "ethernet-phy";
+			compatible = "moxa,moxart-rtl8201cp", "ethernet-phy-ieee802.3-c22";
+			reg = <1>;
+		};
+	};
+
 	mac0: mac@90900000 {
 		compatible = "moxa,moxart-mac";
-		reg =	<0x90900000 0x100>;
+		reg = <0x90900000 0x90>;
 		interrupts = <25 0>;
+		phy-handle = <&ethphy0>;
 	};
 
 	mac1: mac@92000000 {
 		compatible = "moxa,moxart-mac";
-		reg =	<0x92000000 0x100>;
+		reg = <0x92000000 0x90>;
 		interrupts = <27 0>;
+		phy-handle = <&ethphy1>;
 	};
diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index 17c9f0e..c19bff2 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -25,6 +25,9 @@
 #include <linux/of_irq.h>
 #include <linux/crc32.h>
 #include <linux/crc32c.h>
+#include <linux/phy.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
 
 #include "moxart_ether.h"
 
@@ -60,6 +63,16 @@ static int moxart_set_mac_address(struct net_device *ndev, void *addr)
 	return 0;
 }
 
+static int moxart_do_ioctl(struct net_device *ndev, struct ifreq *ir, int cmd)
+{
+	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
+
+	if (!netif_running(ndev))
+		return -EINVAL;
+
+	return phy_mii_ioctl(priv->phy_dev, ir, cmd);
+}
+
 static void moxart_mac_free_memory(struct net_device *ndev)
 {
 	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
@@ -109,6 +122,19 @@ static void moxart_mac_enable(struct net_device *ndev)
 	writel(priv->reg_maccr, priv->base + REG_MAC_CTRL);
 }
 
+static void moxart_mac_update_duplex(struct net_device *ndev)
+{
+	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
+
+	priv->reg_maccr &= ~(FULLDUP | ENRX_IN_HALFTX);
+	if (priv->duplex)
+		priv->reg_maccr |= FULLDUP;
+	else
+		priv->reg_maccr |= ENRX_IN_HALFTX;
+
+	writel(priv->reg_maccr, priv->base + REG_MAC_CTRL);
+}
+
 static void moxart_mac_setup_desc_ring(struct net_device *ndev)
 {
 	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
@@ -168,6 +194,9 @@ static int moxart_mac_open(struct net_device *ndev)
 	moxart_update_mac_address(ndev);
 	moxart_mac_setup_desc_ring(ndev);
 	moxart_mac_enable(ndev);
+
+	phy_start(priv->phy_dev);
+
 	netif_start_queue(ndev);
 
 	netdev_dbg(ndev, "%s: IMR=0x%x, MACCR=0x%x\n",
@@ -183,6 +212,8 @@ static int moxart_mac_stop(struct net_device *ndev)
 
 	napi_disable(&priv->napi);
 
+	phy_stop(priv->phy_dev);
+
 	netif_stop_queue(ndev);
 
 	/* disable all interrupts */
@@ -435,12 +466,49 @@ static struct net_device_ops moxart_netdev_ops = {
 	.ndo_set_mac_address	= moxart_set_mac_address,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_do_ioctl		= moxart_do_ioctl,
 };
 
+static void moxart_adjust_link(struct net_device *ndev)
+{
+	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
+	unsigned long flags;
+	int status_change = 0;
+
+	if (priv->phy_dev->link) {
+		if (priv->speed != priv->phy_dev->speed) {
+			priv->speed = priv->phy_dev->speed;
+			status_change = 1;
+		}
+
+		if (priv->duplex != priv->phy_dev->duplex) {
+			spin_lock_irqsave(&priv->txlock, flags);
+
+			priv->duplex = priv->phy_dev->duplex;
+			moxart_mac_update_duplex(ndev);
+
+			spin_unlock_irqrestore(&priv->txlock, flags);
+			status_change = 1;
+		}
+	}
+
+	if (priv->link != priv->phy_dev->link) {
+		if (!priv->phy_dev->link) {
+			priv->speed = 0;
+			priv->duplex = -1;
+		}
+		priv->link = priv->phy_dev->link;
+		status_change = 1;
+	}
+
+	if (status_change)
+		phy_print_status(priv->phy_dev);
+}
+
 static int moxart_mac_probe(struct platform_device *pdev)
 {
 	struct device *p_dev = &pdev->dev;
-	struct device_node *node = p_dev->of_node;
+	struct device_node *node = p_dev->of_node, *phy_node;
 	struct net_device *ndev;
 	struct moxart_mac_priv_t *priv;
 	struct resource *res;
@@ -461,6 +529,28 @@ static int moxart_mac_probe(struct platform_device *pdev)
 	priv = netdev_priv(ndev);
 	priv->ndev = ndev;
 
+	priv->link = 0;
+	priv->speed = 0;
+	priv->duplex = -1;
+
+	phy_node = of_parse_phandle(node, "phy-handle", 0);
+	if (!phy_node) {
+		dev_err(p_dev, "of_parse_phandle failed\n");
+		ret = -ENODEV;
+		goto init_fail;
+	}
+
+	if (phy_node) {
+		priv->phy_dev = of_phy_connect(priv->ndev, phy_node,
+					       &moxart_adjust_link,
+					       0, of_get_phy_mode(node));
+		if (!priv->phy_dev) {
+			dev_err(p_dev, "of_phy_connect failed\n");
+			ret = -ENODEV;
+			goto init_fail;
+		}
+	}
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	ndev->base_addr = res->start;
 	priv->base = devm_ioremap_resource(p_dev, res);
diff --git a/drivers/net/ethernet/moxa/moxart_ether.h b/drivers/net/ethernet/moxa/moxart_ether.h
index 2be9280..b8877bf 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.h
+++ b/drivers/net/ethernet/moxa/moxart_ether.h
@@ -297,6 +297,8 @@ struct moxart_mac_priv_t {
 	unsigned int reg_imr;
 	struct napi_struct napi;
 	struct net_device *ndev;
+	struct phy_device *phy_dev;
+	int speed, duplex, link;
 
 	dma_addr_t rx_base;
 	dma_addr_t rx_mapping[RX_DESC_NUM];
-- 
1.8.2.1

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

* [PATCH v3 4/7] net: moxa: add ethtool support
  2014-01-20 11:13 [PATCH v3 1/7] net: moxa: clear TX descriptor length bits between sends Jonas Jensen
  2014-01-20 11:13 ` [PATCH v3 2/7] net: moxa: fix build_skb() memory corruption Jonas Jensen
  2014-01-20 11:13 ` [PATCH v3 3/7] net: moxa: connect to PHY Jonas Jensen
@ 2014-01-20 11:13 ` Jonas Jensen
  2014-01-20 11:13 ` [PATCH v3 5/7] net: moxa: add IFF_LIVE_ADDR_CHANGE flag Jonas Jensen
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Jonas Jensen @ 2014-01-20 11:13 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, linux-kernel, davem, f.fainelli, bhutchings,
	Jonas Jensen

Add and assign ethtool_ops callback functions.

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Applies to next-20140120

 drivers/net/ethernet/moxa/moxart_ether.c | 121 +++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index c19bff2..ca892bb 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -31,6 +31,10 @@
 
 #include "moxart_ether.h"
 
+#define DRV_NAME		"moxart-ethernet"
+#define DRV_VERSION		"0.2"
+#define MOXART_NUM_STATS	ARRAY_SIZE(ethtool_stats_keys)
+
 static inline void moxart_emac_write(struct net_device *ndev,
 				     unsigned int reg, unsigned long value)
 {
@@ -63,6 +67,122 @@ static int moxart_set_mac_address(struct net_device *ndev, void *addr)
 	return 0;
 }
 
+static struct {
+	const char str[ETH_GSTRING_LEN];
+} ethtool_stats_keys[] = {
+	{ "tx_ok_mcol_2to15" },
+	{ "tx_ok_1col" },
+	{ "rx_frame_pause" },
+	{ "frame_align_err" },
+	{ "err_col_late_16" },
+	{ "err_col_16" },
+	{ "rx_runt" },
+	{ "late_col" },
+	{ "crc_err" },
+	{ "rx_ftl" },
+	{ "rx_fifo_full" },
+	{ "rx_col" },
+	{ "rx_bcast" },
+	{ "rx_mcast" },
+	{ "rx_ok" },
+	{ "tx_ok" },
+};
+
+static void moxart_get_drvinfo(struct net_device *ndev,
+			       struct ethtool_drvinfo *info)
+{
+	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+	strlcpy(info->bus_info, dev_name(&ndev->dev), sizeof(info->bus_info));
+}
+
+static int moxart_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
+{
+	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
+
+	return phy_ethtool_gset(priv->phy_dev, cmd);
+}
+
+static int moxart_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
+{
+	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
+
+	return phy_ethtool_sset(priv->phy_dev, cmd);
+}
+
+static int moxart_nway_reset(struct net_device *ndev)
+{
+	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
+
+	return genphy_restart_aneg(priv->phy_dev);
+}
+
+static void moxart_get_ethtool_stats(struct net_device *ndev,
+				     struct ethtool_stats *estats,
+				     u64 *tmp_stats)
+{
+	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
+	u32 s;
+	int i = 0;
+
+	s = readl(priv->base + REG_TX_COL_COUNTER);
+	tmp_stats[i++] = s & 0xffff0000;
+	tmp_stats[i++] = s & 0x0000ffff;
+	s = readl(priv->base + REG_RPF_AEP_COUNTER);
+	tmp_stats[i++] = s & 0xffff0000;
+	tmp_stats[i++] = s & 0x0000ffff;
+	s = readl(priv->base + REG_XM_PG_COUNTER);
+	tmp_stats[i++] = s & 0xffff0000;
+	tmp_stats[i++] = s & 0x0000ffff;
+	s = readl(priv->base + REG_RUNT_TLC_COUNTER);
+	tmp_stats[i++] = s & 0xffff0000;
+	tmp_stats[i++] = s & 0x0000ffff;
+	s = readl(priv->base + REG_CRC_FTL_COUNTER);
+	tmp_stats[i++] = s & 0xffff0000;
+	tmp_stats[i++] = s & 0x0000ffff;
+	s = readl(priv->base + REG_RLC_RCC_COUNTER);
+	tmp_stats[i++] = s & 0xffff0000;
+	tmp_stats[i++] = s & 0x0000ffff;
+	tmp_stats[i++] = readl(priv->base + REG_BROC_COUNTER);
+	tmp_stats[i++] = readl(priv->base + REG_MULCA_COUNTER);
+	tmp_stats[i++] = readl(priv->base + REG_XP_COUNTER);
+	tmp_stats[i++] = readl(priv->base + REG_RP_COUNTER);
+}
+
+static int moxart_get_sset_count(struct net_device *netdev,
+					int string_set)
+{
+	switch (string_set) {
+	case ETH_SS_STATS:
+		return MOXART_NUM_STATS;
+	default:
+		return -EINVAL;
+	}
+}
+
+static void moxart_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+	switch (stringset) {
+	case ETH_SS_STATS:
+		memcpy(data, &ethtool_stats_keys, sizeof(ethtool_stats_keys));
+		break;
+	default:
+		WARN_ON(1);
+		break;
+	}
+}
+
+static const struct ethtool_ops moxart_ethtool_ops = {
+	.set_settings		= moxart_set_settings,
+	.get_settings		= moxart_get_settings,
+	.get_drvinfo		= moxart_get_drvinfo,
+	.nway_reset		= moxart_nway_reset,
+	.get_link		= ethtool_op_get_link,
+	.get_ethtool_stats	= moxart_get_ethtool_stats,
+	.get_sset_count		= moxart_get_sset_count,
+	.get_strings		= moxart_get_strings,
+};
+
 static int moxart_do_ioctl(struct net_device *ndev, struct ifreq *ir, int cmd)
 {
 	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
@@ -612,6 +732,7 @@ static int moxart_mac_probe(struct platform_device *pdev)
 	ndev->irq = irq;
 
 	SET_NETDEV_DEV(ndev, &pdev->dev);
+	SET_ETHTOOL_OPS(ndev, &moxart_ethtool_ops);
 
 	ret = register_netdev(ndev);
 	if (ret) {
-- 
1.8.2.1

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

* [PATCH v3 5/7] net: moxa: add IFF_LIVE_ADDR_CHANGE flag
  2014-01-20 11:13 [PATCH v3 1/7] net: moxa: clear TX descriptor length bits between sends Jonas Jensen
                   ` (2 preceding siblings ...)
  2014-01-20 11:13 ` [PATCH v3 4/7] net: moxa: add ethtool support Jonas Jensen
@ 2014-01-20 11:13 ` Jonas Jensen
  2014-01-20 11:13 ` [PATCH v3 6/7] net: moxa: generate random address Jonas Jensen
  2014-01-20 11:13 ` [PATCH v3 7/7] net: moxa: use eth_mac_addr() Jonas Jensen
  5 siblings, 0 replies; 9+ messages in thread
From: Jonas Jensen @ 2014-01-20 11:13 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, linux-kernel, davem, f.fainelli, bhutchings,
	Jonas Jensen

.ndo_set_mac_address hook callback already supports IFF_LIVE_ADDR_CHANGE
so add it to our flags.

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Applies to next-20140120

 drivers/net/ethernet/moxa/moxart_ether.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index ca892bb..6df372f 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -728,7 +728,7 @@ static int moxart_mac_probe(struct platform_device *pdev)
 	ether_setup(ndev);
 	ndev->netdev_ops = &moxart_netdev_ops;
 	netif_napi_add(ndev, &priv->napi, moxart_rx_poll, RX_DESC_NUM);
-	ndev->priv_flags |= IFF_UNICAST_FLT;
+	ndev->priv_flags |= IFF_UNICAST_FLT | IFF_LIVE_ADDR_CHANGE;
 	ndev->irq = irq;
 
 	SET_NETDEV_DEV(ndev, &pdev->dev);
-- 
1.8.2.1

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

* [PATCH v3 6/7] net: moxa: generate random address
  2014-01-20 11:13 [PATCH v3 1/7] net: moxa: clear TX descriptor length bits between sends Jonas Jensen
                   ` (3 preceding siblings ...)
  2014-01-20 11:13 ` [PATCH v3 5/7] net: moxa: add IFF_LIVE_ADDR_CHANGE flag Jonas Jensen
@ 2014-01-20 11:13 ` Jonas Jensen
  2014-01-20 11:13 ` [PATCH v3 7/7] net: moxa: use eth_mac_addr() Jonas Jensen
  5 siblings, 0 replies; 9+ messages in thread
From: Jonas Jensen @ 2014-01-20 11:13 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, linux-kernel, davem, f.fainelli, bhutchings,
	Jonas Jensen

The address register is zero:ed on boot, fill it with a randomly generated
address on probe.

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Applies to next-20140120

 drivers/net/ethernet/moxa/moxart_ether.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index 6df372f..0f25f4dc 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -740,6 +740,12 @@ static int moxart_mac_probe(struct platform_device *pdev)
 		goto init_fail;
 	}
 
+	if (!is_valid_ether_addr(ndev->dev_addr)) {
+		eth_hw_addr_random(ndev);
+		netdev_info(ndev, "generated random MAC address %pM\n",
+			    ndev->dev_addr);
+	}
+
 	netdev_dbg(ndev, "%s: IRQ=%d address=%pM\n",
 		   __func__, ndev->irq, ndev->dev_addr);
 
-- 
1.8.2.1

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

* [PATCH v3 7/7] net: moxa: use eth_mac_addr()
  2014-01-20 11:13 [PATCH v3 1/7] net: moxa: clear TX descriptor length bits between sends Jonas Jensen
                   ` (4 preceding siblings ...)
  2014-01-20 11:13 ` [PATCH v3 6/7] net: moxa: generate random address Jonas Jensen
@ 2014-01-20 11:13 ` Jonas Jensen
  5 siblings, 0 replies; 9+ messages in thread
From: Jonas Jensen @ 2014-01-20 11:13 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, linux-kernel, davem, f.fainelli, bhutchings,
	Jonas Jensen

Replace boilerplate in moxart_set_mac_address() with eth_mac_addr().

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Applies to next-20140120

 drivers/net/ethernet/moxa/moxart_ether.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index 0f25f4dc..8378be9 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -56,12 +56,7 @@ static void moxart_update_mac_address(struct net_device *ndev)
 
 static int moxart_set_mac_address(struct net_device *ndev, void *addr)
 {
-	struct sockaddr *address = addr;
-
-	if (!is_valid_ether_addr(address->sa_data))
-		return -EADDRNOTAVAIL;
-
-	memcpy(ndev->dev_addr, address->sa_data, ndev->addr_len);
+	eth_mac_addr(ndev, addr);
 	moxart_update_mac_address(ndev);
 
 	return 0;
-- 
1.8.2.1

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

* Re: [PATCH v3 3/7] net: moxa: connect to PHY
       [not found]   ` <1390216399-27028-3-git-send-email-jonas.jensen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2014-01-20 14:57     ` Rob Herring
  2014-01-21 13:50       ` Jonas Jensen
  0 siblings, 1 reply; 9+ messages in thread
From: Rob Herring @ 2014-01-20 14:57 UTC (permalink / raw)
  To: Jonas Jensen
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Florian Fainelli,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Ben Hutchings, David Miller,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Mon, Jan 20, 2014 at 5:13 AM, Jonas Jensen <jonas.jensen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> The kernel now has a MDIO bus driver and a phy_driver (RTL8201CP),
> connect to this PHY using OF.
>
> Signed-off-by: Jonas Jensen <jonas.jensen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>
> Notes:
>     Applies to next-20140120
>
>  .../devicetree/bindings/net/moxa,moxart-mac.txt    | 47 ++++++++++-
>  drivers/net/ethernet/moxa/moxart_ether.c           | 92 +++++++++++++++++++++-
>  drivers/net/ethernet/moxa/moxart_ether.h           |  2 +
>  3 files changed, 138 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt b/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt
> index 583418b..94c1f3b 100644
> --- a/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt
> +++ b/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt
> @@ -1,21 +1,64 @@
>  MOXA ART Ethernet Controller
>
> +Integrated MDIO bus node:
> +
> +- compatible: "moxa,moxart-mdio"
> +- Inherits from MDIO bus node binding[1]
> +
> +[1] Documentation/devicetree/bindings/net/phy.txt
> +
> +
> +Ethernet node:
> +
>  Required properties:
>
>  - compatible : Must be "moxa,moxart-mac"
>  - reg : Should contain register location and length
>  - interrupts : Should contain the mac interrupt number
>
> +Optional Properties:
> +
> +- phy-handle : the phandle to a PHY node
> +
> +
>  Example:
>
> +       mdio0: mdio@90900090 {
> +               compatible = "moxa,moxart-mdio";
> +               reg = <0x90900090 0x8>;
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +
> +               ethphy0: ethernet-phy@1 {
> +                       device_type = "ethernet-phy";

Drop this. device_type is only for real OpenFirmware.

> +                       compatible = "moxa,moxart-rtl8201cp", "ethernet-phy-ieee802.3-c22";
> +                       reg = <1>;
> +               };
> +       };
> +
> +       mdio1: mdio@92000090 {
> +               compatible = "moxa,moxart-mdio";
> +               reg = <0x92000090 0x8>;
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +
> +               ethphy1: ethernet-phy@1 {
> +                       device_type = "ethernet-phy";
> +                       compatible = "moxa,moxart-rtl8201cp", "ethernet-phy-ieee802.3-c22";
> +                       reg = <1>;
> +               };
> +       };
> +
>         mac0: mac@90900000 {

Not part of this patch, but this should really be ethernet@...

>                 compatible = "moxa,moxart-mac";
> -               reg =   <0x90900000 0x100>;
> +               reg = <0x90900000 0x90>;
>                 interrupts = <25 0>;
> +               phy-handle = <&ethphy0>;
>         };
>
>         mac1: mac@92000000 {
>                 compatible = "moxa,moxart-mac";
> -               reg =   <0x92000000 0x100>;
> +               reg = <0x92000000 0x90>;
>                 interrupts = <27 0>;
> +               phy-handle = <&ethphy1>;
>         };
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v3 3/7] net: moxa: connect to PHY
  2014-01-20 14:57     ` Rob Herring
@ 2014-01-21 13:50       ` Jonas Jensen
  0 siblings, 0 replies; 9+ messages in thread
From: Jonas Jensen @ 2014-01-21 13:50 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, linux-kernel, davem, f.fainelli, bhutchings,
	robherring2, Jonas Jensen

The kernel now has a MDIO bus driver and a phy_driver (RTL8201CP),
connect to this PHY using OF.

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Thanks for reviewing,
    
    This time I'll avoid sending out the entire set, attaching it here
    directly to my reply.
    
    Because the DT example is directly imported from files in arch/arm/
    those must be updated too. I'll submit those in a separate fixup patch.
    
    Changes since v3:
    
    1. drop device_type property from DT example
    2. replace "mac@" with "ethernet@" in DT example
    
    Applies to next-20140121

 .../devicetree/bindings/net/moxa,moxart-mac.txt    | 49 +++++++++++-
 drivers/net/ethernet/moxa/moxart_ether.c           | 92 +++++++++++++++++++++-
 drivers/net/ethernet/moxa/moxart_ether.h           |  2 +
 3 files changed, 138 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt b/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt
index 583418b..36d5185 100644
--- a/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt
+++ b/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt
@@ -1,21 +1,62 @@
 MOXA ART Ethernet Controller
 
+Integrated MDIO bus node:
+
+- compatible: "moxa,moxart-mdio"
+- Inherits from MDIO bus node binding[1]
+
+[1] Documentation/devicetree/bindings/net/phy.txt
+
+
+Ethernet node:
+
 Required properties:
 
 - compatible : Must be "moxa,moxart-mac"
 - reg : Should contain register location and length
 - interrupts : Should contain the mac interrupt number
 
+Optional Properties:
+
+- phy-handle : the phandle to a PHY node
+
+
 Example:
 
-	mac0: mac@90900000 {
+	mdio0: mdio@90900090 {
+		compatible = "moxa,moxart-mdio";
+		reg = <0x90900090 0x8>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy0: ethernet-phy@1 {
+			compatible = "moxa,moxart-rtl8201cp", "ethernet-phy-ieee802.3-c22";
+			reg = <1>;
+		};
+	};
+
+	mdio1: mdio@92000090 {
+		compatible = "moxa,moxart-mdio";
+		reg = <0x92000090 0x8>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy1: ethernet-phy@1 {
+			compatible = "moxa,moxart-rtl8201cp", "ethernet-phy-ieee802.3-c22";
+			reg = <1>;
+		};
+	};
+
+	mac0: ethernet@90900000 {
 		compatible = "moxa,moxart-mac";
-		reg =	<0x90900000 0x100>;
+		reg = <0x90900000 0x90>;
 		interrupts = <25 0>;
+		phy-handle = <&ethphy0>;
 	};
 
-	mac1: mac@92000000 {
+	mac1: ethernet@92000000 {
 		compatible = "moxa,moxart-mac";
-		reg =	<0x92000000 0x100>;
+		reg = <0x92000000 0x90>;
 		interrupts = <27 0>;
+		phy-handle = <&ethphy1>;
 	};
diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index 17c9f0e..c19bff2 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -25,6 +25,9 @@
 #include <linux/of_irq.h>
 #include <linux/crc32.h>
 #include <linux/crc32c.h>
+#include <linux/phy.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
 
 #include "moxart_ether.h"
 
@@ -60,6 +63,16 @@ static int moxart_set_mac_address(struct net_device *ndev, void *addr)
 	return 0;
 }
 
+static int moxart_do_ioctl(struct net_device *ndev, struct ifreq *ir, int cmd)
+{
+	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
+
+	if (!netif_running(ndev))
+		return -EINVAL;
+
+	return phy_mii_ioctl(priv->phy_dev, ir, cmd);
+}
+
 static void moxart_mac_free_memory(struct net_device *ndev)
 {
 	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
@@ -109,6 +122,19 @@ static void moxart_mac_enable(struct net_device *ndev)
 	writel(priv->reg_maccr, priv->base + REG_MAC_CTRL);
 }
 
+static void moxart_mac_update_duplex(struct net_device *ndev)
+{
+	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
+
+	priv->reg_maccr &= ~(FULLDUP | ENRX_IN_HALFTX);
+	if (priv->duplex)
+		priv->reg_maccr |= FULLDUP;
+	else
+		priv->reg_maccr |= ENRX_IN_HALFTX;
+
+	writel(priv->reg_maccr, priv->base + REG_MAC_CTRL);
+}
+
 static void moxart_mac_setup_desc_ring(struct net_device *ndev)
 {
 	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
@@ -168,6 +194,9 @@ static int moxart_mac_open(struct net_device *ndev)
 	moxart_update_mac_address(ndev);
 	moxart_mac_setup_desc_ring(ndev);
 	moxart_mac_enable(ndev);
+
+	phy_start(priv->phy_dev);
+
 	netif_start_queue(ndev);
 
 	netdev_dbg(ndev, "%s: IMR=0x%x, MACCR=0x%x\n",
@@ -183,6 +212,8 @@ static int moxart_mac_stop(struct net_device *ndev)
 
 	napi_disable(&priv->napi);
 
+	phy_stop(priv->phy_dev);
+
 	netif_stop_queue(ndev);
 
 	/* disable all interrupts */
@@ -435,12 +466,49 @@ static struct net_device_ops moxart_netdev_ops = {
 	.ndo_set_mac_address	= moxart_set_mac_address,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_do_ioctl		= moxart_do_ioctl,
 };
 
+static void moxart_adjust_link(struct net_device *ndev)
+{
+	struct moxart_mac_priv_t *priv = netdev_priv(ndev);
+	unsigned long flags;
+	int status_change = 0;
+
+	if (priv->phy_dev->link) {
+		if (priv->speed != priv->phy_dev->speed) {
+			priv->speed = priv->phy_dev->speed;
+			status_change = 1;
+		}
+
+		if (priv->duplex != priv->phy_dev->duplex) {
+			spin_lock_irqsave(&priv->txlock, flags);
+
+			priv->duplex = priv->phy_dev->duplex;
+			moxart_mac_update_duplex(ndev);
+
+			spin_unlock_irqrestore(&priv->txlock, flags);
+			status_change = 1;
+		}
+	}
+
+	if (priv->link != priv->phy_dev->link) {
+		if (!priv->phy_dev->link) {
+			priv->speed = 0;
+			priv->duplex = -1;
+		}
+		priv->link = priv->phy_dev->link;
+		status_change = 1;
+	}
+
+	if (status_change)
+		phy_print_status(priv->phy_dev);
+}
+
 static int moxart_mac_probe(struct platform_device *pdev)
 {
 	struct device *p_dev = &pdev->dev;
-	struct device_node *node = p_dev->of_node;
+	struct device_node *node = p_dev->of_node, *phy_node;
 	struct net_device *ndev;
 	struct moxart_mac_priv_t *priv;
 	struct resource *res;
@@ -461,6 +529,28 @@ static int moxart_mac_probe(struct platform_device *pdev)
 	priv = netdev_priv(ndev);
 	priv->ndev = ndev;
 
+	priv->link = 0;
+	priv->speed = 0;
+	priv->duplex = -1;
+
+	phy_node = of_parse_phandle(node, "phy-handle", 0);
+	if (!phy_node) {
+		dev_err(p_dev, "of_parse_phandle failed\n");
+		ret = -ENODEV;
+		goto init_fail;
+	}
+
+	if (phy_node) {
+		priv->phy_dev = of_phy_connect(priv->ndev, phy_node,
+					       &moxart_adjust_link,
+					       0, of_get_phy_mode(node));
+		if (!priv->phy_dev) {
+			dev_err(p_dev, "of_phy_connect failed\n");
+			ret = -ENODEV;
+			goto init_fail;
+		}
+	}
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	ndev->base_addr = res->start;
 	priv->base = devm_ioremap_resource(p_dev, res);
diff --git a/drivers/net/ethernet/moxa/moxart_ether.h b/drivers/net/ethernet/moxa/moxart_ether.h
index 2be9280..b8877bf 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.h
+++ b/drivers/net/ethernet/moxa/moxart_ether.h
@@ -297,6 +297,8 @@ struct moxart_mac_priv_t {
 	unsigned int reg_imr;
 	struct napi_struct napi;
 	struct net_device *ndev;
+	struct phy_device *phy_dev;
+	int speed, duplex, link;
 
 	dma_addr_t rx_base;
 	dma_addr_t rx_mapping[RX_DESC_NUM];
-- 
1.8.2.1

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

end of thread, other threads:[~2014-01-21 13:50 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-20 11:13 [PATCH v3 1/7] net: moxa: clear TX descriptor length bits between sends Jonas Jensen
2014-01-20 11:13 ` [PATCH v3 2/7] net: moxa: fix build_skb() memory corruption Jonas Jensen
2014-01-20 11:13 ` [PATCH v3 3/7] net: moxa: connect to PHY Jonas Jensen
     [not found]   ` <1390216399-27028-3-git-send-email-jonas.jensen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-01-20 14:57     ` Rob Herring
2014-01-21 13:50       ` Jonas Jensen
2014-01-20 11:13 ` [PATCH v3 4/7] net: moxa: add ethtool support Jonas Jensen
2014-01-20 11:13 ` [PATCH v3 5/7] net: moxa: add IFF_LIVE_ADDR_CHANGE flag Jonas Jensen
2014-01-20 11:13 ` [PATCH v3 6/7] net: moxa: generate random address Jonas Jensen
2014-01-20 11:13 ` [PATCH v3 7/7] net: moxa: use eth_mac_addr() Jonas Jensen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).