All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch 1/9] eeprom_93cx6: Add data direction control.
       [not found] <20091207121501.819539008@fluff.org.uk>
@ 2009-12-07 12:15 ` ben
  2009-12-07 12:34   ` Ben Dooks
  2009-12-07 12:15 ` [patch 2/9] eeprom_93cx6: Add write support ben
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 12+ messages in thread
From: ben @ 2009-12-07 12:15 UTC (permalink / raw)
  To: netdev
  Cc: linux, doong.ping, tristram.ha, Wolfram Sang, Jean Delvare,
	Linux Kernel

[-- Attachment #1: 93c-eeprom-add-direction.patch --]
[-- Type: text/plain, Size: 2337 bytes --]

Some devices need to know if the data is to be output or read, so add a
data direction into the eeprom structure to tell the driver whether the
data line should be driven.

The user in this case is the Micrel KS8851 which has a direction
control for the EEPROM data line and thus needs to know whether
to drive it (writing) or to tristate it for receiving.

Signed-off-by: Ben Dooks <ben@simtec.co.uk>
Cc: Wolfram Sang <w.sang@pengutronix.de>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Linux Kernel <linux-kernel@vger.kernel.org>

--
 drivers/misc/eeprom/eeprom_93cx6.c |    3 +++
 include/linux/eeprom_93cx6.h       |    2 ++
 2 files changed, 5 insertions(+)

Index: b/drivers/misc/eeprom/eeprom_93cx6.c
===================================================================
--- a/drivers/misc/eeprom/eeprom_93cx6.c	2009-10-06 15:35:38.000000000 +0100
+++ b/drivers/misc/eeprom/eeprom_93cx6.c	2009-10-06 15:51:18.000000000 +0100
@@ -70,6 +70,7 @@ static void eeprom_93cx6_startup(struct 
 	eeprom->reg_data_out = 0;
 	eeprom->reg_data_clock = 0;
 	eeprom->reg_chip_select = 1;
+	eeprom->drive_data = 1;
 	eeprom->register_write(eeprom);
 
 	/*
@@ -108,6 +109,7 @@ static void eeprom_93cx6_write_bits(stru
 	 */
 	eeprom->reg_data_in = 0;
 	eeprom->reg_data_out = 0;
+	eeprom->drive_data = 1;
 
 	/*
 	 * Start writing all bits.
@@ -147,6 +149,7 @@ static void eeprom_93cx6_read_bits(struc
 	 */
 	eeprom->reg_data_in = 0;
 	eeprom->reg_data_out = 0;
+	eeprom->drive_data = 0;
 
 	/*
 	 * Start reading all bits.
Index: b/include/linux/eeprom_93cx6.h
===================================================================
--- a/include/linux/eeprom_93cx6.h	2009-10-06 15:35:38.000000000 +0100
+++ b/include/linux/eeprom_93cx6.h	2009-10-06 15:51:18.000000000 +0100
@@ -45,6 +45,7 @@
  * @register_write(struct eeprom_93cx6 *eeprom): handler to
  * write to the eeprom register by using all reg_* fields.
  * @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines
+ * @drive_data: Set if we're driving the data line.
  * @reg_data_in: register field to indicate data input
  * @reg_data_out: register field to indicate data output
  * @reg_data_clock: register field to set the data clock
@@ -61,6 +62,7 @@ struct eeprom_93cx6 {
 
 	int width;
 
+	char drive_data;
 	char reg_data_in;
 	char reg_data_out;
 	char reg_data_clock;


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

* [patch 2/9] eeprom_93cx6: Add write support
       [not found] <20091207121501.819539008@fluff.org.uk>
  2009-12-07 12:15 ` [patch 1/9] eeprom_93cx6: Add data direction control ben
@ 2009-12-07 12:15 ` ben
  2009-12-07 12:15 ` [patch 3/9] KS8851: Add support for EEPROM MAC address ben
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: ben @ 2009-12-07 12:15 UTC (permalink / raw)
  To: netdev
  Cc: linux, doong.ping, tristram.ha, Wolfram Sang, Jean Delvare,
	Linux Kernel

[-- Attachment #1: 93c-eeprom-add-write.patch --]
[-- Type: text/plain, Size: 3857 bytes --]

Add support for writing data to EEPROM.

Signed-off-by: Ben Dooks <ben@simtec.co.uk>
Cc: Wolfram Sang <w.sang@pengutronix.de>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Linux Kernel <linux-kernel@vger.kernel.org>

---
 drivers/misc/eeprom/eeprom_93cx6.c |   86 +++++++++++++++++++++++++++++++++++++
 include/linux/eeprom_93cx6.h       |    7 +++
 2 files changed, 93 insertions(+)

Index: b/drivers/misc/eeprom/eeprom_93cx6.c
===================================================================
--- a/drivers/misc/eeprom/eeprom_93cx6.c	2009-10-06 15:51:18.000000000 +0100
+++ b/drivers/misc/eeprom/eeprom_93cx6.c	2009-10-06 15:54:36.000000000 +0100
@@ -241,3 +241,89 @@ void eeprom_93cx6_multiread(struct eepro
 }
 EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);
 
+
+/**
+ * eeprom_93cx6_wren - set the write enable state
+ * @eeprom: Pointer to eeprom structure
+ * @enable: true to enable writes, otherwise disable writes
+ *
+ * Set the EEPROM write enable state to either allow or deny
+ * writes depending on the @enable value.
+ */
+void eeprom_93cx6_wren(struct eeprom_93cx6 *eeprom, bool enable)
+{
+	u16 command;
+
+	/* start the command */
+	eeprom_93cx6_startup(eeprom);
+
+	/* create command to enable/disable */
+
+	command = enable ? PCI_EEPROM_EWEN_OPCODE : PCI_EEPROM_EWDS_OPCODE;
+	command <<= (eeprom->width - 2);
+
+	eeprom_93cx6_write_bits(eeprom, command,
+				PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
+
+	eeprom_93cx6_cleanup(eeprom);
+}
+EXPORT_SYMBOL_GPL(eeprom_93cx6_wren);
+
+/**
+ * eeprom_93cx6_write - write data to the EEPROM
+ * @eeprom: Pointer to eeprom structure
+ * @addr: Address to write data to.
+ * @data: The data to write to address @addr.
+ *
+ * Write the @data to the specified @addr in the EEPROM and
+ * waiting for the device to finish writing.
+ *
+ * Note, since we do not expect large number of write operations
+ * we use msleep() to delay in between parts of the operation to
+ * avoid using excessive amounts of CPU time busy waiting.
+ */
+void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom, u8 addr, u16 data)
+{
+	int timeout = 100;
+	u16 command;
+
+	/* start the command */
+	eeprom_93cx6_startup(eeprom);
+
+	command = PCI_EEPROM_WRITE_OPCODE << eeprom->width;
+	command |= addr;
+
+	/* send write command */
+	eeprom_93cx6_write_bits(eeprom, command,
+				PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
+
+	/* send data */
+	eeprom_93cx6_write_bits(eeprom, data, 16);
+
+	/* get ready to check for busy */
+	eeprom->drive_data = 0;
+	eeprom->reg_chip_select = 1;
+	eeprom->register_write(eeprom);
+
+	/* wait at-least 250ns to get DO to be the busy signal */
+	msleep(1);
+
+	/* wait for DO to go high to signify finish */
+
+	while (true) {
+		eeprom->register_read(eeprom);
+
+		if (eeprom->reg_data_out)
+			break;
+
+		msleep(1);
+
+		if (--timeout <= 0) {
+			printk(KERN_ERR "%s: timeout\n", __func__);
+			break;
+		}			
+	}
+
+	eeprom_93cx6_cleanup(eeprom);
+}
+EXPORT_SYMBOL_GPL(eeprom_93cx6_write);
Index: b/include/linux/eeprom_93cx6.h
===================================================================
--- a/include/linux/eeprom_93cx6.h	2009-10-06 15:51:18.000000000 +0100
+++ b/include/linux/eeprom_93cx6.h	2009-10-06 15:53:16.000000000 +0100
@@ -32,6 +32,7 @@
 #define PCI_EEPROM_WIDTH_93C66	8
 #define PCI_EEPROM_WIDTH_OPCODE	3
 #define PCI_EEPROM_WRITE_OPCODE	0x05
+#define PCI_EEPROM_ERASE_OPCODE 0x07
 #define PCI_EEPROM_READ_OPCODE	0x06
 #define PCI_EEPROM_EWDS_OPCODE	0x10
 #define PCI_EEPROM_EWEN_OPCODE	0x13
@@ -73,3 +74,9 @@ extern void eeprom_93cx6_read(struct eep
 	const u8 word, u16 *data);
 extern void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom,
 	const u8 word, __le16 *data, const u16 words);
