netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code
@ 2010-07-21 13:37 Mike Frysinger
  2010-07-21 13:37 ` [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support Mike Frysinger
  2010-07-21 15:02 ` [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code Lennert Buytenhek
  0 siblings, 2 replies; 21+ messages in thread
From: Mike Frysinger @ 2010-07-21 13:37 UTC (permalink / raw)
  To: netdev, David S. Miller
  Cc: uclinux-dist-devel, Karl Beldan, Lennert Buytenhek, Graf Yang,
	Bryan Wu

From: Graf Yang <graf.yang@analog.com>

Signed-off-by: Graf Yang <graf.yang@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 include/linux/if_ether.h  |    1 +
 include/linux/netdevice.h |   10 +++
 include/net/dsa.h         |    2 +-
 net/dsa/Kconfig           |    3 +
 net/dsa/Makefile          |    1 +
 net/dsa/dsa.c             |    6 ++
 net/dsa/dsa_priv.h        |    2 +
 net/dsa/slave.c           |   18 ++++++
 net/dsa/tag_stpid.c       |  147 +++++++++++++++++++++++++++++++++++++++++++++
 net/ethernet/eth.c        |    2 +
 10 files changed, 191 insertions(+), 1 deletions(-)
 create mode 100644 net/dsa/tag_stpid.c

diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index c831467..cb9e2be 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -107,6 +107,7 @@
 #define ETH_P_ARCNET	0x001A		/* 1A for ArcNet :-)            */
 #define ETH_P_DSA	0x001B		/* Distributed Switch Arch.	*/
 #define ETH_P_TRAILER	0x001C		/* Trailer switch tagging	*/
+#define ETH_P_STPID	0x001D		/* STPID switch tagging		*/
 #define ETH_P_PHONET	0x00F5		/* Nokia Phonet frames          */
 #define ETH_P_IEEE802154 0x00F6		/* IEEE802.15.4 frame		*/
 #define ETH_P_CAIF	0x00F7		/* ST-Ericsson CAIF protocol	*/
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b626289..a13dca4 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1140,6 +1140,16 @@ static inline bool netdev_uses_trailer_tags(struct net_device *dev)
 	return 0;
 }
 
+static inline bool netdev_uses_stpid_tags(struct net_device *dev)
+{
+#ifdef CONFIG_NET_DSA_TAG_STPID
+	if (dev->dsa_ptr != NULL)
+		return dsa_uses_stpid_tags(dev->dsa_ptr);
+#endif
+
+	return 0;
+}
+
 /**
  *	netdev_priv - access network device private data
  *	@dev: network device
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 839f768..21a5e2e 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -56,6 +56,6 @@ struct dsa_platform_data {
 
 extern bool dsa_uses_dsa_tags(void *dsa_ptr);
 extern bool dsa_uses_trailer_tags(void *dsa_ptr);
-
+extern bool dsa_uses_stpid_tags(void *dsa_ptr);
 
 #endif
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index 1120178..ee8d705 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -23,6 +23,9 @@ config NET_DSA_TAG_TRAILER
 	bool
 	default n
 
+config NET_DSA_TAG_STPID
+	bool
+	default n
 
 # switch drivers
 config NET_DSA_MV88E6XXX
diff --git a/net/dsa/Makefile b/net/dsa/Makefile
index 2374faf..4881577 100644
--- a/net/dsa/Makefile
+++ b/net/dsa/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_NET_DSA_TAG_DSA) += tag_dsa.o
 obj-$(CONFIG_NET_DSA_TAG_EDSA) += tag_edsa.o
 obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o
+obj-$(CONFIG_NET_DSA_TAG_STPID) += tag_stpid.o
 
 # switch drivers
 obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 6112a12..8cb4dfa 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -220,6 +220,12 @@ bool dsa_uses_trailer_tags(void *dsa_ptr)
 	return !!(dst->tag_protocol == htons(ETH_P_TRAILER));
 }
 
+bool dsa_uses_stpid_tags(void *dsa_ptr)
+{
+	struct dsa_switch_tree *dst = dsa_ptr;
+
+	return !!(dst->tag_protocol == htons(ETH_P_STPID));
+}
 
 /* link polling *************************************************************/
 static void dsa_link_poll_work(struct work_struct *ugly)
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 4b0ea05..be76ded 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -177,5 +177,7 @@ netdev_tx_t edsa_xmit(struct sk_buff *skb, struct net_device *dev);
 /* tag_trailer.c */
 netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev);
 
+/* tag_stpid.c */
+int stpid_xmit(struct sk_buff *skb, struct net_device *dev);
 
 #endif
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 64ca2a6..a1b30a7 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -333,6 +333,19 @@ static const struct net_device_ops trailer_netdev_ops = {
 	.ndo_do_ioctl		= dsa_slave_ioctl,
 };
 #endif
+#ifdef CONFIG_NET_DSA_TAG_STPID
+static const struct net_device_ops stpid_netdev_ops = {
+	.ndo_init		= dsa_slave_init,
+	.ndo_open		= dsa_slave_open,
+	.ndo_stop		= dsa_slave_close,
+	.ndo_start_xmit		= stpid_xmit,
+	.ndo_change_rx_flags	= dsa_slave_change_rx_flags,
+	.ndo_set_rx_mode	= dsa_slave_set_rx_mode,
+	.ndo_set_multicast_list = dsa_slave_set_rx_mode,
+	.ndo_set_mac_address	= dsa_slave_set_mac_address,
+	.ndo_do_ioctl		= dsa_slave_ioctl,
+};
+#endif
 
 /* slave device setup *******************************************************/
 struct net_device *
@@ -370,6 +383,11 @@ dsa_slave_create(struct dsa_switch *ds, struct device *parent,
 		slave_dev->netdev_ops = &trailer_netdev_ops;
 		break;
 #endif
+#ifdef CONFIG_NET_DSA_TAG_STPID
+	case htons(ETH_P_STPID):
+		slave_dev->netdev_ops = &stpid_netdev_ops;
+		break;
+#endif
 	default:
 		BUG();
 	}
diff --git a/net/dsa/tag_stpid.c b/net/dsa/tag_stpid.c
new file mode 100644
index 0000000..b5d9829
--- /dev/null
+++ b/net/dsa/tag_stpid.c
@@ -0,0 +1,147 @@
+/*
+ * net/dsa/tag_stpid.c - special tag identifier,
+ * 0x810 + 4 bit "port mask" + 3 bit 8021p + 1 bit CFI + 12 bit VLAN ID
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include "dsa_priv.h"
+
+#define ETH_P_8021QH      (ETH_P_8021Q >> 8)
+#define ETH_P_8021QL      (ETH_P_8021Q & 0xFF)
+#define STPID_HLEN        4
+
+#define ZERO_VID          0
+#define RESERVED_VID      0xFFF
+#define STPID_VID         ZERO_VID
+
+int stpid_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct dsa_slave_priv *p = netdev_priv(dev);
+	u8 *dsa_header;
+
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += skb->len;
+
+	/*
+	 * For 802.1Q frames, convert to STPID tagged frames,
+	 * do nothing for common frames.
+	 */
+	if (skb->protocol == htons(ETH_P_8021Q)) {
+		if (skb_cow_head(skb, 0) < 0)
+			goto out_free;
+
+		dsa_header = skb->data + 2 * ETH_ALEN;
+		dsa_header[1] = p->port & 0x03;
+	}
+
+	skb->protocol = htons(ETH_P_STPID);
+
+	skb->dev = p->parent->dst->master_netdev;
+	dev_queue_xmit(skb);
+
+	return NETDEV_TX_OK;
+
+out_free:
+	kfree_skb(skb);
+	return NETDEV_TX_OK;
+}
+
+static int stpid_rcv(struct sk_buff *skb, struct net_device *dev,
+		   struct packet_type *pt, struct net_device *orig_dev)
+{
+	struct dsa_switch_tree *dst = dev->dsa_ptr;
+	struct dsa_switch *ds = dst->ds[0];
+	u8 *dsa_header;
+	int source_port;
+	int vid;
+
+	if (unlikely(ds == NULL))
+		goto out_drop;
+
+	skb = skb_unshare(skb, GFP_ATOMIC);
+	if (skb == NULL)
+		goto out;
+
+	/* The ether_head has been pulled by master driver */
+	dsa_header = skb->data - 2;
+
+	vid = ((dsa_header[2] & 0x0f)<<8 | dsa_header[3]);
+
+	source_port = dsa_header[1] & 0x03;
+	if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
+		goto out_drop;
+
+	if (((dsa_header[0] & ETH_P_8021QH) == ETH_P_8021QH) &&
+			(vid != STPID_VID)) {
+		u8 new_header[STPID_HLEN];
+
+		/* Convert STPID tag to 802.1q tag */
+		new_header[0] = ETH_P_8021QH;
+		new_header[1] = ETH_P_8021QL;
+
+		if (skb->ip_summed == CHECKSUM_COMPLETE) {
+			__wsum c = skb->csum;
+			c = csum_add(c, csum_partial(new_header, 2, 0));
+			c = csum_sub(c, csum_partial(dsa_header, 2, 0));
+			skb->csum = c;
+		}
+		memcpy(dsa_header, new_header, STPID_HLEN / 2);
+
+	} else if ((dsa_header[0] & ETH_P_8021QH) &&
+			(vid == STPID_VID)) {
+
+		if (unlikely(!pskb_may_pull(skb, STPID_HLEN)))
+			goto out_drop;
+
+		/* Remove STPID tag and update checksum. */
+		if (skb->ip_summed == CHECKSUM_COMPLETE) {
+			__wsum c = skb->csum;
+			c = csum_sub(c, csum_partial(dsa_header, STPID_HLEN, 0));
+			skb->csum = c;
+		}
+		memmove(skb->data - ETH_HLEN + STPID_HLEN,
+				skb->data - ETH_HLEN, 2 * ETH_ALEN);
+		skb_pull(skb, STPID_HLEN);
+	}
+
+	skb->dev = ds->ports[source_port];
+	skb_push(skb, ETH_HLEN);
+	skb->pkt_type = PACKET_HOST;
+	skb->protocol = eth_type_trans(skb, skb->dev);
+	skb->dev->last_rx = jiffies;
+	skb->dev->stats.rx_packets++;
+	skb->dev->stats.rx_bytes += skb->len;
+	netif_receive_skb(skb);
+
+	return 0;
+
+out_drop:
+	kfree_skb(skb);
+out:
+	return 0;
+}
+
+static struct packet_type stpid_packet_type = {
+	.type	= __constant_htons(ETH_P_STPID),
+	.func	= stpid_rcv,
+};
+
+static int __init stpid_init_module(void)
+{
+	dev_add_pack(&stpid_packet_type);
+	return 0;
+}
+module_init(stpid_init_module);
+
+static void __exit stpid_cleanup_module(void)
+{
+	dev_remove_pack(&stpid_packet_type);
+}
+module_exit(stpid_cleanup_module);
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 215c839..964f9d2 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -194,6 +194,8 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
 		return htons(ETH_P_DSA);
 	if (netdev_uses_trailer_tags(dev))
 		return htons(ETH_P_TRAILER);
+	if (netdev_uses_stpid_tags(dev))
+		return htons(ETH_P_STPID);
 
 	if (ntohs(eth->h_proto) >= 1536)
 		return eth->h_proto;
-- 
1.7.1.1


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