+
+extern void eeprom_93cx6_wren(struct eeprom_93cx6 *eeprom, bool enable);
+
+extern void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom,
+			       u8 addr, u16 data);
+


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

* [patch 3/9] KS8851: Add support for EEPROM MAC address
       [not found] <20091207121501.819539008@fluff.org.uk>
  2009-12-07 12:15 ` [patch 1/9] eeprom_93cx6: Add data direction control ben
  2009-12-07 12:15 ` [patch 2/9] eeprom_93cx6: Add write support ben
@ 2009-12-07 12:15 ` ben
  2009-12-09  4:45   ` David Miller
  2009-12-07 12:15 ` [patch 4/9] KS8851: Add ethtool support for EEPROM ben
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 12+ messages in thread
From: ben @ 2009-12-07 12:15 UTC (permalink / raw)
  To: netdev; +Cc: linux, doong.ping, tristram.ha

[-- Attachment #1: ks8851-mac-from-eeprom.patch --]
[-- Type: text/plain, Size: 3404 bytes --]

Add support for reading the MAC address from the system registers if there
is an EEPROM present. This involves caching the KS_CCR register for later
use (will also be useful for ETHTOOL support) and adding a print to say
that there is an EEPROM present.

Signed-off-by: Ben Dooks <ben@simtec.co.uk>

---

---
 drivers/net/ks8851.c |   46 +++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 39 insertions(+), 7 deletions(-)

Index: b/drivers/net/ks8851.c
===================================================================
--- a/drivers/net/ks8851.c	2009-12-07 10:59:14.000000000 +0000
+++ b/drivers/net/ks8851.c	2009-12-07 10:59:24.000000000 +0000
@@ -76,6 +76,7 @@ union ks8851_tx_hdr {
  * @msg_enable: The message flags controlling driver output (see ethtool).
  * @fid: Incrementing frame id tag.
  * @rc_ier: Cached copy of KS_IER.
+ * @rc_ccr: Cached copy of KS_CCR.
  * @rc_rxqcr: Cached copy of KS_RXQCR.
  *
  * The @lock ensures that the chip is protected when certain operations are
@@ -107,6 +108,7 @@ struct ks8851_net {
 
 	u16			rc_ier;
 	u16			rc_rxqcr;
+	u16			rc_ccr;
 
 	struct mii_if_info	mii;
 	struct ks8851_rxctrl	rxctrl;
@@ -367,21 +369,47 @@ static int ks8851_write_mac_addr(struct 
 }
 
 /**
+ * ks8851_read_mac_addr - read mac address from device registers
+ * @dev: The network device
+ *
+ * Update our copy of the KS8851 MAC address from the registers of @dev.
+*/
+static void ks8851_read_mac_addr(struct net_device *dev)
+{
+	struct ks8851_net *ks = netdev_priv(dev);
+	int i;
+
+	mutex_lock(&ks->lock);
+
+	for (i = 0; i < ETH_ALEN; i++)
+		dev->dev_addr[i] = ks8851_rdreg8(ks, KS_MAR(i));
+
+	mutex_unlock(&ks->lock);
+}
+
+/**
  * ks8851_init_mac - initialise the mac address
  * @ks: The device structure
  *
  * Get or create the initial mac address for the device and then set that
- * into the station address register. Currently we assume that the device
- * does not have a valid mac address in it, and so we use random_ether_addr()
+ * into the station address register. If there is an EEPROM present, then
+ * we try that. If no valid mac address is found we use random_ether_addr()
  * to create a new one.
- *
- * In future, the driver should check to see if the device has an EEPROM
- * attached and whether that has a valid ethernet address in it.
  */
 static void ks8851_init_mac(struct ks8851_net *ks)
 {
 	struct net_device *dev = ks->netdev;
 
+	/* first, try reading what we've got already */
+	if (ks->rc_ccr & CCR_EEPROM) {
+		ks8851_read_mac_addr(dev);
+		if (is_valid_ether_addr(dev->dev_addr))
+			return;
+
+		ks_err(ks, "invalid mac address read %pM\n",
+			dev->dev_addr);
+	}
+
 	random_ether_addr(dev->dev_addr);
 	ks8851_write_mac_addr(dev);
 }
@@ -1280,6 +1308,9 @@ static int __devinit ks8851_probe(struct
 		goto err_id;
 	}
 
+  	/* cache the contents of the CCR register for EEPROM, etc. */
+  	ks->rc_ccr = ks8851_rdreg16(ks, KS_CCR);
+
 	ks8851_read_selftest(ks);
 	ks8851_init_mac(ks);
 	ks->tx_space = ks8851_rdreg16(ks, KS_TXMIR);
@@ -1297,9 +1328,10 @@ static int __devinit ks8851_probe(struct
 		goto err_netdev;
 	}
 
-	dev_info(&spi->dev, "revision %d, MAC %pM, IRQ %d\n",
+	dev_info(&spi->dev, "revision %d, MAC %pM, IRQ %d, %s EEPROM\n",
 		 CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)),
-		 ndev->dev_addr, ndev->irq);
+		 ndev->dev_addr, ndev->irq,
+		 ks->rc_ccr & CCR_EEPROM ? "has" : "no");
 
 	return 0;
 


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

* [patch 4/9] KS8851: Add ethtool support for EEPROM
       [not found] <20091207121501.819539008@fluff.org.uk>
                   ` (2 preceding siblings ...)
  2009-12-07 12:15 ` [patch 3/9] KS8851: Add support for EEPROM MAC address ben
@ 2009-12-07 12:15 ` ben
  2009-12-07 12:15 ` [patch 5/9] KS8851: Add debugfs export for driver state ben
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: ben @ 2009-12-07 12:15 UTC (permalink / raw)
  To: netdev; +Cc: linux, doong.ping, tristram.ha

[-- Attachment #1: ks8851-add-eeprom-ethtool.patch --]
[-- Type: text/plain, Size: 6382 bytes --]

Add ethtool EEPROM read/write support for the KS8851 driver.

Depends on eeprom_93cx6 driver getting EEPROM write support.

Signed-off-by: Ben Dooks <ben@simtec.co.uk>
Signed-off-by: Simtec Linux Team <linux@simtec.co.uk>

---
 drivers/net/Kconfig  |    1 
 drivers/net/ks8851.c |  149 +++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/ks8851.h |    1 
 3 files changed, 151 insertions(+)

Index: b/drivers/net/ks8851.c
===================================================================
--- a/drivers/net/ks8851.c	2009-12-07 10:59:24.000000000 +0000
+++ b/drivers/net/ks8851.c	2009-12-07 11:01:34.000000000 +0000
@@ -19,6 +19,7 @@
 #include <linux/cache.h>
 #include <linux/crc32.h>
 #include <linux/mii.h>
+#include <linux/eeprom_93cx6.h>
 
 #include <linux/spi/spi.h>
 
@@ -78,6 +79,7 @@ union ks8851_tx_hdr {
  * @rc_ier: Cached copy of KS_IER.
  * @rc_ccr: Cached copy of KS_CCR.
  * @rc_rxqcr: Cached copy of KS_RXQCR.
+ * @eeprom: 93CX6 EEPROM state for accessing on-board EEPROM.
  *
  * The @lock ensures that the chip is protected when certain operations are
  * in progress. When the read or write packet transfer is in progress, most
@@ -125,6 +127,8 @@ struct ks8851_net {
 	struct spi_message	spi_msg2;
 	struct spi_transfer	spi_xfer1;
 	struct spi_transfer	spi_xfer2[2];
+
+	struct eeprom_93cx6	eeprom;
 };
 
 static int msg_enable;
@@ -1114,6 +1118,141 @@ static int ks8851_nway_reset(struct net_
 	return mii_nway_restart(&ks->mii);
 }
 
+/* EEPROM support */
+
+static void ks8851_eeprom_regread(struct eeprom_93cx6 *ee)
+{
+	struct ks8851_net *ks = ee->data;
+	unsigned val;
+
+	val = ks8851_rdreg16(ks, KS_EEPCR);
+
+	ee->reg_data_out = (val & EEPCR_EESB) ? 1 : 0;
+	ee->reg_data_clock = (val & EEPCR_EESCK) ? 1 : 0;
+	ee->reg_chip_select = (val & EEPCR_EECS) ? 1 : 0;
+}
+
+static void ks8851_eeprom_regwrite(struct eeprom_93cx6 *ee)
+{
+	struct ks8851_net *ks = ee->data;
+	unsigned val = EEPCR_EESA;	/* default - eeprom access on */
+
+	if (ee->drive_data)
+		val |= EEPRC_EESRW;
+	if (ee->reg_data_in)
+		val |= EEPCR_EEDO;
+	if (ee->reg_data_clock)
+		val |= EEPCR_EESCK;
+	if (ee->reg_chip_select)
+		val |= EEPCR_EECS;
+
+	printk(KERN_INFO "%s: wr %04x\n", __func__, val);
+	ks8851_wrreg16(ks, KS_EEPCR, val);
+}
+
+/**
+ * ks8851_eeprom_claim - claim device EEPROM and activate the interface
+ * @ks: The network deice state.
+ *
+ * Check for the presence of an EEPROM, and then activate software access
+ * to the device.
+ */
+static int ks8851_eeprom_claim(struct ks8851_net *ks)
+{
+	if (!(ks->rc_ccr & CCR_EEPROM))
+		return -ENOENT;
+
+	/* start with clock low, cs high */
+	ks8851_wrreg16(ks, KS_EEPCR, EEPCR_EESA | EEPCR_EECS);
+	return 0;
+}
+
+/**
+ * ks8851_eeprom_release - release the EEPROM interface
+ * @ks: The device state
+ *
+ * Release the software access to the device EEPROM
+ */
+static void ks8851_eeprom_release(struct ks8851_net *ks)
+{
+	unsigned val = ks8851_rdreg16(ks,KS_EEPCR);
+
+	ks8851_wrreg16(ks, KS_EEPCR, val & ~EEPCR_EESA);
+}
+
+#define KS_EEPROM_MAGIC (0x00008851)
+
+static int ks8851_set_eeprom(struct net_device *dev,
+			     struct ethtool_eeprom *ee, u8 *data)
+{
+	struct ks8851_net *ks = netdev_priv(dev);
+	int offset = ee->offset;
+	int len = ee->len;
+	u16 tmp;
+
+	/* currently only support byte writing */
+	if (len != 1)
+		return -EINVAL;
+
+	if (ee->magic != KS_EEPROM_MAGIC)
+		return -EINVAL;
+
+	if (ks8851_eeprom_claim(ks))
+		return -ENOENT;
+
+	eeprom_93cx6_wren(&ks->eeprom, true);
+
+	/* ethtool currently only supports writing bytes, which means
+	 * we have to read/modify/write our 16bit EEPROMs */
+
+	eeprom_93cx6_read(&ks->eeprom, offset/2, &tmp);
+
+	if (offset & 1) {
+		tmp &= 0xff;
+		tmp |= *data << 8;
+	} else {
+		tmp &= 0xff00;
+		tmp |= *data;
+	}
+
+	eeprom_93cx6_write(&ks->eeprom, offset/2, tmp);
+	eeprom_93cx6_wren(&ks->eeprom, false);
+
+	ks8851_eeprom_release(ks);
+
+	return 0;
+}
+
+static int ks8851_get_eeprom(struct net_device *dev,
+			     struct ethtool_eeprom *ee, u8 *data)
+{
+	struct ks8851_net *ks = netdev_priv(dev);
+	int offset = ee->offset;
+	int len = ee->len;
+
+	/* must be 2 byte aligned */
+	if (len & 1 || offset & 1)
+		return -EINVAL;
+
+	if (ks8851_eeprom_claim(ks))
+		return -ENOENT;
+
+	ee->magic = KS_EEPROM_MAGIC;
+
+	eeprom_93cx6_multiread(&ks->eeprom, offset/2, (__le16 *)data, len/2);
+	ks8851_eeprom_release(ks);
+
+	return 0;
+}
+
+static int ks8851_get_eeprom_len(struct net_device *dev)
+{
+	struct ks8851_net *ks = netdev_priv(dev);
+
+	/* currently, we assume it is an 93C46 attached, so return 128 */
+	return ks->rc_ccr & CCR_EEPROM ? 128 : 0;
+}
+
 static const struct ethtool_ops ks8851_ethtool_ops = {
 	.get_drvinfo	= ks8851_get_drvinfo,
 	.get_msglevel	= ks8851_get_msglevel,
@@ -1122,6 +1261,9 @@ static const struct ethtool_ops ks8851_e
 	.set_settings	= ks8851_set_settings,
 	.get_link	= ks8851_get_link,
 	.nway_reset	= ks8851_nway_reset,
+	.get_eeprom_len = ks8851_get_eeprom_len,
+	.get_eeprom	= ks8851_get_eeprom,
+	.set_eeprom	= ks8851_set_eeprom,
 };
 
 /* MII interface controls */
@@ -1271,6 +1413,13 @@ static int __devinit ks8851_probe(struct
 	spi_message_add_tail(&ks->spi_xfer2[0], &ks->spi_msg2);
 	spi_message_add_tail(&ks->spi_xfer2[1], &ks->spi_msg2);
 
+	/* setup EEPROM state */
+
+	ks->eeprom.data = ks;
+	ks->eeprom.width = PCI_EEPROM_WIDTH_93C46;
+	ks->eeprom.register_read = ks8851_eeprom_regread;
+	ks->eeprom.register_write = ks8851_eeprom_regwrite;
+
 	/* setup mii state */
 	ks->mii.dev		= ndev;
 	ks->mii.phy_id		= 1,
Index: b/drivers/net/Kconfig
===================================================================
--- a/drivers/net/Kconfig	2009-12-07 10:52:32.000000000 +0000
+++ b/drivers/net/Kconfig	2009-12-07 11:01:34.000000000 +0000
@@ -1735,6 +1735,7 @@ config KS8851
        depends on SPI
        select MII
 	select CRC32
+	select EEPROM_93CX6
        help
          SPI driver for Micrel KS8851 SPI attached network chip.
 
Index: b/drivers/net/ks8851.h
===================================================================
--- a/drivers/net/ks8851.h	2009-12-07 10:52:32.000000000 +0000
+++ b/drivers/net/ks8851.h	2009-12-07 11:01:34.000000000 +0000
@@ -25,6 +25,7 @@
 #define OBCR_ODS_16mA				(1 << 6)
 
 #define KS_EEPCR				0x22
+#define EEPRC_EESRW				(1 << 5)
 #define EEPCR_EESA				(1 << 4)
 #define EEPCR_EESB				(1 << 3)
 #define EEPCR_EEDO				(1 << 2)


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

* [patch 5/9] KS8851: Add debugfs export for driver state
       [not found] <20091207121501.819539008@fluff.org.uk>
                   ` (3 preceding siblings ...)
  2009-12-07 12:15 ` [patch 4/9] KS8851: Add ethtool support for EEPROM ben
@ 2009-12-07 12:15 ` ben
  2009-12-07 12:15 ` [patch 6/9] KS8851: ks8851_mll.c: Use the ks8851.h header for device register defines ben
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: ben @ 2009-12-07 12:15 UTC (permalink / raw)
  To: netdev; +Cc: linux, doong.ping, tristram.ha

[-- Attachment #1: ks8851-add-debugfs.patch --]
[-- Type: text/plain, Size: 3868 bytes --]

Add the ability to export the state of each network chip via debugfs
to show the cached register state and some of the network device state
information.

Signed-off-by: Ben Dooks <ben@simtec.co.uk>

---
 drivers/net/ks8851.c |   94 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

Index: b/drivers/net/ks8851.c
===================================================================
--- a/drivers/net/ks8851.c	2009-12-07 11:01:34.000000000 +0000
+++ b/drivers/net/ks8851.c	2009-12-07 11:01:39.000000000 +0000
@@ -21,6 +21,9 @@
 #include <linux/mii.h>
 #include <linux/eeprom_93cx6.h>
 
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
 #include <linux/spi/spi.h>
 
 #include "ks8851.h"
@@ -128,6 +131,9 @@ struct ks8851_net {
 	struct spi_transfer	spi_xfer1;
 	struct spi_transfer	spi_xfer2[2];
 
+	struct dentry		*debug_root;
+	struct dentry		*debug_file;
+
 	struct eeprom_93cx6	eeprom;
 };
 
@@ -1374,6 +1380,91 @@ static int ks8851_read_selftest(struct k
 	return 0;
 }
 
+/* debugfs code */
+static int state_show(struct seq_file *seq, void *v)
+{
+	struct ks8851_net *ks = seq->private;
+	struct net_device *ndev = ks->netdev;
+
+	seq_printf(seq, "Register cache:\n");
+	seq_printf(seq, "IEQ\t 0x%04x\n", ks->rc_ier);
+	seq_printf(seq, "RXQCR\t 0x%04x\n", ks->rc_rxqcr);
+	seq_printf(seq, "CCR\t 0x%04x\n", ks->rc_ccr);
+	seq_printf(seq, "RXCR1\t 0x%04x\n", ks->rxctrl.rxcr1);
+	seq_printf(seq, "RXCR2\t 0x%04x\n", ks->rxctrl.rxcr2);
+	seq_printf(seq, "MCHASH\t 0=0x%04x, 1=%04x, 2=0x%04x, 3=0x%04x\n",
+		   ks->rxctrl.mchash[0], ks->rxctrl.mchash[1],
+		   ks->rxctrl.mchash[2], ks->rxctrl.mchash[3]);
+
+	seq_printf(seq, "\n");
+
+	seq_printf(seq, "tx_space = 0x%04x\n", ks->tx_space);
+	seq_printf(seq, "tx fid\t= 0x%02x\n", ks->fid);
+
+	seq_printf(seq, "\n");
+
+	if (ndev->flags & IFF_MULTICAST) {
+		struct dev_mc_list *mcptr = ndev->mc_list;
+		int i;
+
+		seq_printf(seq, "MC list is %d entries\n", ndev->mc_count);
+
+		for (i = 0; i < ndev->mc_count; i++) {
+			seq_printf(seq, "\t%d: %pM\n", i, mcptr->dmi_addr);
+			mcptr = mcptr->next;
+		}
+	} else
+		seq_printf(seq, "No multicast list set\n");
+
+	return 0;
+}
+
+static int state_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, state_show, inode->i_private);
+}
+
+static const struct file_operations state_fops = {
+	.owner	= THIS_MODULE,
+	.open	= state_open,
+	.read	= seq_read,
+	.llseek	= seq_lseek,
+	.release = single_release,
+};
+
+/**
+ * ks8851_create_debugfs - create debugfs directory and files
+ * @ks: The driver state
+ *
+ * Create the debugfs entries for the specific device.
+ */
+static void __devinit ks8851_create_debugfs(struct ks8851_net *ks)
+{
+	struct dentry *root;
+	char root_name[32];
+
+	snprintf(root_name, sizeof(root_name), "ks8851_%s",
+		 dev_name(&ks->spidev->dev));
+
+	root = debugfs_create_dir(root_name, NULL);
+	if (IS_ERR(root)) {
+		ks_err(ks, "cannot create debugfs root\n");
+		return;
+	}
+
+	ks->debug_root = root;
+	ks->debug_file = debugfs_create_file("state", 0444, root,
+					     ks, &state_fops);
+	if (IS_ERR(ks->debug_file))
+		ks_err(ks, "cannot create debugfs state file\n");
+}
+
+static void __devexit ks8851_delete_debugfs(struct ks8851_net *ks)
+{
+	debugfs_remove(ks->debug_file);
+	debugfs_remove(ks->debug_root);
+}
+
 /* driver bus management functions */
 
 static int __devinit ks8851_probe(struct spi_device *spi)
@@ -1482,6 +1573,8 @@ static int __devinit ks8851_probe(struct
 		 ndev->dev_addr, ndev->irq,
 		 ks->rc_ccr & CCR_EEPROM ? "has" : "no");
 
+	ks8851_create_debugfs(ks);
+
 	return 0;
 
 
@@ -1501,6 +1594,7 @@ static int __devexit ks8851_remove(struc
 	if (netif_msg_drv(priv))
 		dev_info(&spi->dev, "remove");
 
+	ks8851_delete_debugfs(priv);
 	unregister_netdev(priv->netdev);
 	free_irq(spi->irq, priv);
 	free_netdev(priv->netdev);


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

* [patch 6/9] KS8851: ks8851_mll.c: Use the ks8851.h header for device register defines
       [not found] <20091207121501.819539008@fluff.org.uk>
                   ` (4 preceding siblings ...)
  2009-12-07 12:15 ` [patch 5/9] KS8851: Add debugfs export for driver state ben
@ 2009-12-07 12:15 ` ben
  2009-12-07 12:15 ` [patch 7/9] KS8851: Update ks8851.h header from ks8851_mll.c ben
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: ben @ 2009-12-07 12:15 UTC (permalink / raw)
  To: netdev; +Cc: linux, doong.ping, tristram.ha, Ben Dooks

[-- Attachment #1: ks8851-reduce-header-duplication.patch --]
[-- Type: text/plain, Size: 9425 bytes --]

From: Ben Dooks <ben-linux@fluff.org>

The ks8851_mll.c file uses an almost identical copy of ks8851.h included
directly into the source code, baring some identation changes. This patch
removes the commone defines from ks8851_mll.c and includes ks8851.h.

As a note, we did not merge anything that is specific in ks8851_mll.c into
ks8851.h yet.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

---
 drivers/net/ks8851_mll.c |  263 -----------------------------------------------
 1 file changed, 5 insertions(+), 258 deletions(-)

Index: b/drivers/net/ks8851_mll.c
===================================================================
--- a/drivers/net/ks8851_mll.c	2009-12-07 10:52:31.000000000 +0000
+++ b/drivers/net/ks8851_mll.c	2009-12-07 11:21:15.000000000 +0000
@@ -32,6 +32,8 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 
+#include "ks8851.h"
+
 #define	DRV_NAME	"ks8851_mll"
 
 static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 };
@@ -40,165 +42,26 @@ static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0
 #define TX_BUF_SIZE			2000
 #define RX_BUF_SIZE			2000
 
-#define KS_CCR				0x08
-#define CCR_EEPROM			(1 << 9)
-#define CCR_SPI				(1 << 8)
 #define CCR_8BIT			(1 << 7)
 #define CCR_16BIT			(1 << 6)
 #define CCR_32BIT			(1 << 5)
 #define CCR_SHARED			(1 << 4)
-#define CCR_32PIN			(1 << 0)
-
-/* MAC address registers */
-#define KS_MARL				0x10
-#define KS_MARM				0x12
-#define KS_MARH				0x14
 
-#define KS_OBCR				0x20
 #define OBCR_ODS_16MA			(1 << 6)
 
-#define KS_EEPCR			0x22
-#define EEPCR_EESA			(1 << 4)
-#define EEPCR_EESB			(1 << 3)
-#define EEPCR_EEDO			(1 << 2)
-#define EEPCR_EESCK			(1 << 1)
-#define EEPCR_EECS			(1 << 0)
-
-#define KS_MBIR				0x24
-#define MBIR_TXMBF			(1 << 12)
-#define MBIR_TXMBFA			(1 << 11)
-#define MBIR_RXMBF			(1 << 4)
-#define MBIR_RXMBFA			(1 << 3)
-
-#define KS_GRR				0x26
-#define GRR_QMU				(1 << 1)
-#define GRR_GSR				(1 << 0)
-
-#define KS_WFCR				0x2A
-#define WFCR_MPRXE			(1 << 7)
-#define WFCR_WF3E			(1 << 3)
-#define WFCR_WF2E			(1 << 2)
-#define WFCR_WF1E			(1 << 1)
-#define WFCR_WF0E			(1 << 0)
-
-#define KS_WF0CRC0			0x30
-#define KS_WF0CRC1			0x32
-#define KS_WF0BM0			0x34
-#define KS_WF0BM1			0x36
-#define KS_WF0BM2			0x38
-#define KS_WF0BM3			0x3A
-
-#define KS_WF1CRC0			0x40
-#define KS_WF1CRC1			0x42
-#define KS_WF1BM0			0x44
-#define KS_WF1BM1			0x46
-#define KS_WF1BM2			0x48
-#define KS_WF1BM3			0x4A
-
-#define KS_WF2CRC0			0x50
-#define KS_WF2CRC1			0x52
-#define KS_WF2BM0			0x54
-#define KS_WF2BM1			0x56
-#define KS_WF2BM2			0x58
-#define KS_WF2BM3			0x5A
-
-#define KS_WF3CRC0			0x60
-#define KS_WF3CRC1			0x62
-#define KS_WF3BM0			0x64
-#define KS_WF3BM1			0x66
-#define KS_WF3BM2			0x68
-#define KS_WF3BM3			0x6A
-
-#define KS_TXCR				0x70
-#define TXCR_TCGICMP			(1 << 8)
-#define TXCR_TCGUDP			(1 << 7)
-#define TXCR_TCGTCP			(1 << 6)
-#define TXCR_TCGIP			(1 << 5)
-#define TXCR_FTXQ			(1 << 4)
-#define TXCR_TXFCE			(1 << 3)
-#define TXCR_TXPE			(1 << 2)
-#define TXCR_TXCRC			(1 << 1)
-#define TXCR_TXE			(1 << 0)
-
-#define KS_TXSR				0x72
-#define TXSR_TXLC			(1 << 13)
-#define TXSR_TXMC			(1 << 12)
-#define TXSR_TXFID_MASK			(0x3f << 0)
-#define TXSR_TXFID_SHIFT		(0)
-#define TXSR_TXFID_GET(_v)		(((_v) >> 0) & 0x3f)
-
-
-#define KS_RXCR1			0x74
-#define RXCR1_FRXQ			(1 << 15)
-#define RXCR1_RXUDPFCC			(1 << 14)
-#define RXCR1_RXTCPFCC			(1 << 13)
-#define RXCR1_RXIPFCC			(1 << 12)
-#define RXCR1_RXPAFMA			(1 << 11)
-#define RXCR1_RXFCE			(1 << 10)
-#define RXCR1_RXEFE			(1 << 9)
-#define RXCR1_RXMAFMA			(1 << 8)
-#define RXCR1_RXBE			(1 << 7)
-#define RXCR1_RXME			(1 << 6)
-#define RXCR1_RXUE			(1 << 5)
-#define RXCR1_RXAE			(1 << 4)
-#define RXCR1_RXINVF			(1 << 1)
-#define RXCR1_RXE			(1 << 0)
 #define RXCR1_FILTER_MASK    		(RXCR1_RXINVF | RXCR1_RXAE | \
 					 RXCR1_RXMAFMA | RXCR1_RXPAFMA)
 
-#define KS_RXCR2			0x76
-#define RXCR2_SRDBL_MASK		(0x7 << 5)
-#define RXCR2_SRDBL_SHIFT		(5)
-#define RXCR2_SRDBL_4B			(0x0 << 5)
-#define RXCR2_SRDBL_8B			(0x1 << 5)
-#define RXCR2_SRDBL_16B			(0x2 << 5)
-#define RXCR2_SRDBL_32B			(0x3 << 5)
-/* #define RXCR2_SRDBL_FRAME		(0x4 << 5) */
-#define RXCR2_IUFFP			(1 << 4)
-#define RXCR2_RXIUFCEZ			(1 << 3)
-#define RXCR2_UDPLFE			(1 << 2)
-#define RXCR2_RXICMPFCC			(1 << 1)
-#define RXCR2_RXSAF			(1 << 0)
-
-#define KS_TXMIR			0x78
-
-#define KS_RXFHSR			0x7C
-#define RXFSHR_RXFV			(1 << 15)
-#define RXFSHR_RXICMPFCS		(1 << 13)
-#define RXFSHR_RXIPFCS			(1 << 12)
-#define RXFSHR_RXTCPFCS			(1 << 11)
-#define RXFSHR_RXUDPFCS			(1 << 10)
-#define RXFSHR_RXBF			(1 << 7)
-#define RXFSHR_RXMF			(1 << 6)
-#define RXFSHR_RXUF			(1 << 5)
-#define RXFSHR_RXMR			(1 << 4)
-#define RXFSHR_RXFT			(1 << 3)
-#define RXFSHR_RXFTL			(1 << 2)
-#define RXFSHR_RXRF			(1 << 1)
-#define RXFSHR_RXCE			(1 << 0)
+#undef RXCR2_SRDBL_FRAME
+
 #define	RXFSHR_ERR			(RXFSHR_RXCE | RXFSHR_RXRF |\
 					RXFSHR_RXFTL | RXFSHR_RXMR |\
 					RXFSHR_RXICMPFCS | RXFSHR_RXIPFCS |\
 					RXFSHR_RXTCPFCS)
+
 #define KS_RXFHBCR			0x7E
 #define RXFHBCR_CNT_MASK		0x0FFF
 
-#define KS_TXQCR			0x80
-#define TXQCR_AETFE			(1 << 2)
-#define TXQCR_TXQMAM			(1 << 1)
-#define TXQCR_METFE			(1 << 0)
-
-#define KS_RXQCR			0x82
-#define RXQCR_RXDTTS			(1 << 12)
-#define RXQCR_RXDBCTS			(1 << 11)
-#define RXQCR_RXFCTS			(1 << 10)
-#define RXQCR_RXIPHTOE			(1 << 9)
-#define RXQCR_RXDTTE			(1 << 7)
-#define RXQCR_RXDBCTE			(1 << 6)
-#define RXQCR_RXFCTE			(1 << 5)
-#define RXQCR_ADRFE			(1 << 4)
-#define RXQCR_SDA			(1 << 3)
-#define RXQCR_RRXEF			(1 << 0)
 #define RXQCR_CMD_CNTL                	(RXQCR_RXFCTE|RXQCR_ADRFE)
 
 #define KS_TXFDPR			0x84
@@ -209,130 +72,14 @@ static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0
 #define KS_RXFDPR			0x86
 #define RXFDPR_RXFPAI			(1 << 14)
 
-#define KS_RXDTTR			0x8C
-#define KS_RXDBCTR			0x8E
-
-#define KS_IER				0x90
-#define KS_ISR				0x92
-#define IRQ_LCI				(1 << 15)
-#define IRQ_TXI				(1 << 14)
-#define IRQ_RXI				(1 << 13)
-#define IRQ_RXOI			(1 << 11)
-#define IRQ_TXPSI			(1 << 9)
-#define IRQ_RXPSI			(1 << 8)
-#define IRQ_TXSAI			(1 << 6)
-#define IRQ_RXWFDI			(1 << 5)
-#define IRQ_RXMPDI			(1 << 4)
-#define IRQ_LDI				(1 << 3)
-#define IRQ_EDI				(1 << 2)
-#define IRQ_SPIBEI			(1 << 1)
-#define IRQ_DEDI			(1 << 0)
-
-#define KS_RXFCTR			0x9C
 #define RXFCTR_THRESHOLD_MASK     	0x00FF
 
-#define KS_RXFC				0x9D
-#define RXFCTR_RXFC_MASK		(0xff << 8)
-#define RXFCTR_RXFC_SHIFT		(8)
-#define RXFCTR_RXFC_GET(_v)		(((_v) >> 8) & 0xff)
-#define RXFCTR_RXFCT_MASK		(0xff << 0)
-#define RXFCTR_RXFCT_SHIFT		(0)
-
-#define KS_TXNTFSR			0x9E
-
-#define KS_MAHTR0			0xA0
-#define KS_MAHTR1			0xA2
-#define KS_MAHTR2			0xA4
-#define KS_MAHTR3			0xA6
-
-#define KS_FCLWR			0xB0
-#define KS_FCHWR			0xB2
-#define KS_FCOWR			0xB4
-
-#define KS_CIDER			0xC0
-#define CIDER_ID			0x8870
-#define CIDER_REV_MASK			(0x7 << 1)
-#define CIDER_REV_SHIFT			(1)
-#define CIDER_REV_GET(_v)		(((_v) >> 1) & 0x7)
-
-#define KS_CGCR				0xC6
-#define KS_IACR				0xC8
-#define IACR_RDEN			(1 << 12)
-#define IACR_TSEL_MASK			(0x3 << 10)
-#define IACR_TSEL_SHIFT			(10)
-#define IACR_TSEL_MIB			(0x3 << 10)
-#define IACR_ADDR_MASK			(0x1f << 0)
-#define IACR_ADDR_SHIFT			(0)
-
-#define KS_IADLR			0xD0
-#define KS_IAHDR			0xD2
-
-#define KS_PMECR			0xD4
-#define PMECR_PME_DELAY			(1 << 14)
-#define PMECR_PME_POL			(1 << 12)
-#define PMECR_WOL_WAKEUP		(1 << 11)
-#define PMECR_WOL_MAGICPKT		(1 << 10)
-#define PMECR_WOL_LINKUP		(1 << 9)
-#define PMECR_WOL_ENERGY		(1 << 8)
-#define PMECR_AUTO_WAKE_EN		(1 << 7)
-#define PMECR_WAKEUP_NORMAL		(1 << 6)
-#define PMECR_WKEVT_MASK		(0xf << 2)
-#define PMECR_WKEVT_SHIFT		(2)
-#define PMECR_WKEVT_GET(_v)		(((_v) >> 2) & 0xf)
-#define PMECR_WKEVT_ENERGY		(0x1 << 2)
-#define PMECR_WKEVT_LINK		(0x2 << 2)
-#define PMECR_WKEVT_MAGICPKT		(0x4 << 2)
-#define PMECR_WKEVT_FRAME		(0x8 << 2)
-#define PMECR_PM_MASK			(0x3 << 0)
-#define PMECR_PM_SHIFT			(0)
-#define PMECR_PM_NORMAL			(0x0 << 0)
-#define PMECR_PM_ENERGY			(0x1 << 0)
-#define PMECR_PM_SOFTDOWN		(0x2 << 0)
-#define PMECR_PM_POWERSAVE		(0x3 << 0)
-
-/* Standard MII PHY data */
-#define KS_P1MBCR			0xE4
 #define P1MBCR_FORCE_FDX		(1 << 8)
 
-#define KS_P1MBSR			0xE6
 #define P1MBSR_AN_COMPLETE		(1 << 5)
 #define P1MBSR_AN_CAPABLE		(1 << 3)
 #define P1MBSR_LINK_UP			(1 << 2)
 
-#define KS_PHY1ILR			0xE8
-#define KS_PHY1IHR			0xEA
-#define KS_P1ANAR			0xEC
-#define KS_P1ANLPR			0xEE
-
-#define KS_P1SCLMD			0xF4
-#define P1SCLMD_LEDOFF			(1 << 15)
-#define P1SCLMD_TXIDS			(1 << 14)
-#define P1SCLMD_RESTARTAN		(1 << 13)
-#define P1SCLMD_DISAUTOMDIX		(1 << 10)
-#define P1SCLMD_FORCEMDIX		(1 << 9)
-#define P1SCLMD_AUTONEGEN		(1 << 7)
-#define P1SCLMD_FORCE100		(1 << 6)
-#define P1SCLMD_FORCEFDX		(1 << 5)
-#define P1SCLMD_ADV_FLOW		(1 << 4)
-#define P1SCLMD_ADV_100BT_FDX		(1 << 3)
-#define P1SCLMD_ADV_100BT_HDX		(1 << 2)
-#define P1SCLMD_ADV_10BT_FDX		(1 << 1)
-#define P1SCLMD_ADV_10BT_HDX		(1 << 0)
-
-#define KS_P1CR				0xF6
-#define P1CR_HP_MDIX			(1 << 15)
-#define P1CR_REV_POL			(1 << 13)
-#define P1CR_OP_100M			(1 << 10)
-#define P1CR_OP_FDX			(1 << 9)
-#define P1CR_OP_MDI			(1 << 7)
-#define P1CR_AN_DONE			(1 << 6)
-#define P1CR_LINK_GOOD			(1 << 5)
-#define P1CR_PNTR_FLOW			(1 << 4)
-#define P1CR_PNTR_100BT_FDX		(1 << 3)
-#define P1CR_PNTR_100BT_HDX		(1 << 2)
-#define P1CR_PNTR_10BT_FDX		(1 << 1)
-#define P1CR_PNTR_10BT_HDX		(1 << 0)
-
 /* TX Frame control */
 
 #define TXFR_TXIC			(1 << 15)


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

* [patch 7/9] KS8851: Update ks8851.h header from ks8851_mll.c
       [not found] <20091207121501.819539008@fluff.org.uk>
                   ` (5 preceding siblings ...)
  2009-12-07 12:15 ` [patch 6/9] KS8851: ks8851_mll.c: Use the ks8851.h header for device register defines ben
@ 2009-12-07 12:15 ` ben
  2009-12-07 12:15 ` [patch 8/9] KS8851: Use the ks8851.h header to hold union ks8851_tx_hdr ben
  2009-12-07 12:15 ` [patch 9/9] KS8851: Add platform data to specific IRQ trigger type ben
  8 siblings, 0 replies; 12+ messages in thread
From: ben @ 2009-12-07 12:15 UTC (permalink / raw)
  To: netdev; +Cc: linux, doong.ping, tristram.ha

[-- Attachment #1: ks8851-reduce-header-duplication2.patch --]
[-- Type: text/plain, Size: 4080 bytes --]

Move more useful definitions from ks8851_mll.c into ks8851.h and include
a brief copyright update from the mll source file. Also mop up a few
definitions that got missed in the first patch.

Signed-off-by: Ben Dooks <ben@simtec.co.uk>

---

Index: b/drivers/net/ks8851.h
===================================================================
--- a/drivers/net/ks8851.h	2009-12-07 11:20:52.000000000 +0000
+++ b/drivers/net/ks8851.h	2009-12-07 11:21:21.000000000 +0000
@@ -3,6 +3,9 @@
  * Copyright 2009 Simtec Electronics
  *      Ben Dooks <ben@simtec.co.uk>
  *
+ * portions from drivers/net/ks8851_mll.c,
+ *	Copyright (c) 2009 Micrel Inc.
+ *
  * KS8851 register definitions
  *
  * This program is free software; you can redistribute it and/or modify
@@ -13,6 +16,10 @@
 #define KS_CCR					0x08
 #define CCR_EEPROM				(1 << 9)
 #define CCR_SPI					(1 << 8)
+#define CCR_8BIT				(1 << 7)
+#define CCR_16BIT				(1 << 6)
+#define CCR_32BIT				(1 << 5)
+#define CCR_SHARED				(1 << 4)
 #define CCR_32PIN				(1 << 0)
 
 /* MAC address registers */
@@ -250,7 +257,13 @@
 
 /* Standard MII PHY data */
 #define KS_P1MBCR				0xE4
+#define P1MBCR_FORCE_FDX			(1 << 8)
+
 #define KS_P1MBSR				0xE6
+#define P1MBSR_AN_COMPLETE			(1 << 5)
+#define P1MBSR_AN_CAPABLE			(1 << 3)
+#define P1MBSR_LINK_UP				(1 << 2)
+
 #define KS_PHY1ILR				0xE8
 #define KS_PHY1IHR				0xEA
 #define KS_P1ANAR				0xEC
@@ -285,6 +298,20 @@
 #define P1CR_PNTR_10BT_FDX			(1 << 1)
 #define P1CR_PNTR_10BT_HDX			(1 << 0)
 
+#define KS_P1SR					0xF8
+#define P1SR_HP_MDIX				(1 << 15)
+#define P1SR_REV_POL				(1 << 13)
+#define P1SR_OP_100M				(1 << 10)
+#define P1SR_OP_FDX				(1 << 9)
+#define P1SR_OP_MDI				(1 << 7)
+#define P1SR_AN_DONE				(1 << 6)
+#define P1SR_LINK_GOOD				(1 << 5)
+#define P1SR_PNTR_FLOW				(1 << 4)
+#define P1SR_PNTR_100BT_FDX			(1 << 3)
+#define P1SR_PNTR_100BT_HDX			(1 << 2)
+#define P1SR_PNTR_10BT_FDX			(1 << 1)
+#define P1SR_PNTR_10BT_HDX			(1 << 0)
+
 /* TX Frame control */
 
 #define TXFR_TXIC				(1 << 15)
Index: b/drivers/net/ks8851_mll.c
===================================================================
--- a/drivers/net/ks8851_mll.c	2009-12-07 11:21:15.000000000 +0000
+++ b/drivers/net/ks8851_mll.c	2009-12-07 11:22:47.000000000 +0000
@@ -42,13 +42,6 @@ static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0
 #define TX_BUF_SIZE			2000
 #define RX_BUF_SIZE			2000
 
-#define CCR_8BIT			(1 << 7)
-#define CCR_16BIT			(1 << 6)
-#define CCR_32BIT			(1 << 5)
-#define CCR_SHARED			(1 << 4)
-
-#define OBCR_ODS_16MA			(1 << 6)
-
 #define RXCR1_FILTER_MASK    		(RXCR1_RXINVF | RXCR1_RXAE | \
 					 RXCR1_RXMAFMA | RXCR1_RXPAFMA)
 