* [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support
  2010-07-21 13:37 [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code Mike Frysinger
@ 2010-07-21 13:37 ` Mike Frysinger
  2010-07-21 15:16   ` Lennert Buytenhek
  2010-07-21 16:29   ` [PATCH 2/2 v2] " Mike Frysinger
  2010-07-21 15:02 ` [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code Lennert Buytenhek
  1 sibling, 2 replies; 21+ messages in thread
From: Mike Frysinger @ 2010-07-21 13:37 UTC (permalink / raw)
  To: netdev, David S. Miller
  Cc: uclinux-dist-devel, Karl Beldan, Lennert Buytenhek, Graf Yang,
	Bryan Wu

From: Graf Yang <graf.yang@analog.com>

Signed-off-by: Graf Yang <graf.yang@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 net/dsa/Kconfig    |    7 +
 net/dsa/Makefile   |    1 +
 net/dsa/ksz8893m.c |  359 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 net/dsa/ksz8893m.h |  223 ++++++++++++++++++++++++++++++++
 4 files changed, 590 insertions(+), 0 deletions(-)
 create mode 100644 net/dsa/ksz8893m.c
 create mode 100644 net/dsa/ksz8893m.h

diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index ee8d705..4a87436 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -60,4 +60,11 @@ config NET_DSA_MV88E6123_61_65
 	  This enables support for the Marvell 88E6123/6161/6165
 	  ethernet switch chips.
 
+config NET_DSA_KSZ8893M
+	bool "MICREL KSZ8893MQL/BL ethernet switch chip support"
+	select NET_DSA_TAG_STPID
+	---help---
+	  This enables support for the Micrel KSZ8893MQL/BL
+	  ethernet switch chips.
+
 endif
diff --git a/net/dsa/Makefile b/net/dsa/Makefile
index 4881577..c4295e3 100644
--- a/net/dsa/Makefile
+++ b/net/dsa/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o
 obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
 obj-$(CONFIG_NET_DSA_MV88E6123_61_65) += mv88e6123_61_65.o
 obj-$(CONFIG_NET_DSA_MV88E6131) += mv88e6131.o
+obj-$(CONFIG_NET_DSA_KSZ8893M) += ksz8893m.o
 
 # the core
 obj-$(CONFIG_NET_DSA) += dsa.o slave.o
diff --git a/net/dsa/ksz8893m.c b/net/dsa/ksz8893m.c
new file mode 100644
index 0000000..98cce04
--- /dev/null
+++ b/net/dsa/ksz8893m.c
@@ -0,0 +1,359 @@
+/*
+ * Integrated 3-Port 10/100 Managed Switch with PHYs
+ *
+ * - KSZ8893M support
+ *
+ * Copyright 2008-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#define pr_fmt(fmt) "ksz8893m: " fmt
+
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <linux/spi/spi.h>
+#include "dsa_priv.h"
+#include "ksz8893m.h"
+
+#define  BUF_LEN 6
+
+static struct _spi_switch {
+	struct spi_transfer xfer;
+	struct spi_device *dev;
+} sw;
+
+static int ksz8893m_read(unsigned char *din, unsigned char reg, int len)
+{
+	int i, ret;
+	struct spi_message message;
+	unsigned char dout[BUF_LEN];
+	struct spi_transfer *t = &sw.xfer;
+
+	t->len = len;
+	t->tx_buf = dout;
+	t->rx_buf = din;
+	dout[0] = SPI_READ;
+	dout[1] = reg;
+	for (i = 2; i < len; i++)
+		dout[i] = 0;
+
+	spi_message_init(&message);
+	spi_message_add_tail(t, &message);
+	ret = spi_sync(sw.dev, &message);
+	if (!ret)
+		return message.status;
+
+	pr_err("read reg%d failed, ret=%d\n", reg, ret);
+	return ret;
+}
+
+static int ksz8893m_write(unsigned char *dout, unsigned char reg, int len)
+{
+	int ret;
+	struct spi_message message;
+	unsigned char din[BUF_LEN];
+	struct spi_transfer *t = &sw.xfer;
+
+	t->len = len;
+	t->tx_buf = dout;
+	t->rx_buf = din;
+	dout[0] = SPI_WRITE;
+	dout[1] = reg;
+
+	spi_message_init(&message);
+	spi_message_add_tail(t, &message);
+	ret = spi_sync(sw.dev, &message);
+	if (!ret)
+		return message.status;
+
+	pr_err("write reg%d failed, ret=%d\n", reg, ret);
+	return ret;
+}
+
+static char *ksz8893m_probe(struct mii_bus *bus, int sw_addr)
+{
+	int ret, phyid_low, phyid_high;
+	unsigned char din[BUF_LEN];
+
+	phyid_high = mdiobus_read(bus, KSZ8893M_CPU_PORT, MII_PHYSID1);
+	phyid_low = mdiobus_read(bus, KSZ8893M_CPU_PORT, MII_PHYSID2);
+	if (phyid_high != PHYID_HIGH || phyid_low != PHYID_LOW)
+		return NULL;
+
+	ret = ksz8893m_read(din, ChipID0, 3);
+
+	if (!ret && FAMILY_ID == din[2])
+		return "KSZ8893M";
+
+	return NULL;
+}
+
+static int ksz8893m_switch_reset(struct dsa_switch *ds)
+{
+	return 0;
+}
+
+static int ksz8893m_setup_global(struct dsa_switch *ds)
+{
+	int ret;
+	unsigned char dout[BUF_LEN];
+	unsigned char din[BUF_LEN];
+
+	/* Set VLAN VID of port1 */
+	ret = ksz8893m_read(din, Port1Control3, 3);
+	if (ret)
+		return ret;
+	din[2] &= 0xf0;
+	dout[2] = (DEFAULT_PORT_VID & 0xfff) >> 8 | din[2];
+	dout[3] = DEFAULT_PORT_VID & 0xff;
+	ret = ksz8893m_write(dout, Port1Control3, 4);
+	if (ret)
+		return ret;
+
+	/* Set VLAN VID of port2 */
+	ret = ksz8893m_read(din, Port2Control3, 3);
+	if (ret)
+		return ret;
+	din[2] &= 0xf0;
+	dout[2] = (DEFAULT_PORT_VID & 0xfff) >> 8 | din[2];
+	dout[3] = DEFAULT_PORT_VID & 0xff;
+	ret = ksz8893m_write(dout, Port2Control3, 4);
+	if (ret)
+		return ret;
+
+	/* Set VLAN VID of port3 */
+	ret = ksz8893m_read(din, Port3Control3, 3);
+	if (ret)
+		return ret;
+	din[2] &= 0xf0;
+	dout[2] = (DEFAULT_PORT_VID & 0xfff) >> 8 | din[2];
+	dout[3] = DEFAULT_PORT_VID & 0xff;
+	ret = ksz8893m_write(dout, Port3Control3, 4);
+	if (ret)
+		return ret;
+
+	/* Insert VLAN tag that egress Port3 */
+	ret = ksz8893m_read(din, Port3Control0, 3);
+	if (ret)
+		return ret;
+	dout[2] = TAG_INSERTION | din[2];
+	ret = ksz8893m_write(dout, Port3Control0, 3);
+	if (ret)
+		return ret;
+
+	/* Enable STPID Mode */
+	ret = ksz8893m_read(din, GlobalControl9, 3);
+	if (ret)
+		return ret;
+	dout[2] = SPECIAL_TPID_MODE | din[2];
+	ret = ksz8893m_write(dout, GlobalControl9, 3);
+	if (ret)
+		return ret;
+
+	/* Start switch */
+	dout[2] = START_SWITCH;
+	ret = ksz8893m_write(dout, ChipID1_StartSwitch, 3);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int ksz8893m_setup_port(struct dsa_switch *ds, int p)
+{
+	int val, ret;
+	val = mdiobus_read(ds->master_mii_bus, p, MII_BMCR);
+	if (val < 0)
+		return val;
+	val |= AN_ENABLE | FORCE_100 | FORCE_FULL_DUPLEX;
+	val &= ~(POWER_DOWN | DISABLE_MDIX | DIS_FAR_END_FAULT |\
+			DISABLE_TRANSMIT | DISABLE_LED);
+	ret = mdiobus_write(ds->master_mii_bus, p, MII_BMCR, val);
+	if (ret < 0)
+		return ret;
+
+	val = mdiobus_read(ds->master_mii_bus, p, MII_ADVERTISE);
+	if (val < 0)
+		return val;
+	val |= ADV_10_HALF | ADV_10_FULL | ADV_100_HALF | ADV_100_FULL;
+	ret = mdiobus_write(ds->master_mii_bus, p, MII_ADVERTISE, val);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int ksz8893m_setup(struct dsa_switch *ds)
+{
+	int i;
+	int ret;
+
+	ret = ksz8893m_switch_reset(ds);
+	if (ret < 0)
+		return ret;
+
+	ret = ksz8893m_setup_global(ds);
+	if (ret < 0)
+		return ret;
+
+	for (i = 1; i < KSZ8893M_PORT_NUM; i++) {
+		ret = ksz8893m_setup_port(ds, i);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int ksz8893m_set_addr(struct dsa_switch *ds, u8 *addr)
+{
+	return 0;
+}
+
+static int ksz8893m_port_to_phy_addr(int port)
+{
+	if (port >= 1 && port <= KSZ8893M_PORT_NUM)
+		return port;
+
+	pr_warning("use default phy addr 3\n");
+	return 3;
+}
+
+static int
+ksz8893m_phy_read(struct dsa_switch *ds, int port, int regnum)
+{
+	int phy_addr = ksz8893m_port_to_phy_addr(port);
+	return mdiobus_read(ds->master_mii_bus, phy_addr, regnum);
+}
+
+static int
+ksz8893m_phy_write(struct dsa_switch *ds,
+			      int port, int regnum, u16 val)
+{
+	int phy_addr = ksz8893m_port_to_phy_addr(port);
+	return mdiobus_write(ds->master_mii_bus, phy_addr, regnum, val);
+}
+
+static void ksz8893m_poll_link(struct dsa_switch *ds)
+{
+	int i;
+
+	for (i = 1; i < KSZ8893M_PORT_NUM; i++) {
+		struct net_device *dev;
+		int val;
+		int link;
+		int speed;
+		int duplex;
+		int anc;
+
+		dev = ds->ports[i];
+		if (dev == NULL)
+			continue;
+
+		link = 0;
+		if (dev->flags & IFF_UP) {
+			val = mdiobus_read(ds->master_mii_bus, i, MII_BMSR);
+			if (val < 0)
+				continue;
+
+			link = !!(val & LINK_STATUS);
+			anc = !!(val & AN_COMPLETE);
+		}
+
+		if (!link) {
+			if (netif_carrier_ok(dev)) {
+				printk(KERN_INFO "%s: link down\n", dev->name);
+				netif_carrier_off(dev);
+			}
+			continue;
+		}
+
+		speed = 10;
+		duplex = 0;
+		val = mdiobus_read(ds->master_mii_bus, i, MII_BMSR);
+		if (val < 0)
+			continue;
+		val &= HALF_10_CAPABLE | FULL_10_CAPABLE |\
+		       HALF_100_CAPABLE | FULL_100_CAPABLE;
+		if (val & FULL_100_CAPABLE) {
+			speed = 100;
+			duplex = 1;
+		} else if (val & HALF_100_CAPABLE) {
+			speed = 100;
+			duplex = 0;
+		} else if (val & FULL_10_CAPABLE) {
+			speed = 10;
+			duplex = 1;
+		}
+
+		if (!netif_carrier_ok(dev)) {
+			printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex\n",
+					dev->name, speed, duplex ? "full" : "half");
+			netif_carrier_on(dev);
+		}
+	}
+}
+
+static int __devinit spi_switch_probe(struct spi_device *spi)
+{
+	if (sw.dev) {
+		pr_err("only one instance supported at a time\n");
+		return 1;
+	}
+	memset(&sw.xfer, 0, sizeof(sw.xfer));
+	sw.dev = spi;
+	return 0;
+}
+
+static int __devexit spi_switch_remove(struct spi_device *spi)
+{
+	sw.dev = NULL;
+	return 0;
+}
+
+static struct spi_driver spi_switch_driver = {
+	.driver = {
+		.name	= "ksz8893m",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe	= spi_switch_probe,
+	.remove	= __devexit_p(spi_switch_remove),
+};
+
+static struct dsa_switch_driver ksz8893m_switch_driver = {
+	.tag_protocol		= __constant_htons(ETH_P_STPID),
+	.probe			= ksz8893m_probe,
+	.setup			= ksz8893m_setup,
+	.set_addr		= ksz8893m_set_addr,
+	.phy_read		= ksz8893m_phy_read,
+	.phy_write		= ksz8893m_phy_write,
+	.poll_link		= ksz8893m_poll_link,
+};
+
+static int __init ksz8893m_init(void)
+{
+	int ret;
+
+	ret = spi_register_driver(&spi_switch_driver);
+	if (ret) {
+		pr_err("can't register driver\n");
+		return ret;
+	}
+
+	register_switch_driver(&ksz8893m_switch_driver);
+	return 0;
+}
+module_init(ksz8893m_init);
+
+static void __exit ksz8893m_cleanup(void)
+{
+	spi_unregister_driver(&spi_switch_driver);
+	unregister_switch_driver(&ksz8893m_switch_driver);
+}
+module_exit(ksz8893m_cleanup);
+
+MODULE_AUTHOR("Graf Yang <graf.yang@analog.com>");
+MODULE_DESCRIPTION("KSZ8893M driver for DSA");
+MODULE_LICENSE("GPL");
diff --git a/net/dsa/ksz8893m.h b/net/dsa/ksz8893m.h
new file mode 100644
index 0000000..84f44e9
--- /dev/null
+++ b/net/dsa/ksz8893m.h
@@ -0,0 +1,223 @@
+/*
+ * Integrated 3-Port 10/100 Managed Switch with PHYs
+ *
+ * - KSZ8893M support
+ *
+ * Copyright 2008-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __KSZ8893M_H__
+#define __KSZ8893M_H__
+
+#include <linux/netdevice.h>
+
+#define KSZ8893M_PORT_NUM 3
+#define KSZ8893M_CPU_PORT 3
+
+#define DEFAULT_PORT_VID  0
+
+#define SPI_READ          3
+#define SPI_WRITE         2
+
+/* PHYID High */
+#define PHYID_HIGH        0x22
+/* PHYID Low */
+#define PHYID_LOW         0x1430
+
+/* MII Basic Control */
+#define SOFT_RESET        0x8000
+#define LOOPBACK          0x4000
+#define FORCE_100         0x2000
+#define AN_ENABLE         0x1000
+#define POWER_DOWN        0x0800
+#define ISOLATE           0x0400
+#define RESTART_AN        0x0200
+#define FORCE_FULL_DUPLEX 0x0100
+#define COLLISION_TEST    0x0080
+/* Bit Reserved */
+#define HP_MDIX           0x0020
+#define Force_MDI         0x0010
+#define DISABLE_MDIX      0x0008
+#define DIS_FAR_END_FAULT 0x0004
+#define DISABLE_TRANSMIT  0x0002
+#define DISABLE_LED       0x0001
+
+/* MII Basic Status */
+#define T4_CAPABLE        0x8000
+#define FULL_100_CAPABLE  0x4000
+#define HALF_100_CAPABLE  0x2000
+#define FULL_10_CAPABLE   0x1000
+#define HALF_10_CAPABLE   0x0800
+/* 4 Bits Reserved */
+#define PREAMBLE_SUPPRESS 0x0040
+#define AN_COMPLETE       0x0020
+#define FAR_END_FAULT     0x0010
+#define AN_CAPABLE        0x0008
+#define LINK_STATUS       0x0004
+#define JABBER_TEST       0x0002
+#define EXTENDED_CAPABLE  0x0001
+
+/* Auto-Negotiation Advertisement Ability */
+#define NEXT_PAGE         0x8000
+/* Bit Reserved */
+#define REMOTE_FAULT      0x2000
+/* 2 Bits Reserved */
+#define PAUSE             0x0400
+/* Bit Reserved */
+#define ADV_100_FULL      0x0100
+#define ADV_100_HALF      0x0080
+#define ADV_10_FULL       0x0040
+#define ADV_10_HALF       0x0020
+#define SELECTOR_FIELD    0x001F
+
+/* Auto-Negotiation Link Partner Ability */
+#define NEXT_PAGE         0x8000
+#define LP_ACK            0x4000
+#define REMOTE_FAULT      0x2000
+/* 2 Bits Reserved */
+#define PAUSE             0x0400
+/* Bit Reserved */
+#define ADV_100_FULL      0x0100
+#define ADV_100_HALF      0x0080
+#define ADV_10_FULL       0x0040
+#define ADV_10_HALF       0x0020
+/* 5 Bits Reserved */
+
+/* LinkMD Control/Status */
+#define VCT_ENABLE        0x8000
+#define VCT_RESULT        0x6000
+#define VCT_10M_SHORT     0x1000
+/* 3 Bits Reserved */
+#define VCT_FAULT_COUNT   0x01FF
+
+/* PHY Special Control/Status */
+/* 10 Bits Reserved */
+#define POLRVS            0x0020
+#define MDI_X_STATUS      0x0010
+#define FORCE_LNK         0x0008
+#define PWRSAVE           0x0004
+#define REMOTE_LOOPBACK   0x0002
+/* Bit Reserved */
+
+
+#define FAMILY_ID         0x88
+#define START_SWITCH      0x01
+#define TAG_INSERTION     0x04
+#define SPECIAL_TPID_MODE 0x01
+
+
+enum switch_phy_reg {
+	/* Global Registers: 0-15 */
+	ChipID0 = 0,
+	ChipID1_StartSwitch,
+	GlobalControl0,
+	GlobalControl1,
+	GlobalControl2, /* 4 */
+	GlobalControl3,
+	GlobalControl4,
+	GlobalControl5,
+	GlobalControl6, /* 8 */
+	GlobalControl7,
+	GlobalControl8,
+	GlobalControl9,
+	GlobalControl10, /* 12 */
+	GlobalControl11,
+	GlobalControl12,
+	GlobalControl13,
+	/* Port Registers: 16-95 */
+	Port1Control0 = 16,
+	Port1Control1,
+	Port1Control2,
+	Port1Control3,
+	Port1Control4, /* 20 */
+	Port1Control5,
+	Port1Control6,
+	Port1Control7,
+	Port1Control8, /* 24 */
+	Port1Control9,
+	Port1PHYSpecialControl_Status,
+	Port1LinkMDResult,
+	Port1Control12, /* 28 */
+	Port1Control13,
+	Port1Status0,
+	Port1Status1,
+	Port2Control0, /* 32 */
+	Port2Control1,
+	Port2Control2,
+	Port2Control3,
+	Port2Control4, /* 36 */
+	Port2Control5,
+	Port2Control6,
+	Port2Control7,
+	Port2Control8, /* 40 */
+	Port2Control9,
+	Port2PHYSpecialControl_Status,
+	Port2LinkMDResult,
+	Port2Control12, /* 44 */
+	Port2Control13,
+	Port2Status0,
+	Port2Status1,
+	Port3Control0, /* 48 */
+	Port3Control1,
+	Port3Control2,
+	Port3Control3,
+	Port3Control4, /* 52 */
+	Port3Control5,
+	Port3Control6,
+	Port3Control7,
+	Port3Control8, /* 56 */
+	Port3Control9,
+	Reservednotappliedtoport3, /* 58-62 */
+	Port3Status1 = 63,
+	/* Advanced Control Registers: 96-141 */
+	TOSPriorityControlRegister0 = 96,
+	TOSPriorityControlRegister1,
+	TOSPriorityControlRegister2,
+	TOSPriorityControlRegister3,
+	TOSPriorityControlRegister4, /* 100 */
+	TOSPriorityControlRegister5,
+	TOSPriorityControlRegister6,
+	TOSPriorityControlRegister7,
+	TOSPriorityControlRegister8, /* 104 */
+	TOSPriorityControlRegister9,
+	TOSPriorityControlRegister10,
+	TOSPriorityControlRegister11,
+	TOSPriorityControlRegister12, /* 108 */
+	TOSPriorityControlRegister13,
+	TOSPriorityControlRegister14,
+	TOSPriorityControlRegister15,
+	MACAddressRegister0 = 112,
+	MACAddressRegister1,
+	MACAddressRegister2,
+	MACAddressRegister3,
+	MACAddressRegister4,
+	MACAddressRegister5,
+	UserDefinedRegister1 = 118,
+	UserDefinedRegister2,
+	UserDefinedRegister3,
+	IndirectAccessControl0 = 121,
+	IndirectAccessControl1,
+	IndirectDataRegister8 = 123,
+	IndirectDataRegister7,
+	IndirectDataRegister6,
+	IndirectDataRegister5,
+	IndirectDataRegister4,
+	IndirectDataRegister3,
+	IndirectDataRegister2,
+	IndirectDataRegister1,
+	IndirectDataRegister0,
+	DigitalTestingStatus0 = 132,
+	DigitalTestingControl0,
+	AnalogTestingControl0,
+	AnalogTestingControl1,
+	AnalogTestingControl2,
+	AnalogTestingControl3,
+	AnalogTestingStatus,
+	AnalogTestingControl4,
+	QMDebug1,
+	QMDebug2,
+};
+
+#endif
-- 
1.7.1.1


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

* Re: [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code
  2010-07-21 13:37 [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code Mike Frysinger
  2010-07-21 13:37 ` [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support Mike Frysinger
@ 2010-07-21 15:02 ` Lennert Buytenhek
  2010-07-21 15:29   ` [Uclinux-dist-devel] " Mike Frysinger
  1 sibling, 1 reply; 21+ messages in thread
From: Lennert Buytenhek @ 2010-07-21 15:02 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: netdev, David S. Miller, uclinux-dist-devel, Karl Beldan,
	Graf Yang, Bryan Wu

On Wed, Jul 21, 2010 at 09:37:21AM -0400, Mike Frysinger wrote:

> diff --git a/net/dsa/tag_stpid.c b/net/dsa/tag_stpid.c
> new file mode 100644
> index 0000000..b5d9829
> --- /dev/null
> +++ b/net/dsa/tag_stpid.c
> @@ -0,0 +1,147 @@
> +/*
> + * net/dsa/tag_stpid.c - special tag identifier,
> + * 0x810 + 4 bit "port mask" + 3 bit 8021p + 1 bit CFI + 12 bit VLAN ID
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#include <linux/etherdevice.h>
> +#include <linux/list.h>
> +#include <linux/netdevice.h>
> +#include "dsa_priv.h"
> +
> +#define ETH_P_8021QH      (ETH_P_8021Q >> 8)
> +#define ETH_P_8021QL      (ETH_P_8021Q & 0xFF)
> +#define STPID_HLEN        4
> +
> +#define ZERO_VID          0
> +#define RESERVED_VID      0xFFF
> +#define STPID_VID         ZERO_VID
> +
> +int stpid_xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> +	struct dsa_slave_priv *p = netdev_priv(dev);
> +	u8 *dsa_header;
> +
> +	dev->stats.tx_packets++;
> +	dev->stats.tx_bytes += skb->len;

Everything up to this point looks OK, but..


> +	/*
> +	 * For 802.1Q frames, convert to STPID tagged frames,
> +	 * do nothing for common frames.
> +	 */
> +	if (skb->protocol == htons(ETH_P_8021Q)) {
> +		if (skb_cow_head(skb, 0) < 0)
> +			goto out_free;
> +
> +		dsa_header = skb->data + 2 * ETH_ALEN;
> +		dsa_header[1] = p->port & 0x03;
> +	}

This is almost certainly wrong -- according to the KSZ8893ML datasheet,
this means that VLAN tagged frames will be switched explicitly (by
sending them to p->port), but non-VLAN tagged frames will be switched
according to the switch's MAC address database.  You want explicit (i.e.
host kernel-side MAC address database lookup) switching in both cases.


> +{
> +	struct dsa_switch_tree *dst = dev->dsa_ptr;
> +	struct dsa_switch *ds = dst->ds[0];
> +	u8 *dsa_header;
> +	int source_port;
> +	int vid;
> +
> +	if (unlikely(ds == NULL))
> +		goto out_drop;
> +
> +	skb = skb_unshare(skb, GFP_ATOMIC);
> +	if (skb == NULL)
> +		goto out;
> +
> +	/* The ether_head has been pulled by master driver */
> +	dsa_header = skb->data - 2;
> +
> +	vid = ((dsa_header[2] & 0x0f)<<8 | dsa_header[3]);

Coding style (need spaces around '<<').


> +
> +	source_port = dsa_header[1] & 0x03;
> +	if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
> +		goto out_drop;
> +
> +	if (((dsa_header[0] & ETH_P_8021QH) == ETH_P_8021QH) &&

This is bogus -- what it does is:

	if ((dsa_header[0] & 0x81) == 0x81)

It doesn't look like you need to mask here at all.

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

* Re: [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support
  2010-07-21 13:37 ` [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support Mike Frysinger
@ 2010-07-21 15:16   ` Lennert Buytenhek
  2010-07-21 15:33     ` Eric Dumazet
                       ` (2 more replies)
  2010-07-21 16:29   ` [PATCH 2/2 v2] " Mike Frysinger
  1 sibling, 3 replies; 21+ messages in thread
From: Lennert Buytenhek @ 2010-07-21 15:16 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: netdev, David S. Miller, uclinux-dist-devel, Karl Beldan,
	Graf Yang, Bryan Wu

On Wed, Jul 21, 2010 at 09:37:22AM -0400, Mike Frysinger wrote:

> From: Graf Yang <graf.yang@analog.com>

Hurray for the first non-Marvell switch chip support in net/dsa!


> +#define pr_fmt(fmt) "ksz8893m: " fmt

This has no users.


> +static int ksz8893m_setup(struct dsa_switch *ds)
> +{
> +	int i;
> +	int ret;
> +
> +	ret = ksz8893m_switch_reset(ds);
> +	if (ret < 0)
> +		return ret;

It's pretty ugly that the mdiobus is passed in via the normal means,
but a reference to the SPI bus to use is just stuffed into some global
variable.

Can you not access all registers via MII?

(If not, struct dsa_chip_data will need go be extended with another
struct device pointer that we can use to find the spi bus with.)


> +static int ksz8893m_port_to_phy_addr(int port)
> +{
> +	if (port >= 1 && port <= KSZ8893M_PORT_NUM)
> +		return port;
> +
> +	pr_warning("use default phy addr 3\n");
> +	return 3;

Does this ever happen?  You should just be able to return -1 here, IMHO.


> +static int __devinit spi_switch_probe(struct spi_device *spi)
> +{
> +	if (sw.dev) {
> +		pr_err("only one instance supported at a time\n");
> +		return 1;
> +	}
> +	memset(&sw.xfer, 0, sizeof(sw.xfer));
> +	sw.dev = spi;
> +	return 0;
> +}
> +
> +static int __devexit spi_switch_remove(struct spi_device *spi)
> +{
> +	sw.dev = NULL;
> +	return 0;
> +}
> +
> +static struct spi_driver spi_switch_driver = {
> +	.driver = {
> +		.name	= "ksz8893m",
> +		.bus	= &spi_bus_type,
> +		.owner	= THIS_MODULE,
> +	},
> +	.probe	= spi_switch_probe,
> +	.remove	= __devexit_p(spi_switch_remove),
> +};

I'm not entirely happy with this.

Then again, there isn't really a clean way to deal with devices that
have multiple different host interfaces as far as I know..


> +#define KSZ8893M_PORT_NUM 3
> +#define KSZ8893M_CPU_PORT 3
> +
> +#define DEFAULT_PORT_VID  0
> +
> +#define SPI_READ          3
> +#define SPI_WRITE         2
>
> [snip]

Something tells me that half the defines (and register index definitions)
in this file aren't used.  Also:


> +/* MII Basic Control */
> +#define SOFT_RESET        0x8000
> +#define LOOPBACK          0x4000
> +#define FORCE_100         0x2000
> +#define AN_ENABLE         0x1000
> +#define POWER_DOWN        0x0800
> +#define ISOLATE           0x0400
> +#define RESTART_AN        0x0200
> +#define FORCE_FULL_DUPLEX 0x0100
> +#define COLLISION_TEST    0x0080

This part of the MII register is standard, and there are BMCR_*
definitions for this in mii.h, no need to duplicate them.


> +#define Force_MDI         0x0010

And please don't use mixed case.


> +#define FAMILY_ID         0x88
> +#define START_SWITCH      0x01
> +#define TAG_INSERTION     0x04
> +#define SPECIAL_TPID_MODE 0x01

It would be nice to mention what registers these bitfields are part of.


> +enum switch_phy_reg {
> +	/* Global Registers: 0-15 */
> +	ChipID0 = 0,
> +	ChipID1_StartSwitch,
> +	GlobalControl0,

And here, just define the registers you need only.

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

* Re: [Uclinux-dist-devel] [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code
  2010-07-21 15:02 ` [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code Lennert Buytenhek
@ 2010-07-21 15:29   ` Mike Frysinger
  2010-07-21 15:35     ` Lennert Buytenhek
  0 siblings, 1 reply; 21+ messages in thread
From: Mike Frysinger @ 2010-07-21 15:29 UTC (permalink / raw)
  To: Lennert Buytenhek
  Cc: Karl Beldan, netdev, Graf Yang, uclinux-dist-devel,
	David S. Miller

On Wed, Jul 21, 2010 at 11:02, Lennert Buytenhek wrote:
> On Wed, Jul 21, 2010 at 09:37:21AM -0400, Mike Frysinger wrote:
>> +     source_port = dsa_header[1] & 0x03;
>> +     if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
>> +             goto out_drop;
>> +
>> +     if (((dsa_header[0] & ETH_P_8021QH) == ETH_P_8021QH) &&
>
> This is bogus -- what it does is:
>
>        if ((dsa_header[0] & 0x81) == 0x81)
>
> It doesn't look like you need to mask here at all.

where does it say dsa_header[0] will always have 0x81 set ?
-mike

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

* Re: [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support
  2010-07-21 15:16   ` Lennert Buytenhek
@ 2010-07-21 15:33     ` Eric Dumazet
  2010-07-21 15:36       ` Lennert Buytenhek
  2010-07-21 16:40       ` Joe Perches
  2010-07-21 16:05     ` [Uclinux-dist-devel] " Mike Frysinger
       [not found]     ` <20100721151608.GM21121-SHk0+jKqY/D5VnbZ9m/NDkB+6BGkLq7r@public.gmane.org>
  2 siblings, 2 replies; 21+ messages in thread
From: Eric Dumazet @ 2010-07-21 15:33 UTC (permalink / raw)
  To: Lennert Buytenhek
  Cc: Mike Frysinger, netdev, David S. Miller, uclinux-dist-devel,
	Karl Beldan, Graf Yang, Bryan Wu

Le mercredi 21 juillet 2010 à 17:16 +0200, Lennert Buytenhek a écrit :

> > +#define pr_fmt(fmt) "ksz8893m: " fmt
> 
> This has no users.
> 

Dont tell this to Joe Perches ;)

It is used by all pr_err() friends

#define pr_emerg(fmt, ...) \
        printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
#define pr_alert(fmt, ...) \
        printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
#define pr_crit(fmt, ...) \
        printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
#define pr_err(fmt, ...) \
        printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
#define pr_warning(fmt, ...) \
        printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
#define pr_warn pr_warning
#define pr_notice(fmt, ...) \
        printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
#define pr_info(fmt, ...) \
        printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
#define pr_cont(fmt, ...) \
        printk(KERN_CONT fmt, ##__VA_ARGS__)



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

* Re: [Uclinux-dist-devel] [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code
  2010-07-21 15:29   ` [Uclinux-dist-devel] " Mike Frysinger
@ 2010-07-21 15:35     ` Lennert Buytenhek
  2010-07-21 16:08       ` Mike Frysinger
  0 siblings, 1 reply; 21+ messages in thread
From: Lennert Buytenhek @ 2010-07-21 15:35 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: Karl Beldan, netdev, Graf Yang, uclinux-dist-devel,
	David S. Miller

On Wed, Jul 21, 2010 at 11:29:30AM -0400, Mike Frysinger wrote:

> >> +     source_port = dsa_header[1] & 0x03;
> >> +     if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
> >> +             goto out_drop;
> >> +
> >> +     if (((dsa_header[0] & ETH_P_8021QH) == ETH_P_8021QH) &&
> >
> > This is bogus -- what it does is:
> >
> >        if ((dsa_header[0] & 0x81) == 0x81)
> >
> > It doesn't look like you need to mask here at all.
> 
> where does it say dsa_header[0] will always have 0x81 set ?

Eh?

This code is checking whether the packet has a STPID tag on it or not.
A STPID tag exists if the first 12 nibbles are 0x810.

You are checking whether the first 8 nibbles of this are equal to 0x81
by doing:

	if ((byte & 0x81) == 0x81)

What if the first byte is 0x93?  Or 0xc5?

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

* Re: [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support
  2010-07-21 15:33     ` Eric Dumazet
@ 2010-07-21 15:36       ` Lennert Buytenhek
  2010-07-21 16:40       ` Joe Perches
  1 sibling, 0 replies; 21+ messages in thread
From: Lennert Buytenhek @ 2010-07-21 15:36 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Mike Frysinger, netdev, David S. Miller, uclinux-dist-devel,
	Karl Beldan, Graf Yang, Bryan Wu

On Wed, Jul 21, 2010 at 05:33:13PM +0200, Eric Dumazet wrote:

> > > +#define pr_fmt(fmt) "ksz8893m: " fmt
> > 
> > This has no users.
> 
> Dont tell this to Joe Perches ;)
> 
> It is used by all pr_err() friends

Oops, my bad!

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

* Re: [Uclinux-dist-devel] [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support
  2010-07-21 15:16   ` Lennert Buytenhek
  2010-07-21 15:33     ` Eric Dumazet
@ 2010-07-21 16:05     ` Mike Frysinger
  2010-07-21 20:31       ` Karl Beldan
       [not found]     ` <20100721151608.GM21121-SHk0+jKqY/D5VnbZ9m/NDkB+6BGkLq7r@public.gmane.org>
  2 siblings, 1 reply; 21+ messages in thread
From: Mike Frysinger @ 2010-07-21 16:05 UTC (permalink / raw)
  To: Lennert Buytenhek
  Cc: Karl Beldan, netdev, uclinux-dist-devel, David S. Miller

On Wed, Jul 21, 2010 at 11:16, Lennert Buytenhek wrote:
> On Wed, Jul 21, 2010 at 09:37:22AM -0400, Mike Frysinger wrote:
>> +static int ksz8893m_setup(struct dsa_switch *ds)
>> +{
>> +     int i;
>> +     int ret;
>> +
>> +     ret = ksz8893m_switch_reset(ds);
>> +     if (ret < 0)
>> +             return ret;
>
> It's pretty ugly that the mdiobus is passed in via the normal means,
> but a reference to the SPI bus to use is just stuffed into some global
> variable.
>
> Can you not access all registers via MII?

it depends on the host mdio bus.  if it supports the semi-standard
behavior of toggling the OP field of MDIO frames, then yes, you can do
it via MII.  but i dont think the current mdio framework in the kernel
keeps track of that functionality, so there isnt a way in the driver
to say "is this possible, else fall back to SPI".

certainly the part that was used to develop this driver does not
support this behavior thus SPI is the only way of accessing the
extended registers.  i guess the driver could be extended so that
people could pick which mode they want to program the registers via
platform resources, but we have no way of testing that, so i say let
the person who actually can use & wants that functionality implement
it.

> (If not, struct dsa_chip_data will need go be extended with another
> struct device pointer that we can use to find the spi bus with.)

if the framework supports, i can convert the driver to it, but i'm not
sure we have the time atm to tackle reworking common frameworks.

>> +static int ksz8893m_port_to_phy_addr(int port)
>> +{
>> +     if (port >= 1 && port <= KSZ8893M_PORT_NUM)
>> +             return port;
>> +
>> +     pr_warning("use default phy addr 3\n");
>> +     return 3;
>
> Does this ever happen?  You should just be able to return -1 here, IMHO.

i dont recall seeing a warning, but presumably if it it did occur,
something else needs fixing.  so -1 is OK.

>> +/* MII Basic Control */
>> +#define SOFT_RESET        0x8000
>> +#define LOOPBACK          0x4000
>> +#define FORCE_100         0x2000
>> +#define AN_ENABLE         0x1000
>> +#define POWER_DOWN        0x0800
>> +#define ISOLATE           0x0400
>> +#define RESTART_AN        0x0200
>> +#define FORCE_FULL_DUPLEX 0x0100
>> +#define COLLISION_TEST    0x0080
>
> This part of the MII register is standard, and there are BMCR_*
> definitions for this in mii.h, no need to duplicate them.

most are copies of the MII headers, so i just converted them all and
punted the rest

>> +#define FAMILY_ID         0x88
>> +#define START_SWITCH      0x01
>> +#define TAG_INSERTION     0x04
>> +#define SPECIAL_TPID_MODE 0x01
>
> It would be nice to mention what registers these bitfields are part of.

done

>> +enum switch_phy_reg {
>> +     /* Global Registers: 0-15 */
>> +     ChipID0 = 0,
>> +     ChipID1_StartSwitch,
>> +     GlobalControl0,
>
> And here, just define the registers you need only.

i'm not sure that's necessary ... having the complete register layout
is useful for people who want to extend in the future
-mike

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

* Re: [Uclinux-dist-devel] [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code
  2010-07-21 15:35     ` Lennert Buytenhek
@ 2010-07-21 16:08       ` Mike Frysinger
  2010-07-29 17:50         ` Mike Frysinger
  0 siblings, 1 reply; 21+ messages in thread
From: Mike Frysinger @ 2010-07-21 16:08 UTC (permalink / raw)
  To: Lennert Buytenhek
  Cc: Karl Beldan, netdev, uclinux-dist-devel, David S. Miller

On Wed, Jul 21, 2010 at 11:35, Lennert Buytenhek wrote:
> On Wed, Jul 21, 2010 at 11:29:30AM -0400, Mike Frysinger wrote:
>> >> +     source_port = dsa_header[1] & 0x03;
>> >> +     if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
>> >> +             goto out_drop;
>> >> +
>> >> +     if (((dsa_header[0] & ETH_P_8021QH) == ETH_P_8021QH) &&
>> >
>> > This is bogus -- what it does is:
>> >
>> >        if ((dsa_header[0] & 0x81) == 0x81)
>> >
>> > It doesn't look like you need to mask here at all.
>>
>> where does it say dsa_header[0] will always have 0x81 set ?
>
> Eh?
>
> This code is checking whether the packet has a STPID tag on it or not.
> A STPID tag exists if the first 12 nibbles are 0x810.
>
> You are checking whether the first 8 nibbles of this are equal to 0x81
> by doing:
>
>        if ((byte & 0x81) == 0x81)
>
> What if the first byte is 0x93?  Or 0xc5?

that was my point.  should it be masking or doing a raw compare ?

i have nfc as i had nothing to do with the creation of this code.  i
dont know the first thing about VLAN tags or anything else at that
level.
-mike

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

* [PATCH 2/2 v2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support
  2010-07-21 13:37 ` [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support Mike Frysinger
  2010-07-21 15:16   ` Lennert Buytenhek
@ 2010-07-21 16:29   ` Mike Frysinger
  2010-07-21 20:45     ` Karl Beldan
  1 sibling, 1 reply; 21+ messages in thread
From: Mike Frysinger @ 2010-07-21 16:29 UTC (permalink / raw)
  To: netdev, David S. Miller
  Cc: uclinux-dist-devel, Karl Beldan, Lennert Buytenhek, Graf Yang,
	Bryan Wu

From: Graf Yang <graf.yang@analog.com>

Signed-off-by: Graf Yang <graf.yang@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
v2
	- clean up header duplication

 net/dsa/Kconfig    |    7 +
 net/dsa/Makefile   |    1 +
 net/dsa/ksz8893m.c |  341 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 net/dsa/ksz8893m.h |  163 +++++++++++++++++++++++++
 4 files changed, 512 insertions(+), 0 deletions(-)
 create mode 100644 net/dsa/ksz8893m.c
 create mode 100644 net/dsa/ksz8893m.h

diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index ee8d705..4a87436 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -60,4 +60,11 @@ config NET_DSA_MV88E6123_61_65
 	  This enables support for the Marvell 88E6123/6161/6165
 	  ethernet switch chips.
 
+config NET_DSA_KSZ8893M
+	bool "MICREL KSZ8893MQL/BL ethernet switch chip support"
+	select NET_DSA_TAG_STPID
+	---help---
+	  This enables support for the Micrel KSZ8893MQL/BL
+	  ethernet switch chips.
+
 endif
diff --git a/net/dsa/Makefile b/net/dsa/Makefile
index 4881577..c4295e3 100644
--- a/net/dsa/Makefile
+++ b/net/dsa/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o
 obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
 obj-$(CONFIG_NET_DSA_MV88E6123_61_65) += mv88e6123_61_65.o
 obj-$(CONFIG_NET_DSA_MV88E6131) += mv88e6131.o
+obj-$(CONFIG_NET_DSA_KSZ8893M) += ksz8893m.o
 
 # the core
 obj-$(CONFIG_NET_DSA) += dsa.o slave.o
diff --git a/net/dsa/ksz8893m.c b/net/dsa/ksz8893m.c
new file mode 100644
index 0000000..0bfa193
--- /dev/null
+++ b/net/dsa/ksz8893m.c
@@ -0,0 +1,341 @@
+/*
+ * Integrated 3-Port 10/100 Managed Switch with PHYs
+ *
+ * - KSZ8893M support
+ *
+ * Copyright 2008-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#define pr_fmt(fmt) "ksz8893m: " fmt
+
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <linux/spi/spi.h>
+#include "dsa_priv.h"
+#include "ksz8893m.h"
+
+#define  BUF_LEN 6
+
+static struct _spi_switch {
+	struct spi_transfer xfer;
+	struct spi_device *dev;
+} sw;
+
+static int ksz8893m_read(unsigned char *din, unsigned char reg, int len)
+{
+	int i, ret;
+	struct spi_message message;
+	unsigned char dout[BUF_LEN];
+	struct spi_transfer *t = &sw.xfer;
+
+	t->len = len;
+	t->tx_buf = dout;
+	t->rx_buf = din;
+	dout[0] = SPI_READ;
+	dout[1] = reg;
+	for (i = 2; i < len; i++)
+		dout[i] = 0;
+
+	spi_message_init(&message);
+	spi_message_add_tail(t, &message);
+	ret = spi_sync(sw.dev, &message);
+	if (!ret)
+		return message.status;
+
+	pr_err("read reg%d failed, ret=%d\n", reg, ret);
+	return ret;
+}
+
+static int ksz8893m_write(unsigned char *dout, unsigned char reg, int len)
+{
+	int ret;
+	struct spi_message message;
+	unsigned char din[BUF_LEN];
+	struct spi_transfer *t = &sw.xfer;
+
+	t->len = len;
+	t->tx_buf = dout;
+	t->rx_buf = din;
+	dout[0] = SPI_WRITE;
+	dout[1] = reg;
+
+	spi_message_init(&message);
+	spi_message_add_tail(t, &message);
+	ret = spi_sync(sw.dev, &message);
+	if (!ret)
+		return message.status;
+
+	pr_err("write reg%d failed, ret=%d\n", reg, ret);
+	return ret;
+}
+
+static char *ksz8893m_probe(struct mii_bus *bus, int sw_addr)
+{
+	int ret, phyid_low, phyid_high;
+	unsigned char din[BUF_LEN];
+
+	phyid_high = mdiobus_read(bus, KSZ8893M_CPU_PORT, MII_PHYSID1);
+	phyid_low = mdiobus_read(bus, KSZ8893M_CPU_PORT, MII_PHYSID2);
+	if (phyid_high != PHYID_HIGH || phyid_low != PHYID_LOW)
+		return NULL;
+
+	ret = ksz8893m_read(din, ChipID0, 3);
+
+	if (!ret && FAMILY_ID == din[2])
+		return "KSZ8893M";
+
+	return NULL;
+}
+
+static int ksz8893m_switch_reset(struct dsa_switch *ds)
+{
+	return 0;
+}
+
+static int ksz8893m_setup_global(struct dsa_switch *ds)
+{
+	int ret;
+	unsigned char dout[BUF_LEN];
+	unsigned char din[BUF_LEN];
+
+	/* Set VLAN VID of port1 */
+	ret = ksz8893m_read(din, Port1Control3, 3);
+	if (ret)
+		return ret;
+	din[2] &= 0xf0;
+	dout[2] = (DEFAULT_PORT_VID & 0xfff) >> 8 | din[2];
+	dout[3] = DEFAULT_PORT_VID & 0xff;
+	ret = ksz8893m_write(dout, Port1Control3, 4);
+	if (ret)
+		return ret;
+
+	/* Set VLAN VID of port2 */
+	ret = ksz8893m_read(din, Port2Control3, 3);
+	if (ret)
+		return ret;
+	din[2] &= 0xf0;
+	dout[2] = (DEFAULT_PORT_VID & 0xfff) >> 8 | din[2];
+	dout[3] = DEFAULT_PORT_VID & 0xff;
+	ret = ksz8893m_write(dout, Port2Control3, 4);
+	if (ret)
+		return ret;
+
+	/* Set VLAN VID of port3 */
+	ret = ksz8893m_read(din, Port3Control3, 3);
+	if (ret)
+		return ret;
+	din[2] &= 0xf0;
+	dout[2] = (DEFAULT_PORT_VID & 0xfff) >> 8 | din[2];
+	dout[3] = DEFAULT_PORT_VID & 0xff;
+	ret = ksz8893m_write(dout, Port3Control3, 4);
+	if (ret)
+		return ret;
+
+	/* Insert VLAN tag that egress Port3 */
+	ret = ksz8893m_read(din, Port3Control0, 3);
+	if (ret)
+		return ret;
+	dout[2] = TAG_INSERTION | din[2];
+	ret = ksz8893m_write(dout, Port3Control0, 3);
+	if (ret)
+		return ret;
+
+	/* Enable STPID Mode */
+	ret = ksz8893m_read(din, GlobalControl9, 3);
+	if (ret)
+		return ret;
+	dout[2] = SPECIAL_TPID_MODE | din[2];
+	ret = ksz8893m_write(dout, GlobalControl9, 3);
+	if (ret)
+		return ret;
+
+	/* Start switch */
+	dout[2] = START_SWITCH;
+	ret = ksz8893m_write(dout, ChipID1_StartSwitch, 3);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int ksz8893m_setup_port(struct dsa_switch *ds, int p)
+{
+	int val, ret;
+	val = mdiobus_read(ds->master_mii_bus, p, MII_BMCR);
+	if (val < 0)
+		return val;
+	val |= BMCR_ANENABLE | BMCR_SPEED100 | BMCR_FULLDPLX;
+	val &= ~(BMCR_PDOWN | DISABLE_MDIX | DIS_FAR_END_FAULT |
+			DISABLE_TRANSMIT | DISABLE_LED);
+	ret = mdiobus_write(ds->master_mii_bus, p, MII_BMCR, val);
+	if (ret < 0)
+		return ret;
+
+	val = mdiobus_read(ds->master_mii_bus, p, MII_ADVERTISE);
+	if (val < 0)
+		return val;
+	val |= ADVERTISE_10HALF | ADVERTISE_10FULL |
+		ADVERTISE_100HALF | ADVERTISE_100FULL;
+	ret = mdiobus_write(ds->master_mii_bus, p, MII_ADVERTISE, val);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int ksz8893m_setup(struct dsa_switch *ds)
+{
+	int i;
+	int ret;
+
+	ret = ksz8893m_switch_reset(ds);
+	if (ret < 0)
+		return ret;
+
+	ret = ksz8893m_setup_global(ds);
+	if (ret < 0)
+		return ret;
+
+	for (i = 1; i < KSZ8893M_PORT_NUM; i++) {
+		ret = ksz8893m_setup_port(ds, i);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int ksz8893m_set_addr(struct dsa_switch *ds, u8 *addr)
+{
+	return 0;
+}
+
+static int ksz8893m_port_to_phy_addr(int port)
+{
+	if (port >= 1 && port <= KSZ8893M_PORT_NUM)
+		return port;
+	return -1;
+}
+
+static int
+ksz8893m_phy_read(struct dsa_switch *ds, int port, int regnum)
+{
+	int phy_addr = ksz8893m_port_to_phy_addr(port);
+	return mdiobus_read(ds->master_mii_bus, phy_addr, regnum);
+}
+
+static int
+ksz8893m_phy_write(struct dsa_switch *ds,
+			      int port, int regnum, u16 val)
+{
+	int phy_addr = ksz8893m_port_to_phy_addr(port);
+	return mdiobus_write(ds->master_mii_bus, phy_addr, regnum, val);
+}
+
+static void ksz8893m_poll_link(struct dsa_switch *ds)
+{
+	int i;
+
+	for (i = 1; i < KSZ8893M_PORT_NUM; i++) {
+		struct net_device *dev;
+		int val, link;
+
+		dev = ds->ports[i];
+		if (dev == NULL)
+			continue;
+
+		link = 0;
+		if (dev->flags & IFF_UP) {
+			val = mdiobus_read(ds->master_mii_bus, i, MII_BMSR);
+			if (val < 0)
+				continue;
+
+			link = val & BMSR_LSTATUS;
+		}
+
+		if (!link) {
+			if (netif_carrier_ok(dev)) {
+				printk(KERN_INFO "%s: link down\n", dev->name);
+				netif_carrier_off(dev);
+			}
+			continue;
+		}
+
+		val = mdiobus_read(ds->master_mii_bus, i, MII_BMSR);
+		if (val < 0)
+			continue;
+
+		if (!netif_carrier_ok(dev)) {
+			printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex\n",
+					dev->name,
+					(val & LPA_100) ? 100 : 10,
+					(val & LPA_DUPLEX) ? "half" : "full");
+			netif_carrier_on(dev);
+		}
+	}
+}
+
+static int __devinit spi_switch_probe(struct spi_device *spi)
+{
+	if (sw.dev) {
+		pr_err("only one instance supported at a time\n");
+		return 1;
+	}
+	memset(&sw.xfer, 0, sizeof(sw.xfer));
+	sw.dev = spi;
+	return 0;
+}
+
+static int __devexit spi_switch_remove(struct spi_device *spi)
+{
+	sw.dev = NULL;
+	return 0;
+}
+
+static struct spi_driver spi_switch_driver = {
+	.driver = {
+		.name	= "ksz8893m",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe	= spi_switch_probe,
+	.remove	= __devexit_p(spi_switch_remove),
+};
+
+static struct dsa_switch_driver ksz8893m_switch_driver = {
+	.tag_protocol		= __constant_htons(ETH_P_STPID),
+	.probe			= ksz8893m_probe,
+	.setup			= ksz8893m_setup,
+	.set_addr		= ksz8893m_set_addr,
+	.phy_read		= ksz8893m_phy_read,
+	.phy_write		= ksz8893m_phy_write,
+	.poll_link		= ksz8893m_poll_link,
+};
+
+static int __init ksz8893m_init(void)
+{
+	int ret;
+
+	ret = spi_register_driver(&spi_switch_driver);
+	if (ret) {
+		pr_err("can't register driver\n");
+		return ret;
+	}
+
+	register_switch_driver(&ksz8893m_switch_driver);
+	return 0;
+}
+module_init(ksz8893m_init);
+
+static void __exit ksz8893m_cleanup(void)
+{
+	spi_unregister_driver(&spi_switch_driver);
+	unregister_switch_driver(&ksz8893m_switch_driver);
+}
+module_exit(ksz8893m_cleanup);
+
+MODULE_AUTHOR("Graf Yang <graf.yang@analog.com>");
+MODULE_DESCRIPTION("KSZ8893M driver for DSA");
+MODULE_LICENSE("GPL");
diff --git a/net/dsa/ksz8893m.h b/net/dsa/ksz8893m.h
new file mode 100644
index 0000000..30e0df0
--- /dev/null
+++ b/net/dsa/ksz8893m.h
@@ -0,0 +1,163 @@
+/*
+ * Integrated 3-Port 10/100 Managed Switch with PHYs
+ *
+ * - KSZ8893M support
+ *
+ * Copyright 2008-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __KSZ8893M_H__
+#define __KSZ8893M_H__
+
+#define KSZ8893M_PORT_NUM 3
+#define KSZ8893M_CPU_PORT 3
+
+#define DEFAULT_PORT_VID  0
+
+/* Simple SPI command set for poking registers */
+#define SPI_READ          3
+#define SPI_WRITE         2
+
+/* Expected value for MII_PHYSID1 */
+#define PHYID_HIGH        0x22
+/* Expected value for MII_PHYSID2 */
+#define PHYID_LOW         0x1430
+
+/* ChipID0 defines */
+#define FAMILY_ID         0x88
+
+/* ChipID1_StartSwitch defines */
+#define START_SWITCH      0x01
+
+/* Port3Control0 defines */
+#define TAG_INSERTION     0x04
+
+/* GlobalControl9 defines */
+#define SPECIAL_TPID_MODE 0x01
+
+/* BMCR Reserved Bits */
+#define HP_MDIX           0x0020
+#define FORCE_MDI         0x0010
+#define DISABLE_MDIX      0x0008
+#define DIS_FAR_END_FAULT 0x0004
+#define DISABLE_TRANSMIT  0x0002
+#define DISABLE_LED       0x0001
+
+/* BMSCR Reserved Bits */
+#define PREAMBLE_SUPPRESS 0x0040
+
+enum switch_phy_reg {
+	/* Global Registers: 0-15 */
+	ChipID0 = 0,
+	ChipID1_StartSwitch,
+	GlobalControl0,
+	GlobalControl1,
+	GlobalControl2, /* 4 */
+	GlobalControl3,
+	GlobalControl4,
+	GlobalControl5,
+	GlobalControl6, /* 8 */
+	GlobalControl7,
+	GlobalControl8,
+	GlobalControl9,
+	GlobalControl10, /* 12 */
+	GlobalControl11,
+	GlobalControl12,
+	GlobalControl13,
+	/* Port Registers: 16-95 */
+	Port1Control0 = 16,
+	Port1Control1,
+	Port1Control2,
+	Port1Control3,
+	Port1Control4, /* 20 */
+	Port1Control5,
+	Port1Control6,
+	Port1Control7,
+	Port1Control8, /* 24 */
+	Port1Control9,
+	Port1PHYSpecialControl_Status,
+	Port1LinkMDResult,
+	Port1Control12, /* 28 */
+	Port1Control13,
+	Port1Status0,
+	Port1Status1,
+	Port2Control0, /* 32 */
+	Port2Control1,
+	Port2Control2,
+	Port2Control3,
+	Port2Control4, /* 36 */
+	Port2Control5,
+	Port2Control6,
+	Port2Control7,
+	Port2Control8, /* 40 */
+	Port2Control9,
+	Port2PHYSpecialControl_Status,
+	Port2LinkMDResult,
+	Port2Control12, /* 44 */
+	Port2Control13,
+	Port2Status0,
+	Port2Status1,
+	Port3Control0, /* 48 */
+	Port3Control1,
+	Port3Control2,
+	Port3Control3,
+	Port3Control4, /* 52 */
+	Port3Control5,
+	Port3Control6,
+	Port3Control7,
+	Port3Control8, /* 56 */
+	Port3Control9,
+	Reservednotappliedtoport3, /* 58-62 */
+	Port3Status1 = 63,
+	/* Advanced Control Registers: 96-141 */
+	TOSPriorityControlRegister0 = 96,
+	TOSPriorityControlRegister1,
+	TOSPriorityControlRegister2,
+	TOSPriorityControlRegister3,
+	TOSPriorityControlRegister4, /* 100 */
+	TOSPriorityControlRegister5,
+	TOSPriorityControlRegister6,
+	TOSPriorityControlRegister7,
+	TOSPriorityControlRegister8, /* 104 */
+	TOSPriorityControlRegister9,
+	TOSPriorityControlRegister10,
+	TOSPriorityControlRegister11,
+	TOSPriorityControlRegister12, /* 108 */
+	TOSPriorityControlRegister13,
+	TOSPriorityControlRegister14,
+	TOSPriorityControlRegister15,
+	MACAddressRegister0 = 112,
+	MACAddressRegister1,
+	MACAddressRegister2,
+	MACAddressRegister3,
+	MACAddressRegister4,
+	MACAddressRegister5,
+	UserDefinedRegister1 = 118,
+	UserDefinedRegister2,
+	UserDefinedRegister3,
+	IndirectAccessControl0 = 121,
+	IndirectAccessControl1,
+	IndirectDataRegister8 = 123,
+	IndirectDataRegister7,
+	IndirectDataRegister6,
+	IndirectDataRegister5,
+	IndirectDataRegister4,
+	IndirectDataRegister3,
+	IndirectDataRegister2,
+	IndirectDataRegister1,
+	IndirectDataRegister0,
+	DigitalTestingStatus0 = 132,
+	DigitalTestingControl0,
+	AnalogTestingControl0,
+	AnalogTestingControl1,
+	AnalogTestingControl2,
+	AnalogTestingControl3,
+	AnalogTestingStatus,
+	AnalogTestingControl4,
+	QMDebug1,
+	QMDebug2,
+};
+
+#endif
-- 
1.7.1.1


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

* Re: [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support
  2010-07-21 15:33     ` Eric Dumazet
  2010-07-21 15:36       ` Lennert Buytenhek
@ 2010-07-21 16:40       ` Joe Perches
  1 sibling, 0 replies; 21+ messages in thread
From: Joe Perches @ 2010-07-21 16:40 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Lennert Buytenhek, Mike Frysinger, netdev, David S. Miller,
	uclinux-dist-devel, Karl Beldan, Graf Yang, Bryan Wu

On Wed, 2010-07-21 at 17:33 +0200, Eric Dumazet wrote:
> It is used by all pr_err() friends

Shouldn't these drivers be moved into
something like drivers/net/dsa/ rather
than be kept in net?

The #define pr_fmt would be more standard as
	#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
The printks could be netdev_<level>

Suggested patches:

diff --git a/net/dsa/ksz8893m.c b/net/dsa/ksz8893m.c
index 98cce04..80fb0ac 100644
--- a/net/dsa/ksz8893m.c
+++ b/net/dsa/ksz8893m.c
@@ -8,7 +8,7 @@
  * Licensed under the GPL-2 or later.
  */
 
-#define pr_fmt(fmt) "ksz8893m: " fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/list.h>
 #include <linux/netdevice.h>
@@ -42,11 +42,14 @@ static int ksz8893m_read(unsigned char *din, unsigned char reg, int len)
 	spi_message_init(&message);
 	spi_message_add_tail(t, &message);
 	ret = spi_sync(sw.dev, &message);
-	if (!ret)
-		return message.status;
+	if (ret) {
+		pr_err("read reg%d failed, ret=%d\n", reg, ret);
+		return ret;
+	}
+	if (message.status)
+		pr_err("read reg%d failed, status=%d\n", reg, message.status);
 
-	pr_err("read reg%d failed, ret=%d\n", reg, ret);
-	return ret;
+	return message.status;
 }
 
 static int ksz8893m_write(unsigned char *dout, unsigned char reg, int len)
@@ -65,11 +68,14 @@ static int ksz8893m_write(unsigned char *dout, unsigned char reg, int len)
 	spi_message_init(&message);
 	spi_message_add_tail(t, &message);
 	ret = spi_sync(sw.dev, &message);
-	if (!ret)
-		return message.status;
+	if (ret) {
+		pr_err("write reg%d failed, ret=%d\n", reg, ret);
+		return ret;
+	}
+	if (message.status)
+		pr_err("write reg%d failed, status=%d\n", reg, message.status);
 
-	pr_err("write reg%d failed, ret=%d\n", reg, ret);
-	return ret;
+	return message.status;
 }
 
 static char *ksz8893m_probe(struct mii_bus *bus, int sw_addr)
@@ -168,8 +174,8 @@ static int ksz8893m_setup_port(struct dsa_switch *ds, int p)
 	if (val < 0)
 		return val;
 	val |= AN_ENABLE | FORCE_100 | FORCE_FULL_DUPLEX;
-	val &= ~(POWER_DOWN | DISABLE_MDIX | DIS_FAR_END_FAULT |\
-			DISABLE_TRANSMIT | DISABLE_LED);
+	val &= ~(POWER_DOWN | DISABLE_MDIX | DIS_FAR_END_FAULT |
+		 DISABLE_TRANSMIT | DISABLE_LED);
 	ret = mdiobus_write(ds->master_mii_bus, p, MII_BMCR, val);
 	if (ret < 0)
 		return ret;
@@ -228,8 +234,7 @@ ksz8893m_phy_read(struct dsa_switch *ds, int port, int regnum)
 }
 
 static int
-ksz8893m_phy_write(struct dsa_switch *ds,
-			      int port, int regnum, u16 val)
+ksz8893m_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
 {
 	int phy_addr = ksz8893m_port_to_phy_addr(port);
 	return mdiobus_write(ds->master_mii_bus, phy_addr, regnum, val);
@@ -263,7 +268,7 @@ static void ksz8893m_poll_link(struct dsa_switch *ds)
 
 		if (!link) {
 			if (netif_carrier_ok(dev)) {
-				printk(KERN_INFO "%s: link down\n", dev->name);
+				netdev_info(dev, "link down\n");
 				netif_carrier_off(dev);
 			}
 			continue;
@@ -274,8 +279,8 @@ static void ksz8893m_poll_link(struct dsa_switch *ds)
 		val = mdiobus_read(ds->master_mii_bus, i, MII_BMSR);
 		if (val < 0)
 			continue;
-		val &= HALF_10_CAPABLE | FULL_10_CAPABLE |\
-		       HALF_100_CAPABLE | FULL_100_CAPABLE;
+		val &= (HALF_10_CAPABLE | FULL_10_CAPABLE |
+			HALF_100_CAPABLE | FULL_100_CAPABLE);
 		if (val & FULL_100_CAPABLE) {
 			speed = 100;
 			duplex = 1;
@@ -288,8 +293,8 @@ static void ksz8893m_poll_link(struct dsa_switch *ds)
 		}
 
 		if (!netif_carrier_ok(dev)) {
-			printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex\n",
-					dev->name, speed, duplex ? "full" : "half");
+			netdev_info(dev, "link up, %d Mb/s, %s duplex\n",
+				    speed, duplex ? "full" : "half");
 			netif_carrier_on(dev);
 		}
 	}




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

* Re: [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support
       [not found]     ` <20100721151608.GM21121-SHk0+jKqY/D5VnbZ9m/NDkB+6BGkLq7r@public.gmane.org>
@ 2010-07-21 17:23       ` David Miller
  0 siblings, 0 replies; 21+ messages in thread
From: David Miller @ 2010-07-21 17:23 UTC (permalink / raw)
  To: buytenh-OLH4Qvv75CYX/NnBR394Jw
  Cc: karl.beldan-Re5JQEeQqe8AvxtiuMwx3w, vapier-aBrp7R+bbdUdnm+yROfE0A,
	netdev-u79uwXL29TY76Z2rM5mHXA, graf.yang-OyLXuOCK7orQT0dZR+AlfA,
	uclinux-dist-devel-ZG0+EudsQA8dtHy/vicBwGD2FQJk+8+b

From: Lennert Buytenhek <buytenh-OLH4Qvv75CYX/NnBR394Jw@public.gmane.org>
Date: Wed, 21 Jul 2010 17:16:08 +0200

> On Wed, Jul 21, 2010 at 09:37:22AM -0400, Mike Frysinger wrote:
> 
>> +#define pr_fmt(fmt) "ksz8893m: " fmt
> 
> This has no users.

egrep pr_fmt include/linux/kernel.h

It feeds into all of the various kernel logging interfaces.

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

* Re: [Uclinux-dist-devel] [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support
  2010-07-21 16:05     ` [Uclinux-dist-devel] " Mike Frysinger
@ 2010-07-21 20:31       ` Karl Beldan
  2010-07-21 21:00         ` Mike Frysinger
  0 siblings, 1 reply; 21+ messages in thread
From: Karl Beldan @ 2010-07-21 20:31 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: Lennert Buytenhek, netdev, uclinux-dist-devel, David S. Miller

On Wed, Jul 21, 2010 at 6:05 PM, Mike Frysinger <vapier.adi@gmail.com> wrote:
> On Wed, Jul 21, 2010 at 11:16, Lennert Buytenhek wrote:
>> On Wed, Jul 21, 2010 at 09:37:22AM -0400, Mike Frysinger wrote:
>>> +static int ksz8893m_setup(struct dsa_switch *ds)
>>> +{
>>> +     int i;
>>> +     int ret;
>>> +
>>> +     ret = ksz8893m_switch_reset(ds);
>>> +     if (ret < 0)
>>> +             return ret;
>>
>> It's pretty ugly that the mdiobus is passed in via the normal means,
>> but a reference to the SPI bus to use is just stuffed into some global
>> variable.
>>
>> Can you not access all registers via MII?
>
> it depends on the host mdio bus.  if it supports the semi-standard
> behavior of toggling the OP field of MDIO frames, then yes, you can do
> it via MII.  but i dont think the current mdio framework in the kernel
> keeps track of that functionality, so there isnt a way in the driver
> to say "is this possible, else fall back to SPI".
>
Are you referring to SMI ?

> certainly the part that was used to develop this driver does not
> support this behavior thus SPI is the only way of accessing the
> extended registers.  i guess the driver could be extended so that
> people could pick which mode they want to program the registers via
> platform resources, but we have no way of testing that, so i say let
> the person who actually can use & wants that functionality implement
> it.
>
>> (If not, struct dsa_chip_data will need go be extended with another
>> struct device pointer that we can use to find the spi bus with.)
>
> if the framework supports, i can convert the driver to it, but i'm not
> sure we have the time atm to tackle reworking common frameworks.
>
If someone tackles this, it would be nice that they bear in mind that
phylib's drivers also need spi/smi/i2c register access.

>>> +static int ksz8893m_port_to_phy_addr(int port)
>>> +{
>>> +     if (port >= 1 && port <= KSZ8893M_PORT_NUM)
>>> +             return port;
>>> +
>>> +     pr_warning("use default phy addr 3\n");
>>> +     return 3;
>>
>> Does this ever happen?  You should just be able to return -1 here, IMHO.
>
> i dont recall seeing a warning, but presumably if it it did occur,
> something else needs fixing.  so -1 is OK.
>
I would remove this.

-- 
Karl

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

* Re: [PATCH 2/2 v2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support
  2010-07-21 16:29   ` [PATCH 2/2 v2] " Mike Frysinger
@ 2010-07-21 20:45     ` Karl Beldan
  0 siblings, 0 replies; 21+ messages in thread
From: Karl Beldan @ 2010-07-21 20:45 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: netdev, David S. Miller, uclinux-dist-devel, Lennert Buytenhek,
	Graf Yang, Bryan Wu

On 7/21/10, Mike Frysinger <vapier@gentoo.org> wrote:
[...]
>  net/dsa/Kconfig    |    7 +
>  net/dsa/Makefile   |    1 +
>  net/dsa/ksz8893m.c |  341
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  net/dsa/ksz8893m.h |  163 +++++++++++++++++++++++++
>  4 files changed, 512 insertions(+), 0 deletions(-)
>  create mode 100644 net/dsa/ksz8893m.c
>  create mode 100644 net/dsa/ksz8893m.h
>
[...]
> +/* Port3Control0 defines */
> +#define TAG_INSERTION     0x04
> +
> +/* GlobalControl9 defines */
> +#define SPECIAL_TPID_MODE 0x01
> +

How about prefixes like 'PC0_' (PortControl0)  ?

-- 
Karl

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

* Re: [Uclinux-dist-devel] [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support
  2010-07-21 20:31       ` Karl Beldan
@ 2010-07-21 21:00         ` Mike Frysinger
  2010-07-22 19:27           ` Karl Beldan
  0 siblings, 1 reply; 21+ messages in thread
From: Mike Frysinger @ 2010-07-21 21:00 UTC (permalink / raw)
  To: Karl Beldan
  Cc: Lennert Buytenhek, netdev, uclinux-dist-devel, David S. Miller

On Wed, Jul 21, 2010 at 16:31, Karl Beldan wrote:
> On Wed, Jul 21, 2010 at 6:05 PM, Mike Frysinger wrote:
>> On Wed, Jul 21, 2010 at 11:16, Lennert Buytenhek wrote:
>>> On Wed, Jul 21, 2010 at 09:37:22AM -0400, Mike Frysinger wrote:
>>>> +static int ksz8893m_setup(struct dsa_switch *ds)
>>>> +{
>>>> +     int i;
>>>> +     int ret;
>>>> +
>>>> +     ret = ksz8893m_switch_reset(ds);
>>>> +     if (ret < 0)
>>>> +             return ret;
>>>
>>> It's pretty ugly that the mdiobus is passed in via the normal means,
>>> but a reference to the SPI bus to use is just stuffed into some global
>>> variable.
>>>
>>> Can you not access all registers via MII?
>>
>> it depends on the host mdio bus.  if it supports the semi-standard
>> behavior of toggling the OP field of MDIO frames, then yes, you can do
>> it via MII.  but i dont think the current mdio framework in the kernel
>> keeps track of that functionality, so there isnt a way in the driver
>> to say "is this possible, else fall back to SPI".
>
> Are you referring to SMI ?

that is the term the ksz datasheet uses (Serial Management Interface),
but i'm not aware of it being a standardized term.  even the ksz
datasheet admits that its behavior is a bit non-standard.  the
Blackfin MAC doesnt support it so we have no way of testing the it as
that is the MAC on the board with the ksz switch.
-mike

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

* Re: [Uclinux-dist-devel] [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support
  2010-07-21 21:00         ` Mike Frysinger
@ 2010-07-22 19:27           ` Karl Beldan
  0 siblings, 0 replies; 21+ messages in thread
From: Karl Beldan @ 2010-07-22 19:27 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: Lennert Buytenhek, netdev, uclinux-dist-devel, David S. Miller

On Wed, Jul 21, 2010 at 11:00 PM, Mike Frysinger <vapier.adi@gmail.com> wrote:
> On Wed, Jul 21, 2010 at 16:31, Karl Beldan wrote:
>> On Wed, Jul 21, 2010 at 6:05 PM, Mike Frysinger wrote:
>>> On Wed, Jul 21, 2010 at 11:16, Lennert Buytenhek wrote:
>>>> On Wed, Jul 21, 2010 at 09:37:22AM -0400, Mike Frysinger wrote:
>>>>> +static int ksz8893m_setup(struct dsa_switch *ds)
>>>>> +{
>>>>> +     int i;
>>>>> +     int ret;
>>>>> +
>>>>> +     ret = ksz8893m_switch_reset(ds);
>>>>> +     if (ret < 0)
>>>>> +             return ret;
>>>>
>>>> It's pretty ugly that the mdiobus is passed in via the normal means,
>>>> but a reference to the SPI bus to use is just stuffed into some global
>>>> variable.
>>>>
>>>> Can you not access all registers via MII?
>>>
>>> it depends on the host mdio bus.  if it supports the semi-standard
>>> behavior of toggling the OP field of MDIO frames, then yes, you can do
>>> it via MII.  but i dont think the current mdio framework in the kernel
>>> keeps track of that functionality, so there isnt a way in the driver
>>> to say "is this possible, else fall back to SPI".
>>
>> Are you referring to SMI ?
>
> that is the term the ksz datasheet uses (Serial Management Interface),
> but i'm not aware of it being a standardized term.  even the ksz
> datasheet admits that its behavior is a bit non-standard.  the
> Blackfin MAC doesnt support it so we have no way of testing the it as
> that is the MAC on the board with the ksz switch.
>
Can't either, we don't even have mdio, only spi.
Speaking of which, maybe you can replace this while you are at it :

--- net/dsa/slave.c	2010-05-22 09:58:34.000000000 +0200
 void dsa_slave_mii_bus_init(struct dsa_switch *ds)
 {
 	ds->slave_mii_bus->priv = (void *)ds;
-	ds->slave_mii_bus->name = "dsa slave smi";



-- 
Karl

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

* Re: [Uclinux-dist-devel] [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code
  2010-07-21 16:08       ` Mike Frysinger
@ 2010-07-29 17:50         ` Mike Frysinger
  2010-08-10 14:05           ` Lennert Buytenhek
  0 siblings, 1 reply; 21+ messages in thread
From: Mike Frysinger @ 2010-07-29 17:50 UTC (permalink / raw)
  To: Lennert Buytenhek
  Cc: Karl Beldan, netdev, uclinux-dist-devel, David S. Miller

On Wed, Jul 21, 2010 at 12:08, Mike Frysinger wrote:
> On Wed, Jul 21, 2010 at 11:35, Lennert Buytenhek wrote:
>> On Wed, Jul 21, 2010 at 11:29:30AM -0400, Mike Frysinger wrote:
>>> >> +     source_port = dsa_header[1] & 0x03;
>>> >> +     if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
>>> >> +             goto out_drop;
>>> >> +
>>> >> +     if (((dsa_header[0] & ETH_P_8021QH) == ETH_P_8021QH) &&
>>> >
>>> > This is bogus -- what it does is:
>>> >
>>> >        if ((dsa_header[0] & 0x81) == 0x81)
>>> >
>>> > It doesn't look like you need to mask here at all.
>>>
>>> where does it say dsa_header[0] will always have 0x81 set ?
>>
>> Eh?
>>
>> This code is checking whether the packet has a STPID tag on it or not.
>> A STPID tag exists if the first 12 nibbles are 0x810.
>>
>> You are checking whether the first 8 nibbles of this are equal to 0x81
>> by doing:
>>
>>        if ((byte & 0x81) == 0x81)
>>
>> What if the first byte is 0x93?  Or 0xc5?
>
> that was my point.  should it be masking or doing a raw compare ?

and the answer is ... ?  so i can send an updated patch ;)
-mike

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

* Re: [Uclinux-dist-devel] [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code
  2010-07-29 17:50         ` Mike Frysinger
@ 2010-08-10 14:05           ` Lennert Buytenhek
  2010-08-10 17:04             ` Mike Frysinger
  0 siblings, 1 reply; 21+ messages in thread
From: Lennert Buytenhek @ 2010-08-10 14:05 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: Karl Beldan, netdev, uclinux-dist-devel

On Thu, Jul 29, 2010 at 01:50:45PM -0400, Mike Frysinger wrote:

> >>> >> +     source_port = dsa_header[1] & 0x03;
> >>> >> +     if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
> >>> >> +             goto out_drop;
> >>> >> +
> >>> >> +     if (((dsa_header[0] & ETH_P_8021QH) == ETH_P_8021QH) &&
> >>> >
> >>> > This is bogus -- what it does is:
> >>> >
> >>> >        if ((dsa_header[0] & 0x81) == 0x81)
> >>> >
> >>> > It doesn't look like you need to mask here at all.
> >>>
> >>> where does it say dsa_header[0] will always have 0x81 set ?
> >>
> >> Eh?
> >>
> >> This code is checking whether the packet has a STPID tag on it or not.
> >> A STPID tag exists if the first 12 nibbles are 0x810.
> >>
> >> You are checking whether the first 8 nibbles of this are equal to 0x81
> >> by doing:
> >>
> >>        if ((byte & 0x81) == 0x81)
> >>
> >> What if the first byte is 0x93?  Or 0xc5?
> >
> > that was my point.  should it be masking or doing a raw compare ?
> 
> and the answer is ... ?  so i can send an updated patch ;)

From what I understand, you should just be checking for equality with
0x81 in the first byte, as that is what indicates presence of the STPID
tag.

Is the hardware you're doing this on available somewhere for me to
try things out on?

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

* Re: [Uclinux-dist-devel] [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code
  2010-08-10 14:05           ` Lennert Buytenhek
@ 2010-08-10 17:04             ` Mike Frysinger
  2010-08-12 22:38               ` Mike Frysinger
  0 siblings, 1 reply; 21+ messages in thread
From: Mike Frysinger @ 2010-08-10 17:04 UTC (permalink / raw)
  To: Lennert Buytenhek; +Cc: Karl Beldan, netdev, uclinux-dist-devel

On Tue, Aug 10, 2010 at 10:05, Lennert Buytenhek wrote:
> Is the hardware you're doing this on available somewhere for me to
> try things out on?

yes & no.  the board in question is here (that picture has two ethernet ports):
http://www.analog.com/en/embedded-processing-dsp/blackfin/BF518-EZBRD/processors/product.html

but that was the first few revs of the board ... later ones have
dropped the switch because it didnt support PTP packets.  i dont think
you can specify "give me an older rev" when ordering from ADI.

if you're interested, i can probably find you an older one laying
around if you're interested in testing things.
-mike

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

* Re: [Uclinux-dist-devel] [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code
  2010-08-10 17:04             ` Mike Frysinger
@ 2010-08-12 22:38               ` Mike Frysinger
  0 siblings, 0 replies; 21+ messages in thread
From: Mike Frysinger @ 2010-08-12 22:38 UTC (permalink / raw)
  To: Lennert Buytenhek; +Cc: Karl Beldan, netdev, uclinux-dist-devel

On Tue, Aug 10, 2010 at 13:04, Mike Frysinger wrote:
> On Tue, Aug 10, 2010 at 10:05, Lennert Buytenhek wrote:
>> Is the hardware you're doing this on available somewhere for me to
>> try things out on?
>
> if you're interested, i can probably find you an older one laying
> around if you're interested in testing things.

hrm, too many "interested" in that sentence ...

at any rate, i'm implying you'd get the board for free if that makes a
difference to you
-mike

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

end of thread, other threads:[~2010-08-12 22:39 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-21 13:37 [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code Mike Frysinger
2010-07-21 13:37 ` [PATCH 2/2] net: dsa: introduce MICREL KSZ8893MQL/BL ethernet switch chip support Mike Frysinger
2010-07-21 15:16   ` Lennert Buytenhek
2010-07-21 15:33     ` Eric Dumazet
2010-07-21 15:36       ` Lennert Buytenhek
2010-07-21 16:40       ` Joe Perches
2010-07-21 16:05     ` [Uclinux-dist-devel] " Mike Frysinger
2010-07-21 20:31       ` Karl Beldan
2010-07-21 21:00         ` Mike Frysinger
2010-07-22 19:27           ` Karl Beldan
     [not found]     ` <20100721151608.GM21121-SHk0+jKqY/D5VnbZ9m/NDkB+6BGkLq7r@public.gmane.org>
2010-07-21 17:23       ` David Miller
2010-07-21 16:29   ` [PATCH 2/2 v2] " Mike Frysinger
2010-07-21 20:45     ` Karl Beldan
2010-07-21 15:02 ` [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code Lennert Buytenhek
2010-07-21 15:29   ` [Uclinux-dist-devel] " Mike Frysinger
2010-07-21 15:35     ` Lennert Buytenhek
2010-07-21 16:08       ` Mike Frysinger
2010-07-29 17:50         ` Mike Frysinger
2010-08-10 14:05           ` Lennert Buytenhek
2010-08-10 17:04             ` Mike Frysinger
2010-08-12 22:38               ` Mike Frysinger

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).