@@ -64,41 +57,10 @@ static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0
 
 #define RXQCR_CMD_CNTL                	(RXQCR_RXFCTE|RXQCR_ADRFE)
 
-#define KS_TXFDPR			0x84
-#define TXFDPR_TXFPAI			(1 << 14)
-#define TXFDPR_TXFP_MASK		(0x7ff << 0)
-#define TXFDPR_TXFP_SHIFT		(0)
-
-#define KS_RXFDPR			0x86
-#define RXFDPR_RXFPAI			(1 << 14)
-
 #define RXFCTR_THRESHOLD_MASK     	0x00FF
 
-#define P1MBCR_FORCE_FDX		(1 << 8)
-
-#define P1MBSR_AN_COMPLETE		(1 << 5)
-#define P1MBSR_AN_CAPABLE		(1 << 3)
-#define P1MBSR_LINK_UP			(1 << 2)
-
 /* TX Frame control */
 
-#define TXFR_TXIC			(1 << 15)
-#define TXFR_TXFID_MASK			(0x3f << 0)
-#define TXFR_TXFID_SHIFT		(0)
-
-#define KS_P1SR				0xF8
-#define P1SR_HP_MDIX			(1 << 15)
-#define P1SR_REV_POL			(1 << 13)
-#define P1SR_OP_100M			(1 << 10)
-#define P1SR_OP_FDX			(1 << 9)
-#define P1SR_OP_MDI			(1 << 7)
-#define P1SR_AN_DONE			(1 << 6)
-#define P1SR_LINK_GOOD			(1 << 5)
-#define P1SR_PNTR_FLOW			(1 << 4)
-#define P1SR_PNTR_100BT_FDX		(1 << 3)
-#define P1SR_PNTR_100BT_HDX		(1 << 2)
-#define P1SR_PNTR_10BT_FDX		(1 << 1)
-#define P1SR_PNTR_10BT_HDX		(1 << 0)
 
 #define	ENUM_BUS_NONE			0
 #define	ENUM_BUS_8BIT			1
@@ -1360,7 +1322,7 @@ static int __devinit ks8851_probe(struct
 	memcpy(netdev->dev_addr, ks->mac_addr, 6);
 
 	data = ks_rdreg16(ks, KS_OBCR);
-	ks_wrreg16(ks, KS_OBCR, data | OBCR_ODS_16MA);
+	ks_wrreg16(ks, KS_OBCR, data | OBCR_ODS_16mA);
 
 	/**
 	 * If you want to use the default MAC addr,


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

* [patch 8/9] KS8851: Use the ks8851.h header to hold union ks8851_tx_hdr
       [not found] <20091207121501.819539008@fluff.org.uk>
                   ` (6 preceding siblings ...)
  2009-12-07 12:15 ` [patch 7/9] KS8851: Update ks8851.h header from ks8851_mll.c ben
@ 2009-12-07 12:15 ` ben
  2009-12-07 12:15 ` [patch 9/9] KS8851: Add platform data to specific IRQ trigger type ben
  8 siblings, 0 replies; 12+ messages in thread
From: ben @ 2009-12-07 12:15 UTC (permalink / raw)
  To: netdev; +Cc: linux, doong.ping, tristram.ha

[-- Attachment #1: ks8851-reduce-header-duplication3.patch --]
[-- Type: text/plain, Size: 2833 bytes --]

The union ks8851_tx_hdr turns up in both ks8851.c and ks8851_mll.c in two
different formats, thus making a common version in ks8851.h is going to
save source file usage.

The ks8851_mll.c uses the name ks_tx_hdr instead of ks8851_tx_hdr, so
rename this instance.

Signed-off-by: Ben Dooks <ben@simtec.co.uk>

---

Index: b/drivers/net/ks8851.c
===================================================================
--- a/drivers/net/ks8851.c	2009-12-07 11:24:54.000000000 +0000
+++ b/drivers/net/ks8851.c	2009-12-07 11:29:02.000000000 +0000
@@ -46,19 +46,6 @@ struct ks8851_rxctrl {
 	u16	rxcr2;
 };
 
-/**
- * union ks8851_tx_hdr - tx header data
- * @txb: The header as bytes
- * @txw: The header as 16bit, little-endian words
- *
- * A dual representation of the tx header data to allow
- * access to individual bytes, and to allow 16bit accesses
- * with 16bit alignment.
- */
-union ks8851_tx_hdr {
-	u8	txb[6];
-	__le16	txw[3];
-};
 
 /**
  * struct ks8851_net - KS8851 driver private data
Index: b/drivers/net/ks8851.h
===================================================================
--- a/drivers/net/ks8851.h	2009-12-07 11:26:50.000000000 +0000
+++ b/drivers/net/ks8851.h	2009-12-07 11:28:31.000000000 +0000
@@ -323,3 +323,17 @@
 #define KS_SPIOP_WR				(0x40)
 #define KS_SPIOP_RXFIFO				(0x80)
 #define KS_SPIOP_TXFIFO				(0xC0)
+
+/**
+ * union ks8851_tx_hdr - tx header data
+ * @txb: The header as bytes
+ * @txw: The header as 16bit, little-endian words
+ *
+ * A dual representation of the tx header data to allow
+ * access to individual bytes, and to allow 16bit accesses
+ * with 16bit alignment.
+ */
+union ks8851_tx_hdr {
+	u8	txb[6];
+	__le16	txw[3];
+};
Index: b/drivers/net/ks8851_mll.c
===================================================================
--- a/drivers/net/ks8851_mll.c	2009-12-07 11:24:46.000000000 +0000
+++ b/drivers/net/ks8851_mll.c	2009-12-07 11:28:49.000000000 +0000
@@ -72,20 +72,6 @@ static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0
 #define MAC_ADDR_LEN			6
 
 /**
- * union ks_tx_hdr - tx header data
- * @txb: The header as bytes
- * @txw: The header as 16bit, little-endian words
- *
- * A dual representation of the tx header data to allow
- * access to individual bytes, and to allow 16bit accesses
- * with 16bit alignment.
- */
-union ks_tx_hdr {
-	u8      txb[4];
-	__le16  txw[2];
-};
-
-/**
  * struct ks_net - KS8851 driver private data
  * @net_device 	: The network device we're bound to
  * @hw_addr	: start address of data register.
@@ -137,7 +123,7 @@ struct ks_net {
 	struct net_device	*netdev;
 	void __iomem    	*hw_addr;
 	void __iomem    	*hw_addr_cmd;
-	union ks_tx_hdr		txh ____cacheline_aligned;
+	union ks8851_tx_hdr	txh ____cacheline_aligned;
 	struct mutex      	lock; /* spinlock to be interrupt safe */
 	struct platform_device *pdev;
 	struct mii_if_info	mii;


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

* [patch 9/9] KS8851: Add platform data to specific IRQ trigger type.
       [not found] <20091207121501.819539008@fluff.org.uk>
                   ` (7 preceding siblings ...)
  2009-12-07 12:15 ` [patch 8/9] KS8851: Use the ks8851.h header to hold union ks8851_tx_hdr ben
@ 2009-12-07 12:15 ` ben
  8 siblings, 0 replies; 12+ messages in thread
From: ben @ 2009-12-07 12:15 UTC (permalink / raw)
  To: netdev; +Cc: linux, doong.ping, tristram.ha

[-- Attachment #1: ks8851-add-platform-data.patch --]
[-- Type: text/plain, Size: 3805 bytes --]

Add platform data to allow the board registering the SPI device to
pass what IRQ trigger type it needs to the driver. The default of
low-level trigger is used if no data is specified, or the field is
zero.

Signed-off-by: Ben Dooks <ben@simtec.co.uk>

---
 drivers/net/ks8851.c   |   27 +++++++++++++++++++++++----
 include/linux/ks8851.h |   23 +++++++++++++++++++++++
 2 files changed, 46 insertions(+), 4 deletions(-)

Index: b/drivers/net/ks8851.c
===================================================================
--- a/drivers/net/ks8851.c	2009-12-07 11:47:13.000000000 +0000
+++ b/drivers/net/ks8851.c	2009-12-07 11:58:01.000000000 +0000
@@ -20,6 +20,7 @@
 #include <linux/crc32.h>
 #include <linux/mii.h>
 #include <linux/eeprom_93cx6.h>
+#include <linux/ks8851.h>
 
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
@@ -70,6 +71,7 @@ struct ks8851_rxctrl {
  * @rc_ccr: Cached copy of KS_CCR.
  * @rc_rxqcr: Cached copy of KS_RXQCR.
  * @eeprom: 93CX6 EEPROM state for accessing on-board EEPROM.
+ * @irq_flags: The IRQ flags passed to request_irq().
  *
  * The @lock ensures that the chip is protected when certain operations are
  * in progress. When the read or write packet transfer is in progress, most
@@ -412,6 +414,15 @@ static void ks8851_init_mac(struct ks885
 }
 
 /**
+ * is_level_irq() - return if the given IRQ flags are level triggered
+ * @flags: The flags passed to request_irq().
+*/
+static bool is_level_irq(unsigned flags)
+{
+	return flags & (IRQF_TIRGGER_LOW | IRQF_TRIGGER_HIGH);
+}
+
+/**
  * ks8851_irq - device interrupt handler
  * @irq: Interrupt number passed from the IRQ hnalder.
  * @pw: The private word passed to register_irq(), our struct ks8851_net.
@@ -423,7 +434,9 @@ static irqreturn_t ks8851_irq(int irq, v
 {
 	struct ks8851_net *ks = pw;
 
-	disable_irq_nosync(irq);
+	if (is_level_irq(ks->irq_flags))
+		disable_irq_nosync(irq);
+
 	schedule_work(&ks->irq_work);
 	return IRQ_HANDLED;
 }
@@ -637,7 +650,8 @@ static void ks8851_irq_work(struct work_
 
 	mutex_unlock(&ks->lock);
 
-	enable_irq(ks->netdev->irq);
+	if (is_level_irq(ks->irq_flags))
+		enable_irq(ks->netdev->irq);
 }
 
 /**
@@ -1456,6 +1470,7 @@ static void __devexit ks8851_delete_debu
 
 static int __devinit ks8851_probe(struct spi_device *spi)
 {
+	struct ks8851_pdata *pd = spi->dev.platform_data;
 	struct net_device *ndev;
 	struct ks8851_net *ks;
 	int ret;
@@ -1542,8 +1557,12 @@ static int __devinit ks8851_probe(struct
 	ks8851_init_mac(ks);
 	ks->tx_space = ks8851_rdreg16(ks, KS_TXMIR);
 
-	ret = request_irq(spi->irq, ks8851_irq, IRQF_TRIGGER_LOW,
-			  ndev->name, ks);
+	if (pd && pd->irq_flags)
+		ks->irq_flags = pd->irq_flags;
+	else
+		ks->irq_flags = IRQF_TRIGGER_LOW;
+
+	ret = request_irq(spi->irq, ks8851_irq, ks->irq_flags, ndev->name, ks);
 	if (ret < 0) {
 		dev_err(&spi->dev, "failed to get irq\n");
 		goto err_irq;
Index: b/include/linux/ks8851.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ b/include/linux/ks8851.h	2009-12-07 11:53:54.000000000 +0000
@@ -0,0 +1,23 @@
+/* include/linux/ks8851.h
+ *
+ * Platform specific configuration data for KS8851 driver.
+ *
+ * Copyright 2009 Simtec Electronics
+ *	http://www.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/**
+ * struct ks8851_pdata - platform specific configuration data
+ * @irq_flags: The IRQ trigger flags to pass to request_irq().
+ *
+ * Platform specific configuration to be passed from board support
+ * registering the spi device to the driver.
+ */
+struct ks8851_pdata {
+	unsigned	irq_flags;
+};


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

* [patch 3/9] KS8851: Add support for EEPROM MAC address
       [not found] <20091207121727.016092171@fluff.org.uk>
@ 2009-12-07 12:17 ` Ben Dooks
  0 siblings, 0 replies; 12+ messages in thread
From: Ben Dooks @ 2009-12-07 12:17 UTC (permalink / raw)
  To: netdev; +Cc: linux, doong.ping, tristram.ha

[-- Attachment #1: ks8851-mac-from-eeprom.patch --]
[-- Type: text/plain, Size: 3404 bytes --]

Add support for reading the MAC address from the system registers if there
is an EEPROM present. This involves caching the KS_CCR register for later
use (will also be useful for ETHTOOL support) and adding a print to say
that there is an EEPROM present.

Signed-off-by: Ben Dooks <ben@simtec.co.uk>

---

---
 drivers/net/ks8851.c |   46 +++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 39 insertions(+), 7 deletions(-)

Index: b/drivers/net/ks8851.c
===================================================================
--- a/drivers/net/ks8851.c	2009-12-07 10:59:14.000000000 +0000
+++ b/drivers/net/ks8851.c	2009-12-07 10:59:24.000000000 +0000
@@ -76,6 +76,7 @@ union ks8851_tx_hdr {
  * @msg_enable: The message flags controlling driver output (see ethtool).
  * @fid: Incrementing frame id tag.
  * @rc_ier: Cached copy of KS_IER.
+ * @rc_ccr: Cached copy of KS_CCR.
  * @rc_rxqcr: Cached copy of KS_RXQCR.
  *
  * The @lock ensures that the chip is protected when certain operations are
@@ -107,6 +108,7 @@ struct ks8851_net {
 
 	u16			rc_ier;
 	u16			rc_rxqcr;
+	u16			rc_ccr;
 
 	struct mii_if_info	mii;
 	struct ks8851_rxctrl	rxctrl;
@@ -367,21 +369,47 @@ static int ks8851_write_mac_addr(struct 
 }
 
 /**
+ * ks8851_read_mac_addr - read mac address from device registers
+ * @dev: The network device
+ *
+ * Update our copy of the KS8851 MAC address from the registers of @dev.
+*/
+static void ks8851_read_mac_addr(struct net_device *dev)
+{
+	struct ks8851_net *ks = netdev_priv(dev);
+	int i;
+
+	mutex_lock(&ks->lock);
+
+	for (i = 0; i < ETH_ALEN; i++)
+		dev->dev_addr[i] = ks8851_rdreg8(ks, KS_MAR(i));
+
+	mutex_unlock(&ks->lock);
+}
+
+/**
  * ks8851_init_mac - initialise the mac address
  * @ks: The device structure
  *
  * Get or create the initial mac address for the device and then set that
- * into the station address register. Currently we assume that the device
- * does not have a valid mac address in it, and so we use random_ether_addr()
+ * into the station address register. If there is an EEPROM present, then
+ * we try that. If no valid mac address is found we use random_ether_addr()
  * to create a new one.
- *
- * In future, the driver should check to see if the device has an EEPROM
- * attached and whether that has a valid ethernet address in it.
  */
 static void ks8851_init_mac(struct ks8851_net *ks)
 {
 	struct net_device *dev = ks->netdev;
 
+	/* first, try reading what we've got already */
+	if (ks->rc_ccr & CCR_EEPROM) {
+		ks8851_read_mac_addr(dev);
+		if (is_valid_ether_addr(dev->dev_addr))
+			return;
+
+		ks_err(ks, "invalid mac address read %pM\n",
+			dev->dev_addr);
+	}
+
 	random_ether_addr(dev->dev_addr);
 	ks8851_write_mac_addr(dev);
 }
@@ -1280,6 +1308,9 @@ static int __devinit ks8851_probe(struct
 		goto err_id;
 	}
 
+  	/* cache the contents of the CCR register for EEPROM, etc. */
+  	ks->rc_ccr = ks8851_rdreg16(ks, KS_CCR);
+
 	ks8851_read_selftest(ks);
 	ks8851_init_mac(ks);
 	ks->tx_space = ks8851_rdreg16(ks, KS_TXMIR);
@@ -1297,9 +1328,10 @@ static int __devinit ks8851_probe(struct
 		goto err_netdev;
 	}
 
-	dev_info(&spi->dev, "revision %d, MAC %pM, IRQ %d\n",
+	dev_info(&spi->dev, "revision %d, MAC %pM, IRQ %d, %s EEPROM\n",
 		 CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)),
-		 ndev->dev_addr, ndev->irq);
+		 ndev->dev_addr, ndev->irq,
+		 ks->rc_ccr & CCR_EEPROM ? "has" : "no");
 
 	return 0;
 


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

* Re: [patch 1/9] eeprom_93cx6: Add data direction control.
  2009-12-07 12:15 ` [patch 1/9] eeprom_93cx6: Add data direction control ben
@ 2009-12-07 12:34   ` Ben Dooks
  0 siblings, 0 replies; 12+ messages in thread
From: Ben Dooks @ 2009-12-07 12:34 UTC (permalink / raw)
  To: netdev
  Cc: linux, doong.ping, tristram.ha, Wolfram Sang, Jean Delvare,
	Linux Kernel

Please ignore this first set, sent without changing from: address. (I
did try and stop quilt, but it seems I didn't kill all the processes)

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

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

* Re: [patch 3/9] KS8851: Add support for EEPROM MAC address
  2009-12-07 12:15 ` [patch 3/9] KS8851: Add support for EEPROM MAC address ben
@ 2009-12-09  4:45   ` David Miller
  0 siblings, 0 replies; 12+ messages in thread
From: David Miller @ 2009-12-09  4:45 UTC (permalink / raw)
  To: ben; +Cc: netdev, linux, doong.ping, tristram.ha


Sorry this patch set adds a bunch of features and is too late
for the current merge window.

Please resubmit when net-next-2.6 is openned up again, which should
happen shortly after 2.6.33-rc1 is released.

Thanks.

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

end of thread, other threads:[~2009-12-09  4:45 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20091207121501.819539008@fluff.org.uk>
2009-12-07 12:15 ` [patch 1/9] eeprom_93cx6: Add data direction control ben
2009-12-07 12:34   ` Ben Dooks
2009-12-07 12:15 ` [patch 2/9] eeprom_93cx6: Add write support ben
2009-12-07 12:15 ` [patch 3/9] KS8851: Add support for EEPROM MAC address ben
2009-12-09  4:45   ` David Miller
2009-12-07 12:15 ` [patch 4/9] KS8851: Add ethtool support for EEPROM ben
2009-12-07 12:15 ` [patch 5/9] KS8851: Add debugfs export for driver state ben
2009-12-07 12:15 ` [patch 6/9] KS8851: ks8851_mll.c: Use the ks8851.h header for device register defines ben
2009-12-07 12:15 ` [patch 7/9] KS8851: Update ks8851.h header from ks8851_mll.c ben
2009-12-07 12:15 ` [patch 8/9] KS8851: Use the ks8851.h header to hold union ks8851_tx_hdr ben
2009-12-07 12:15 ` [patch 9/9] KS8851: Add platform data to specific IRQ trigger type ben
     [not found] <20091207121727.016092171@fluff.org.uk>
2009-12-07 12:17 ` [patch 3/9] KS8851: Add support for EEPROM MAC address Ben Dooks

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.