* [patch v3 00/12] DM9000 for next kernel release.
@ 2008-06-24 21:15 Ben Dooks
2008-06-24 21:15 ` [patch v3 01/12] DM9000: Remove the 2 resources probe scheme Ben Dooks
` (11 more replies)
0 siblings, 12 replies; 15+ messages in thread
From: Ben Dooks @ 2008-06-24 21:15 UTC (permalink / raw)
To: netdev; +Cc: jeff, laurentp
This is a new DM9000 series, with some minor
fixups and a couple of changes:
1) Fixes for checkpatch.pl have been appied
2) Update the output when using NSR link polling
to look more like the MII outputs, and some
tidying of the resultant code.
3) Add some documentation for the driver.
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 15+ messages in thread
* [patch v3 01/12] DM9000: Remove the 2 resources probe scheme.
2008-06-24 21:15 [patch v3 00/12] DM9000 for next kernel release Ben Dooks
@ 2008-06-24 21:15 ` Ben Dooks
2008-06-25 3:06 ` Jeff Garzik
2008-06-24 21:15 ` [patch v3 02/12] DM9000: Fixup blackfin after removing 2 resource usage Ben Dooks
` (10 subsequent siblings)
11 siblings, 1 reply; 15+ messages in thread
From: Ben Dooks @ 2008-06-24 21:15 UTC (permalink / raw)
To: netdev; +Cc: jeff, laurentp, Ben Dooks
[-- Attachment #1: thirdparty/dm9000-remove-2resources.patch --]
[-- Type: text/plain, Size: 4697 bytes --]
From: Laurent Pinchart <laurentp@cse-semaphore.com>
The dm9000 driver accepts either 2 or 3 resources to describe the platform
devices. The 2 resources case abuses the ioresource mechanism by passing
ioremap()ed memory through the platform device resources. This patch removes
that case and converts boards that were using it to the 3 resources scheme.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Laurent Pinchart <laurentp@cse-semaphore.com>
---
Index: linux-2.6.26-rc7-next20080624/drivers/net/dm9000.c
===================================================================
--- linux-2.6.26-rc7-next20080624.orig/drivers/net/dm9000.c 2008-06-24 21:58:09.000000000 +0100
+++ linux-2.6.26-rc7-next20080624/drivers/net/dm9000.c 2008-06-24 21:58:25.000000000 +0100
@@ -528,7 +528,6 @@ dm9000_probe(struct platform_device *pde
struct board_info *db; /* Point a board information structure */
struct net_device *ndev;
const unsigned char *mac_src;
- unsigned long base;
int ret = 0;
int iosize;
int i;
@@ -558,81 +557,64 @@ dm9000_probe(struct platform_device *pde
INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);
- if (pdev->num_resources < 2) {
+ if (pdev->num_resources < 3) {
ret = -ENODEV;
goto out;
- } else if (pdev->num_resources == 2) {
- base = pdev->resource[0].start;
-
- if (!request_mem_region(base, 4, ndev->name)) {
- ret = -EBUSY;
- goto out;
- }
-
- ndev->base_addr = base;
- ndev->irq = pdev->resource[1].start;
- db->io_addr = (void __iomem *)base;
- db->io_data = (void __iomem *)(base + 4);
-
- /* ensure at least we have a default set of IO routines */
- dm9000_set_io(db, 2);
-
- } else {
- db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-
- if (db->addr_res == NULL || db->data_res == NULL ||
- db->irq_res == NULL) {
- dev_err(db->dev, "insufficient resources\n");
- ret = -ENOENT;
- goto out;
- }
+ }
- i = res_size(db->addr_res);
- db->addr_req = request_mem_region(db->addr_res->start, i,
- pdev->name);
-
- if (db->addr_req == NULL) {
- dev_err(db->dev, "cannot claim address reg area\n");
- ret = -EIO;
- goto out;
- }
+ db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+ if (db->addr_res == NULL || db->data_res == NULL ||
+ db->irq_res == NULL) {
+ dev_err(db->dev, "insufficient resources\n");
+ ret = -ENOENT;
+ goto out;
+ }
- db->io_addr = ioremap(db->addr_res->start, i);
+ iosize = res_size(db->addr_res);
+ db->addr_req = request_mem_region(db->addr_res->start, iosize,
+ pdev->name);
+
+ if (db->addr_req == NULL) {
+ dev_err(db->dev, "cannot claim address reg area\n");
+ ret = -EIO;
+ goto out;
+ }
- if (db->io_addr == NULL) {
- dev_err(db->dev, "failed to ioremap address reg\n");
- ret = -EINVAL;
- goto out;
- }
+ db->io_addr = ioremap(db->addr_res->start, iosize);
- iosize = res_size(db->data_res);
- db->data_req = request_mem_region(db->data_res->start, iosize,
- pdev->name);
-
- if (db->data_req == NULL) {
- dev_err(db->dev, "cannot claim data reg area\n");
- ret = -EIO;
- goto out;
- }
+ if (db->io_addr == NULL) {
+ dev_err(db->dev, "failed to ioremap address reg\n");
+ ret = -EINVAL;
+ goto out;
+ }
- db->io_data = ioremap(db->data_res->start, iosize);
+ iosize = res_size(db->data_res);
+ db->data_req = request_mem_region(db->data_res->start, iosize,
+ pdev->name);
+
+ if (db->data_req == NULL) {
+ dev_err(db->dev, "cannot claim data reg area\n");
+ ret = -EIO;
+ goto out;
+ }
- if (db->io_data == NULL) {
- dev_err(db->dev,"failed to ioremap data reg\n");
- ret = -EINVAL;
- goto out;
- }
+ db->io_data = ioremap(db->data_res->start, iosize);
- /* fill in parameters for net-dev structure */
+ if (db->io_data == NULL) {
+ dev_err(db->dev, "failed to ioremap data reg\n");
+ ret = -EINVAL;
+ goto out;
+ }
- ndev->base_addr = (unsigned long)db->io_addr;
- ndev->irq = db->irq_res->start;
+ /* fill in parameters for net-dev structure */
+ ndev->base_addr = (unsigned long)db->io_addr;
+ ndev->irq = db->irq_res->start;
- /* ensure at least we have a default set of IO routines */
- dm9000_set_io(db, iosize);
- }
+ /* ensure at least we have a default set of IO routines */
+ dm9000_set_io(db, iosize);
/* check to see if anything is being over-ridden */
if (pdata != NULL) {
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 15+ messages in thread
* [patch v3 02/12] DM9000: Fixup blackfin after removing 2 resource usage
2008-06-24 21:15 [patch v3 00/12] DM9000 for next kernel release Ben Dooks
2008-06-24 21:15 ` [patch v3 01/12] DM9000: Remove the 2 resources probe scheme Ben Dooks
@ 2008-06-24 21:15 ` Ben Dooks
2008-06-24 21:15 ` [patch v3 03/12] DM9000: Add support for DM9000A and DM9000B chips Ben Dooks
` (9 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Ben Dooks @ 2008-06-24 21:15 UTC (permalink / raw)
To: netdev; +Cc: jeff, laurentp, Bryan Wu, Ben Dooks
[-- Attachment #1: thirdparty/dm9000-fixup-blackfin.patch --]
[-- Type: text/plain, Size: 2563 bytes --]
From: Laurent Pinchart <laurentp@cse-semaphore.com>
The dm9000 driver accepts either 2 or 3 resources to describe the platform
devices. The 2 resources case abuses the ioresource mechanism by passing
ioremap()ed memory through the platform device resources. This patch removes
converts boards that were using it to the 3 resources scheme.
CC: Bryan Wu <cooloney@kernel.org>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Laurent Pinchart <laurentp@cse-semaphore.com>
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 5958eec..689b69c 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -323,10 +323,15 @@ static struct platform_device smc91x_device = {
static struct resource dm9000_resources[] = {
[0] = {
.start = 0x203FB800,
- .end = 0x203FB800 + 8,
+ .end = 0x203FB800 + 1,
.flags = IORESOURCE_MEM,
},
[1] = {
+ .start = 0x203FB800 + 4,
+ .end = 0x203FB800 + 5,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
.start = IRQ_PF9,
.end = IRQ_PF9,
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c
index 7cc4864..4103a97 100644
--- a/arch/blackfin/mach-bf533/boards/H8606.c
+++ b/arch/blackfin/mach-bf533/boards/H8606.c
@@ -65,10 +65,15 @@ static struct platform_device rtc_device = {
static struct resource dm9000_resources[] = {
[0] = {
.start = 0x20300000,
- .end = 0x20300000 + 8,
+ .end = 0x20300000 + 1,
.flags = IORESOURCE_MEM,
},
[1] = {
+ .start = 0x20300000 + 4,
+ .end = 0x20300000 + 5,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
.start = IRQ_PF10,
.end = IRQ_PF10,
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c
index 7d25082..01b63e2 100644
--- a/arch/blackfin/mach-bf537/boards/generic_board.c
+++ b/arch/blackfin/mach-bf537/boards/generic_board.c
@@ -166,10 +166,15 @@ static struct platform_device smc91x_device = {
static struct resource dm9000_resources[] = {
[0] = {
.start = 0x203FB800,
- .end = 0x203FB800 + 8,
+ .end = 0x203FB800 + 1,
.flags = IORESOURCE_MEM,
},
[1] = {
+ .start = 0x203FB800 + 4,
+ .end = 0x203FB800 + 5,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
.start = IRQ_PF9,
.end = IRQ_PF9,
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [patch v3 03/12] DM9000: Add support for DM9000A and DM9000B chips
2008-06-24 21:15 [patch v3 00/12] DM9000 for next kernel release Ben Dooks
2008-06-24 21:15 ` [patch v3 01/12] DM9000: Remove the 2 resources probe scheme Ben Dooks
2008-06-24 21:15 ` [patch v3 02/12] DM9000: Fixup blackfin after removing 2 resource usage Ben Dooks
@ 2008-06-24 21:15 ` Ben Dooks
2008-06-24 21:16 ` [patch v3 04/12] DM9000: Cleanups after the resource changes Ben Dooks
` (8 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Ben Dooks @ 2008-06-24 21:15 UTC (permalink / raw)
To: netdev; +Cc: jeff, laurentp, Ben Dooks
[-- Attachment #1: simtec/simtec-drivers-net-dm9000-support-dm9000ab.patch --]
[-- Type: text/plain, Size: 5020 bytes --]
Add support for both the DM9000A and DM9000B versions of
the DM9000 networking chip. This includes adding support
for the Link-Change IRQ which is used instead of polling
the PHY every 2 seconds.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Index: linux-2.6.26-rc7-next20080624/drivers/net/dm9000.c
===================================================================
--- linux-2.6.26-rc7-next20080624.orig/drivers/net/dm9000.c 2008-06-24 22:03:10.000000000 +0100
+++ linux-2.6.26-rc7-next20080624/drivers/net/dm9000.c 2008-06-24 22:03:28.000000000 +0100
@@ -85,6 +85,16 @@ MODULE_PARM_DESC(watchdog, "transmit tim
* these two devices.
*/
+/* The driver supports the original DM9000E, and now the two newer
+ * devices, DM9000A and DM9000B.
+ */
+
+enum dm9000_type {
+ TYPE_DM9000E, /* original DM9000 */
+ TYPE_DM9000A,
+ TYPE_DM9000B
+};
+
/* Structure/enum declaration ------------------------------- */
typedef struct board_info {
@@ -98,9 +108,11 @@ typedef struct board_info {
u16 dbug_cnt;
u8 io_mode; /* 0:word, 2:byte */
u8 phy_addr;
+ u8 imr_all;
unsigned int flags;
unsigned int in_suspend :1;
+ enum dm9000_type type;
int debug_level;
void (*inblk)(void __iomem *port, void *data, int length);
@@ -302,7 +314,8 @@ static void dm9000_set_io(struct board_i
static void dm9000_schedule_poll(board_info_t *db)
{
- schedule_delayed_work(&db->phy_poll, HZ * 2);
+ if (db->type == TYPE_DM9000E)
+ schedule_delayed_work(&db->phy_poll, HZ * 2);
}
/* Our watchdog timed out. Called by the networking layer */
@@ -516,6 +529,17 @@ dm9000_release_board(struct platform_dev
}
}
+static unsigned char dm9000_type_to_char(enum dm9000_type type)
+{
+ switch (type) {
+ case TYPE_DM9000E: return 'e';
+ case TYPE_DM9000A: return 'a';
+ case TYPE_DM9000B: return 'b';
+ }
+
+ return '?';
+}
+
#define res_size(_r) (((_r)->end - (_r)->start) + 1)
/*
@@ -665,6 +689,23 @@ dm9000_probe(struct platform_device *pde
goto out;
}
+ /* Identify what type of DM9000 we are working on */
+
+ id_val = ior(db, DM9000_CHIPR);
+ dev_dbg(db->dev, "dm9000 revision 0x%02x\n", id_val);
+
+ switch (id_val) {
+ case CHIPR_DM9000A:
+ db->type = TYPE_DM9000A;
+ break;
+ case CHIPR_DM9000B:
+ db->type = TYPE_DM9000B;
+ break;
+ default:
+ dev_dbg(db->dev, "ID %02x => defaulting to DM9000E\n", id_val);
+ db->type = TYPE_DM9000E;
+ }
+
/* from this point we assume that we have found a DM9000 */
/* driver system function */
@@ -715,8 +756,9 @@ dm9000_probe(struct platform_device *pde
if (ret == 0) {
DECLARE_MAC_BUF(mac);
- printk("%s: dm9000 at %p,%p IRQ %d MAC: %s (%s)\n",
- ndev->name, db->io_addr, db->io_data, ndev->irq,
+ printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %s (%s)\n",
+ ndev->name, dm9000_type_to_char(db->type),
+ db->io_addr, db->io_data, ndev->irq,
print_mac(mac, ndev->dev_addr), mac_src);
}
return 0;
@@ -778,6 +820,7 @@ static void
dm9000_init_dm9000(struct net_device *dev)
{
board_info_t *db = (board_info_t *) dev->priv;
+ unsigned int imr;
dm9000_dbg(db, 1, "entering %s\n", __func__);
@@ -804,8 +847,14 @@ dm9000_init_dm9000(struct net_device *de
/* Set address filter table */
dm9000_hash_table(dev);
+ imr = IMR_PAR | IMR_PTM | IMR_PRM;
+ if (db->type != TYPE_DM9000E)
+ imr |= IMR_LNKCHNG;
+
+ db->imr_all = imr;
+
/* Enable TX/RX interrupt mask */
- iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
+ iow(db, DM9000_IMR, imr);
/* Init Driver variable */
db->tx_pkt_cnt = 0;
@@ -962,8 +1011,15 @@ dm9000_interrupt(int irq, void *dev_id)
if (int_status & ISR_PTS)
dm9000_tx_done(dev, db);
+ if (db->type != TYPE_DM9000E) {
+ if (int_status & ISR_LNKCHNG) {
+ /* fire a link-change request */
+ schedule_delayed_work(&db->phy_poll, 1);
+ }
+ }
+
/* Re-enable interrupt mask */
- iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
+ iow(db, DM9000_IMR, db->imr_all);
/* Restore previous register address */
writeb(reg_save, db->io_addr);
Index: linux-2.6.26-rc7-next20080624/drivers/net/dm9000.h
===================================================================
--- linux-2.6.26-rc7-next20080624.orig/drivers/net/dm9000.h 2008-06-24 21:58:09.000000000 +0100
+++ linux-2.6.26-rc7-next20080624/drivers/net/dm9000.h 2008-06-24 22:03:12.000000000 +0100
@@ -45,6 +45,9 @@
#define DM9000_CHIPR 0x2C
#define DM9000_SMCR 0x2F
+#define CHIPR_DM9000A 0x19
+#define CHIPR_DM9000B 0x1B
+
#define DM9000_MRCMDX 0xF0
#define DM9000_MRCMD 0xF2
#define DM9000_MRRL 0xF4
@@ -131,5 +134,13 @@
#define DM9000_PKT_RDY 0x01 /* Packet ready to receive */
#define DM9000_PKT_MAX 1536 /* Received packet max size */
+/* DM9000A / DM9000B definitions */
+
+#define IMR_LNKCHNG (1<<5)
+#define IMR_UNDERRUN (1<<4)
+
+#define ISR_LNKCHNG (1<<5)
+#define ISR_UNDERRUN (1<<4)
+
#endif /* _DM9000X_H_ */
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 15+ messages in thread
* [patch v3 04/12] DM9000: Cleanups after the resource changes
2008-06-24 21:15 [patch v3 00/12] DM9000 for next kernel release Ben Dooks
` (2 preceding siblings ...)
2008-06-24 21:15 ` [patch v3 03/12] DM9000: Add support for DM9000A and DM9000B chips Ben Dooks
@ 2008-06-24 21:16 ` Ben Dooks
2008-06-24 21:16 ` [patch v3 05/12] DM9000: Cleanup source code Ben Dooks
` (7 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Ben Dooks @ 2008-06-24 21:16 UTC (permalink / raw)
To: netdev; +Cc: jeff, laurentp, Ben Dooks
[-- Attachment #1: simtec/simtec-drivers-net-dm9000-cleanups0.patch --]
[-- Type: text/plain, Size: 1908 bytes --]
Remove the now extraneous checks in dm9000_release_board()
now that the two-resource case is removed. Also remove the
check on pdev->num_resources, as we check the return data
from platform_get_resource() to ensure we have not only
the right number but the right type of resources as well.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Index: linux-2.6.26-rc6-quilt1/drivers/net/dm9000.c
===================================================================
--- linux-2.6.26-rc6-quilt1.orig/drivers/net/dm9000.c 2008-06-15 22:52:31.000000000 +0100
+++ linux-2.6.26-rc6-quilt1/drivers/net/dm9000.c 2008-06-15 23:14:39.000000000 +0100
@@ -505,12 +502,6 @@ dm9000_poll_work(struct work_struct *w)
static void
dm9000_release_board(struct platform_device *pdev, struct board_info *db)
{
- if (db->data_res == NULL) {
- if (db->addr_res != NULL)
- release_mem_region((unsigned long)db->io_addr, 4);
- return;
- }
-
/* unmap our resources */
iounmap(db->io_addr);
@@ -518,15 +509,11 @@ dm9000_release_board(struct platform_dev
/* release the resources */
- if (db->data_req != NULL) {
- release_resource(db->data_req);
- kfree(db->data_req);
- }
+ release_resource(db->data_req);
+ kfree(db->data_req);
- if (db->addr_req != NULL) {
- release_resource(db->addr_req);
- kfree(db->addr_req);
- }
+ release_resource(db->addr_req);
+ kfree(db->addr_req);
}
static unsigned char dm9000_type_to_char(enum dm9000_type type)
@@ -580,12 +567,6 @@ dm9000_probe(struct platform_device *pde
INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);
-
- if (pdev->num_resources < 3) {
- ret = -ENODEV;
- goto out;
- }
-
db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 15+ messages in thread
* [patch v3 05/12] DM9000: Cleanup source code
2008-06-24 21:15 [patch v3 00/12] DM9000 for next kernel release Ben Dooks
` (3 preceding siblings ...)
2008-06-24 21:16 ` [patch v3 04/12] DM9000: Cleanups after the resource changes Ben Dooks
@ 2008-06-24 21:16 ` Ben Dooks
2008-06-24 21:16 ` [patch v3 06/12] DM9000: Cleanup source code - remove forward declerations Ben Dooks
` (6 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Ben Dooks @ 2008-06-24 21:16 UTC (permalink / raw)
To: netdev; +Cc: jeff, laurentp, Ben Dooks
[-- Attachment #1: simtec/simtec-drivers-net-dm9000-cleanups1.patch --]
[-- Type: text/plain, Size: 5622 bytes --]
Cleanup bits of the DM9000 driver to make the code
neater and easier to read. This is includes removing
some old definitions, re-indenting areas, etc.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Index: linux-2.6.26-rc7-next20080620/drivers/net/dm9000.c
===================================================================
--- linux-2.6.26-rc7-next20080620.orig/drivers/net/dm9000.c 2008-06-23 11:56:36.000000000 +0100
+++ linux-2.6.26-rc7-next20080620/drivers/net/dm9000.c 2008-06-23 11:56:37.000000000 +0100
@@ -44,9 +44,8 @@
#define DM9000_PHY 0x40 /* PHY address 0x01 */
-#define CARDNAME "dm9000"
-#define PFX CARDNAME ": "
-#define DRV_VERSION "1.30"
+#define CARDNAME "dm9000"
+#define DRV_VERSION "1.31"
#ifdef CONFIG_BLACKFIN
#define readsb insb
@@ -98,22 +97,23 @@ enum dm9000_type {
/* Structure/enum declaration ------------------------------- */
typedef struct board_info {
- void __iomem *io_addr; /* Register I/O base address */
- void __iomem *io_data; /* Data I/O address */
- u16 irq; /* IRQ */
-
- u16 tx_pkt_cnt;
- u16 queue_pkt_len;
- u16 queue_start_addr;
- u16 dbug_cnt;
- u8 io_mode; /* 0:word, 2:byte */
- u8 phy_addr;
- u8 imr_all;
- unsigned int flags;
- unsigned int in_suspend :1;
+ void __iomem *io_addr; /* Register I/O base address */
+ void __iomem *io_data; /* Data I/O address */
+ u16 irq; /* IRQ */
+
+ u16 tx_pkt_cnt;
+ u16 queue_pkt_len;
+ u16 queue_start_addr;
+ u16 dbug_cnt;
+ u8 io_mode; /* 0:word, 2:byte */
+ u8 phy_addr;
+ u8 imr_all;
+
+ unsigned int flags;
+ unsigned int in_suspend :1;
+ int debug_level;
enum dm9000_type type;
- int debug_level;
void (*inblk)(void __iomem *port, void *data, int length);
void (*outblk)(void __iomem *port, void *data, int length);
@@ -132,10 +132,10 @@ typedef struct board_info {
struct delayed_work phy_poll;
struct net_device *ndev;
- spinlock_t lock;
+ spinlock_t lock;
struct mii_if_info mii;
- u32 msg_enable;
+ u32 msg_enable;
} board_info_t;
/* debug code */
@@ -153,19 +153,16 @@ static inline board_info_t *to_dm9000_bo
}
/* function declaration ------------------------------------- */
-static int dm9000_probe(struct platform_device *);
static int dm9000_open(struct net_device *);
static int dm9000_start_xmit(struct sk_buff *, struct net_device *);
static int dm9000_stop(struct net_device *);
-static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd);
static void dm9000_init_dm9000(struct net_device *);
static irqreturn_t dm9000_interrupt(int, void *);
-static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg);
-static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg,
- int value);
+static int dm9000_phy_read(struct net_device *dev, int phy, int reg);
+static void dm9000_phy_write(struct net_device *dev, int phy, int reg, int v);
static void dm9000_read_eeprom(board_info_t *, int addr, u8 *to);
static void dm9000_write_eeprom(board_info_t *, int addr, u8 *dp);
@@ -655,7 +652,7 @@ dm9000_probe(struct platform_device *pde
dm9000_reset(db);
- /* try two times, DM9000 sometimes gets the first read wrong */
+ /* try multiple times, DM9000 sometimes gets the read wrong */
for (i = 0; i < 8; i++) {
id_val = ior(db, DM9000_VIDL);
id_val |= (u32)ior(db, DM9000_VIDH) << 8;
@@ -763,7 +760,7 @@ out:
static int
dm9000_open(struct net_device *dev)
{
- board_info_t *db = (board_info_t *) dev->priv;
+ board_info_t *db = dev->priv;
unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
if (netif_msg_ifup(db))
@@ -803,7 +800,7 @@ dm9000_open(struct net_device *dev)
static void
dm9000_init_dm9000(struct net_device *dev)
{
- board_info_t *db = (board_info_t *) dev->priv;
+ board_info_t *db = dev->priv;
unsigned int imr;
dm9000_dbg(db, 1, "entering %s\n", __func__);
@@ -854,7 +851,7 @@ static int
dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
unsigned long flags;
- board_info_t *db = (board_info_t *) dev->priv;
+ board_info_t *db = dev->priv;
dm9000_dbg(db, 3, "%s:\n", __func__);
@@ -897,7 +894,7 @@ dm9000_start_xmit(struct sk_buff *skb, s
static void
dm9000_shutdown(struct net_device *dev)
{
- board_info_t *db = (board_info_t *) dev->priv;
+ board_info_t *db = dev->priv;
/* RESET device */
dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
@@ -913,7 +910,7 @@ dm9000_shutdown(struct net_device *dev)
static int
dm9000_stop(struct net_device *ndev)
{
- board_info_t *db = (board_info_t *) ndev->priv;
+ board_info_t *db = ndev->priv;
if (netif_msg_ifdown(db))
dev_dbg(db->dev, "shutting down %s\n", ndev->name);
@@ -964,7 +961,7 @@ static irqreturn_t
dm9000_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
- board_info_t *db = (board_info_t *) dev->priv;
+ board_info_t *db = dev->priv;
int int_status;
u8 reg_save;
@@ -1345,7 +1342,8 @@ dm9000_phy_read(struct net_device *dev,
* Write a word to phyxcer
*/
static void
-dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
+dm9000_phy_write(struct net_device *dev,
+ int phyaddr_unused, int reg, int value)
{
board_info_t *db = (board_info_t *) dev->priv;
unsigned long flags;
@@ -1454,7 +1452,7 @@ dm9000_init(void)
{
printk(KERN_INFO "%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION);
- return platform_driver_register(&dm9000_driver); /* search board and register */
+ return platform_driver_register(&dm9000_driver);
}
static void __exit
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 15+ messages in thread
* [patch v3 06/12] DM9000: Cleanup source code - remove forward declerations
2008-06-24 21:15 [patch v3 00/12] DM9000 for next kernel release Ben Dooks
` (4 preceding siblings ...)
2008-06-24 21:16 ` [patch v3 05/12] DM9000: Cleanup source code Ben Dooks
@ 2008-06-24 21:16 ` Ben Dooks
2008-06-24 21:16 ` [patch v3 07/12] DM9000: Use NSR to determine link-status on internal PHY Ben Dooks
` (5 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Ben Dooks @ 2008-06-24 21:16 UTC (permalink / raw)
To: netdev; +Cc: jeff, laurentp, Ben Dooks
[-- Attachment #1: simtec/simtec-drivers-net-dm9000-cleanups2.patch --]
[-- Type: text/plain, Size: 32870 bytes --]
Cleanup the source code by moving the code around to avoid
having to declare the functions before they are used.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Index: linux-2.6.26-rc7-next20080624/drivers/net/dm9000.c
===================================================================
--- linux-2.6.26-rc7-next20080624.orig/drivers/net/dm9000.c 2008-06-24 22:03:38.000000000 +0100
+++ linux-2.6.26-rc7-next20080624/drivers/net/dm9000.c 2008-06-24 22:09:14.000000000 +0100
@@ -152,23 +152,6 @@ static inline board_info_t *to_dm9000_bo
return dev->priv;
}
-/* function declaration ------------------------------------- */
-static int dm9000_open(struct net_device *);
-static int dm9000_start_xmit(struct sk_buff *, struct net_device *);
-static int dm9000_stop(struct net_device *);
-
-static void dm9000_init_dm9000(struct net_device *);
-
-static irqreturn_t dm9000_interrupt(int, void *);
-
-static int dm9000_phy_read(struct net_device *dev, int phy, int reg);
-static void dm9000_phy_write(struct net_device *dev, int phy, int reg, int v);
-
-static void dm9000_read_eeprom(board_info_t *, int addr, u8 *to);
-static void dm9000_write_eeprom(board_info_t *, int addr, u8 *dp);
-static void dm9000_rx(struct net_device *);
-static void dm9000_hash_table(struct net_device *);
-
/* DM9000 network board routine ---------------------------- */
static void
@@ -315,49 +298,129 @@ static void dm9000_schedule_poll(board_i
schedule_delayed_work(&db->phy_poll, HZ * 2);
}
-/* Our watchdog timed out. Called by the networking layer */
-static void dm9000_timeout(struct net_device *dev)
+static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+ board_info_t *dm = to_dm9000_board(dev);
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ return generic_mii_ioctl(&dm->mii, if_mii(req), cmd, NULL);
+}
+
+static unsigned int
+dm9000_read_locked(board_info_t *db, int reg)
{
- board_info_t *db = (board_info_t *) dev->priv;
- u8 reg_save;
unsigned long flags;
+ unsigned int ret;
- /* Save previous register address */
- reg_save = readb(db->io_addr);
- spin_lock_irqsave(&db->lock,flags);
+ spin_lock_irqsave(&db->lock, flags);
+ ret = ior(db, reg);
+ spin_unlock_irqrestore(&db->lock, flags);
- netif_stop_queue(dev);
- dm9000_reset(db);
- dm9000_init_dm9000(dev);
- /* We can accept TX packets again */
- dev->trans_start = jiffies;
- netif_wake_queue(dev);
+ return ret;
+}
- /* Restore previous register address */
- writeb(reg_save, db->io_addr);
- spin_unlock_irqrestore(&db->lock,flags);
+static int dm9000_wait_eeprom(board_info_t *db)
+{
+ unsigned int status;
+ int timeout = 8; /* wait max 8msec */
+
+ /* The DM9000 data sheets say we should be able to
+ * poll the ERRE bit in EPCR to wait for the EEPROM
+ * operation. From testing several chips, this bit
+ * does not seem to work.
+ *
+ * We attempt to use the bit, but fall back to the
+ * timeout (which is why we do not return an error
+ * on expiry) to say that the EEPROM operation has
+ * completed.
+ */
+
+ while (1) {
+ status = dm9000_read_locked(db, DM9000_EPCR);
+
+ if ((status & EPCR_ERRE) == 0)
+ break;
+
+ if (timeout-- < 0) {
+ dev_dbg(db->dev, "timeout waiting EEPROM\n");
+ break;
+ }
+ }
+
+ return 0;
}
-#ifdef CONFIG_NET_POLL_CONTROLLER
/*
- *Used by netconsole
+ * Read a word data from EEPROM
*/
-static void dm9000_poll_controller(struct net_device *dev)
+static void
+dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
{
- disable_irq(dev->irq);
- dm9000_interrupt(dev->irq,dev);
- enable_irq(dev->irq);
+ unsigned long flags;
+
+ if (db->flags & DM9000_PLATF_NO_EEPROM) {
+ to[0] = 0xff;
+ to[1] = 0xff;
+ return;
+ }
+
+ mutex_lock(&db->addr_lock);
+
+ spin_lock_irqsave(&db->lock, flags);
+
+ iow(db, DM9000_EPAR, offset);
+ iow(db, DM9000_EPCR, EPCR_ERPRR);
+
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ dm9000_wait_eeprom(db);
+
+ /* delay for at-least 150uS */
+ msleep(1);
+
+ spin_lock_irqsave(&db->lock, flags);
+
+ iow(db, DM9000_EPCR, 0x0);
+
+ to[0] = ior(db, DM9000_EPDRL);
+ to[1] = ior(db, DM9000_EPDRH);
+
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ mutex_unlock(&db->addr_lock);
}
-#endif
-static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+/*
+ * Write a word data to SROM
+ */
+static void
+dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
{
- board_info_t *dm = to_dm9000_board(dev);
+ unsigned long flags;
- if (!netif_running(dev))
- return -EINVAL;
+ if (db->flags & DM9000_PLATF_NO_EEPROM)
+ return;
- return generic_mii_ioctl(&dm->mii, if_mii(req), cmd, NULL);
+ mutex_lock(&db->addr_lock);
+
+ spin_lock_irqsave(&db->lock, flags);
+ iow(db, DM9000_EPAR, offset);
+ iow(db, DM9000_EPDRH, data[1]);
+ iow(db, DM9000_EPDRL, data[0]);
+ iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ dm9000_wait_eeprom(db);
+
+ mdelay(1); /* wait at least 150uS to clear */
+
+ spin_lock_irqsave(&db->lock, flags);
+ iow(db, DM9000_EPCR, 0);
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ mutex_unlock(&db->addr_lock);
}
/* ethtool ops */
@@ -527,294 +590,78 @@ static unsigned char dm9000_type_to_char
return '?';
}
-#define res_size(_r) (((_r)->end - (_r)->start) + 1)
-
/*
- * Search DM9000 board, allocate space and register it
+ * Set DM9000 multicast address
*/
-static int __devinit
-dm9000_probe(struct platform_device *pdev)
+static void
+dm9000_hash_table(struct net_device *dev)
{
- struct dm9000_plat_data *pdata = pdev->dev.platform_data;
- struct board_info *db; /* Point a board information structure */
- struct net_device *ndev;
- const unsigned char *mac_src;
- int ret = 0;
- int iosize;
- int i;
- u32 id_val;
-
- /* Init network device */
- ndev = alloc_etherdev(sizeof (struct board_info));
- if (!ndev) {
- dev_err(&pdev->dev, "could not allocate device.\n");
- return -ENOMEM;
- }
+ board_info_t *db = (board_info_t *) dev->priv;
+ struct dev_mc_list *mcptr = dev->mc_list;
+ int mc_cnt = dev->mc_count;
+ int i, oft;
+ u32 hash_val;
+ u16 hash_table[4];
+ u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN;
+ unsigned long flags;
- SET_NETDEV_DEV(ndev, &pdev->dev);
+ dm9000_dbg(db, 1, "entering %s\n", __func__);
- dev_dbg(&pdev->dev, "dm9000_probe()\n");
+ spin_lock_irqsave(&db->lock, flags);
- /* setup board info structure */
- db = (struct board_info *) ndev->priv;
- memset(db, 0, sizeof (*db));
+ for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
+ iow(db, oft, dev->dev_addr[i]);
- db->dev = &pdev->dev;
- db->ndev = ndev;
+ /* Clear Hash Table */
+ for (i = 0; i < 4; i++)
+ hash_table[i] = 0x0;
- spin_lock_init(&db->lock);
- mutex_init(&db->addr_lock);
+ /* broadcast address */
+ hash_table[3] = 0x8000;
- INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);
+ if (dev->flags & IFF_PROMISC)
+ rcr |= RCR_PRMSC;
- db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (dev->flags & IFF_ALLMULTI)
+ rcr |= RCR_ALL;
- if (db->addr_res == NULL || db->data_res == NULL ||
- db->irq_res == NULL) {
- dev_err(db->dev, "insufficient resources\n");
- ret = -ENOENT;
- goto out;
+ /* the multicast address in Hash Table : 64 bits */
+ for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
+ hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f;
+ hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
}
- iosize = res_size(db->addr_res);
- db->addr_req = request_mem_region(db->addr_res->start, iosize,
- pdev->name);
-
- if (db->addr_req == NULL) {
- dev_err(db->dev, "cannot claim address reg area\n");
- ret = -EIO;
- goto out;
+ /* Write the hash table to MAC MD table */
+ for (i = 0, oft = DM9000_MAR; i < 4; i++) {
+ iow(db, oft++, hash_table[i]);
+ iow(db, oft++, hash_table[i] >> 8);
}
- db->io_addr = ioremap(db->addr_res->start, iosize);
-
- if (db->io_addr == NULL) {
- dev_err(db->dev, "failed to ioremap address reg\n");
- ret = -EINVAL;
- goto out;
- }
+ iow(db, DM9000_RCR, rcr);
+ spin_unlock_irqrestore(&db->lock, flags);
+}
- iosize = res_size(db->data_res);
- db->data_req = request_mem_region(db->data_res->start, iosize,
- pdev->name);
+/*
+ * Initilize dm9000 board
+ */
+static void
+dm9000_init_dm9000(struct net_device *dev)
+{
+ board_info_t *db = dev->priv;
+ unsigned int imr;
- if (db->data_req == NULL) {
- dev_err(db->dev, "cannot claim data reg area\n");
- ret = -EIO;
- goto out;
- }
+ dm9000_dbg(db, 1, "entering %s\n", __func__);
- db->io_data = ioremap(db->data_res->start, iosize);
+ /* I/O mode */
+ db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */
- if (db->io_data == NULL) {
- dev_err(db->dev, "failed to ioremap data reg\n");
- ret = -EINVAL;
- goto out;
- }
+ /* GPIO0 on pre-activate PHY */
+ iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */
+ iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */
+ iow(db, DM9000_GPR, 0); /* Enable PHY */
- /* fill in parameters for net-dev structure */
- ndev->base_addr = (unsigned long)db->io_addr;
- ndev->irq = db->irq_res->start;
-
- /* ensure at least we have a default set of IO routines */
- dm9000_set_io(db, iosize);
-
- /* check to see if anything is being over-ridden */
- if (pdata != NULL) {
- /* check to see if the driver wants to over-ride the
- * default IO width */
-
- if (pdata->flags & DM9000_PLATF_8BITONLY)
- dm9000_set_io(db, 1);
-
- if (pdata->flags & DM9000_PLATF_16BITONLY)
- dm9000_set_io(db, 2);
-
- if (pdata->flags & DM9000_PLATF_32BITONLY)
- dm9000_set_io(db, 4);
-
- /* check to see if there are any IO routine
- * over-rides */
-
- if (pdata->inblk != NULL)
- db->inblk = pdata->inblk;
-
- if (pdata->outblk != NULL)
- db->outblk = pdata->outblk;
-
- if (pdata->dumpblk != NULL)
- db->dumpblk = pdata->dumpblk;
-
- db->flags = pdata->flags;
- }
-
- dm9000_reset(db);
-
- /* try multiple times, DM9000 sometimes gets the read wrong */
- for (i = 0; i < 8; i++) {
- id_val = ior(db, DM9000_VIDL);
- id_val |= (u32)ior(db, DM9000_VIDH) << 8;
- id_val |= (u32)ior(db, DM9000_PIDL) << 16;
- id_val |= (u32)ior(db, DM9000_PIDH) << 24;
-
- if (id_val == DM9000_ID)
- break;
- dev_err(db->dev, "read wrong id 0x%08x\n", id_val);
- }
-
- if (id_val != DM9000_ID) {
- dev_err(db->dev, "wrong id: 0x%08x\n", id_val);
- ret = -ENODEV;
- goto out;
- }
-
- /* Identify what type of DM9000 we are working on */
-
- id_val = ior(db, DM9000_CHIPR);
- dev_dbg(db->dev, "dm9000 revision 0x%02x\n", id_val);
-
- switch (id_val) {
- case CHIPR_DM9000A:
- db->type = TYPE_DM9000A;
- break;
- case CHIPR_DM9000B:
- db->type = TYPE_DM9000B;
- break;
- default:
- dev_dbg(db->dev, "ID %02x => defaulting to DM9000E\n", id_val);
- db->type = TYPE_DM9000E;
- }
-
- /* from this point we assume that we have found a DM9000 */
-
- /* driver system function */
- ether_setup(ndev);
-
- ndev->open = &dm9000_open;
- ndev->hard_start_xmit = &dm9000_start_xmit;
- ndev->tx_timeout = &dm9000_timeout;
- ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
- ndev->stop = &dm9000_stop;
- ndev->set_multicast_list = &dm9000_hash_table;
- ndev->ethtool_ops = &dm9000_ethtool_ops;
- ndev->do_ioctl = &dm9000_ioctl;
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
- ndev->poll_controller = &dm9000_poll_controller;
-#endif
-
- db->msg_enable = NETIF_MSG_LINK;
- db->mii.phy_id_mask = 0x1f;
- db->mii.reg_num_mask = 0x1f;
- db->mii.force_media = 0;
- db->mii.full_duplex = 0;
- db->mii.dev = ndev;
- db->mii.mdio_read = dm9000_phy_read;
- db->mii.mdio_write = dm9000_phy_write;
-
- mac_src = "eeprom";
-
- /* try reading the node address from the attached EEPROM */
- for (i = 0; i < 6; i += 2)
- dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
-
- if (!is_valid_ether_addr(ndev->dev_addr)) {
- /* try reading from mac */
-
- mac_src = "chip";
- for (i = 0; i < 6; i++)
- ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
- }
-
- if (!is_valid_ether_addr(ndev->dev_addr))
- dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
- "set using ifconfig\n", ndev->name);
-
- platform_set_drvdata(pdev, ndev);
- ret = register_netdev(ndev);
-
- if (ret == 0) {
- DECLARE_MAC_BUF(mac);
- printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %s (%s)\n",
- ndev->name, dm9000_type_to_char(db->type),
- db->io_addr, db->io_data, ndev->irq,
- print_mac(mac, ndev->dev_addr), mac_src);
- }
- return 0;
-
-out:
- dev_err(db->dev, "not found (%d).\n", ret);
-
- dm9000_release_board(pdev, db);
- free_netdev(ndev);
-
- return ret;
-}
-
-/*
- * Open the interface.
- * The interface is opened whenever "ifconfig" actives it.
- */
-static int
-dm9000_open(struct net_device *dev)
-{
- board_info_t *db = dev->priv;
- unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
-
- if (netif_msg_ifup(db))
- dev_dbg(db->dev, "enabling %s\n", dev->name);
-
- /* If there is no IRQ type specified, default to something that
- * may work, and tell the user that this is a problem */
-
- if (irqflags == IRQF_TRIGGER_NONE) {
- dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
- irqflags = DEFAULT_TRIGGER;
- }
-
- irqflags |= IRQF_SHARED;
-
- if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
- return -EAGAIN;
-
- /* Initialize DM9000 board */
- dm9000_reset(db);
- dm9000_init_dm9000(dev);
-
- /* Init driver variable */
- db->dbug_cnt = 0;
-
- mii_check_media(&db->mii, netif_msg_link(db), 1);
- netif_start_queue(dev);
-
- dm9000_schedule_poll(db);
-
- return 0;
-}
-
-/*
- * Initilize dm9000 board
- */
-static void
-dm9000_init_dm9000(struct net_device *dev)
-{
- board_info_t *db = dev->priv;
- unsigned int imr;
-
- dm9000_dbg(db, 1, "entering %s\n", __func__);
-
- /* I/O mode */
- db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */
-
- /* GPIO0 on pre-activate PHY */
- iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */
- iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */
- iow(db, DM9000_GPR, 0); /* Enable PHY */
-
- if (db->flags & DM9000_PLATF_EXT_PHY)
- iow(db, DM9000_NCR, NCR_EXT_PHY);
+ if (db->flags & DM9000_PLATF_EXT_PHY)
+ iow(db, DM9000_NCR, NCR_EXT_PHY);
/* Program operating register */
iow(db, DM9000_TCR, 0); /* TX Polling clear */
@@ -843,6 +690,29 @@ dm9000_init_dm9000(struct net_device *de
dev->trans_start = 0;
}
+/* Our watchdog timed out. Called by the networking layer */
+static void dm9000_timeout(struct net_device *dev)
+{
+ board_info_t *db = (board_info_t *) dev->priv;
+ u8 reg_save;
+ unsigned long flags;
+
+ /* Save previous register address */
+ reg_save = readb(db->io_addr);
+ spin_lock_irqsave(&db->lock, flags);
+
+ netif_stop_queue(dev);
+ dm9000_reset(db);
+ dm9000_init_dm9000(dev);
+ /* We can accept TX packets again */
+ dev->trans_start = jiffies;
+ netif_wake_queue(dev);
+
+ /* Restore previous register address */
+ writeb(reg_save, db->io_addr);
+ spin_unlock_irqrestore(&db->lock, flags);
+}
+
/*
* Hardware start transmission.
* Send a packet to media from the upper layer.
@@ -891,60 +761,22 @@ dm9000_start_xmit(struct sk_buff *skb, s
return 0;
}
-static void
-dm9000_shutdown(struct net_device *dev)
-{
- board_info_t *db = dev->priv;
-
- /* RESET device */
- dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
- iow(db, DM9000_GPR, 0x01); /* Power-Down PHY */
- iow(db, DM9000_IMR, IMR_PAR); /* Disable all interrupt */
- iow(db, DM9000_RCR, 0x00); /* Disable RX */
-}
-
/*
- * Stop the interface.
- * The interface is stopped when it is brought.
+ * DM9000 interrupt handler
+ * receive the packet to upper layer, free the transmitted packet
*/
-static int
-dm9000_stop(struct net_device *ndev)
-{
- board_info_t *db = ndev->priv;
- if (netif_msg_ifdown(db))
- dev_dbg(db->dev, "shutting down %s\n", ndev->name);
-
- cancel_delayed_work_sync(&db->phy_poll);
+static void dm9000_tx_done(struct net_device *dev, board_info_t *db)
+{
+ int tx_status = ior(db, DM9000_NSR); /* Got TX status */
- netif_stop_queue(ndev);
- netif_carrier_off(ndev);
+ if (tx_status & (NSR_TX2END | NSR_TX1END)) {
+ /* One packet sent complete */
+ db->tx_pkt_cnt--;
+ dev->stats.tx_packets++;
- /* free interrupt */
- free_irq(ndev->irq, ndev);
-
- dm9000_shutdown(ndev);
-
- return 0;
-}
-
-/*
- * DM9000 interrupt handler
- * receive the packet to upper layer, free the transmitted packet
- */
-
-static void
-dm9000_tx_done(struct net_device *dev, board_info_t * db)
-{
- int tx_status = ior(db, DM9000_NSR); /* Got TX status */
-
- if (tx_status & (NSR_TX2END | NSR_TX1END)) {
- /* One packet sent complete */
- db->tx_pkt_cnt--;
- dev->stats.tx_packets++;
-
- if (netif_msg_tx_done(db))
- dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status);
+ if (netif_msg_tx_done(db))
+ dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status);
/* Queue packet check & send */
if (db->tx_pkt_cnt > 0) {
@@ -957,59 +789,6 @@ dm9000_tx_done(struct net_device *dev, b
}
}
-static irqreturn_t
-dm9000_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- board_info_t *db = dev->priv;
- int int_status;
- u8 reg_save;
-
- dm9000_dbg(db, 3, "entering %s\n", __func__);
-
- /* A real interrupt coming */
-
- spin_lock(&db->lock);
-
- /* Save previous register address */
- reg_save = readb(db->io_addr);
-
- /* Disable all interrupts */
- iow(db, DM9000_IMR, IMR_PAR);
-
- /* Got DM9000 interrupt status */
- int_status = ior(db, DM9000_ISR); /* Got ISR */
- iow(db, DM9000_ISR, int_status); /* Clear ISR status */
-
- if (netif_msg_intr(db))
- dev_dbg(db->dev, "interrupt status %02x\n", int_status);
-
- /* Received the coming packet */
- if (int_status & ISR_PRS)
- dm9000_rx(dev);
-
- /* Trnasmit Interrupt check */
- if (int_status & ISR_PTS)
- dm9000_tx_done(dev, db);
-
- if (db->type != TYPE_DM9000E) {
- if (int_status & ISR_LNKCHNG) {
- /* fire a link-change request */
- schedule_delayed_work(&db->phy_poll, 1);
- }
- }
-
- /* Re-enable interrupt mask */
- iow(db, DM9000_IMR, db->imr_all);
-
- /* Restore previous register address */
- writeb(reg_save, db->io_addr);
-
- spin_unlock(&db->lock);
-
- return IRQ_HANDLED;
-}
-
struct dm9000_rxhdr {
u8 RxPktReady;
u8 RxStatus;
@@ -1113,210 +892,148 @@ dm9000_rx(struct net_device *dev)
} while (rxbyte == DM9000_PKT_RDY);
}
-static unsigned int
-dm9000_read_locked(board_info_t *db, int reg)
+static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
{
- unsigned long flags;
- unsigned int ret;
+ struct net_device *dev = dev_id;
+ board_info_t *db = dev->priv;
+ int int_status;
+ u8 reg_save;
- spin_lock_irqsave(&db->lock, flags);
- ret = ior(db, reg);
- spin_unlock_irqrestore(&db->lock, flags);
+ dm9000_dbg(db, 3, "entering %s\n", __func__);
- return ret;
-}
+ /* A real interrupt coming */
-static int dm9000_wait_eeprom(board_info_t *db)
-{
- unsigned int status;
- int timeout = 8; /* wait max 8msec */
+ spin_lock(&db->lock);
- /* The DM9000 data sheets say we should be able to
- * poll the ERRE bit in EPCR to wait for the EEPROM
- * operation. From testing several chips, this bit
- * does not seem to work.
- *
- * We attempt to use the bit, but fall back to the
- * timeout (which is why we do not return an error
- * on expiry) to say that the EEPROM operation has
- * completed.
- */
+ /* Save previous register address */
+ reg_save = readb(db->io_addr);
- while (1) {
- status = dm9000_read_locked(db, DM9000_EPCR);
+ /* Disable all interrupts */
+ iow(db, DM9000_IMR, IMR_PAR);
- if ((status & EPCR_ERRE) == 0)
- break;
+ /* Got DM9000 interrupt status */
+ int_status = ior(db, DM9000_ISR); /* Got ISR */
+ iow(db, DM9000_ISR, int_status); /* Clear ISR status */
- if (timeout-- < 0) {
- dev_dbg(db->dev, "timeout waiting EEPROM\n");
- break;
+ if (netif_msg_intr(db))
+ dev_dbg(db->dev, "interrupt status %02x\n", int_status);
+
+ /* Received the coming packet */
+ if (int_status & ISR_PRS)
+ dm9000_rx(dev);
+
+ /* Trnasmit Interrupt check */
+ if (int_status & ISR_PTS)
+ dm9000_tx_done(dev, db);
+
+ if (db->type != TYPE_DM9000E) {
+ if (int_status & ISR_LNKCHNG) {
+ /* fire a link-change request */
+ schedule_delayed_work(&db->phy_poll, 1);
}
}
- return 0;
+ /* Re-enable interrupt mask */
+ iow(db, DM9000_IMR, db->imr_all);
+
+ /* Restore previous register address */
+ writeb(reg_save, db->io_addr);
+
+ spin_unlock(&db->lock);
+
+ return IRQ_HANDLED;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
/*
- * Read a word data from EEPROM
+ *Used by netconsole
*/
-static void
-dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
+static void dm9000_poll_controller(struct net_device *dev)
{
- unsigned long flags;
-
- if (db->flags & DM9000_PLATF_NO_EEPROM) {
- to[0] = 0xff;
- to[1] = 0xff;
- return;
- }
-
- mutex_lock(&db->addr_lock);
+ disable_irq(dev->irq);
+ dm9000_interrupt(dev->irq, dev);
+ enable_irq(dev->irq);
+}
+#endif
- spin_lock_irqsave(&db->lock, flags);
+/*
+ * Open the interface.
+ * The interface is opened whenever "ifconfig" actives it.
+ */
+static int
+dm9000_open(struct net_device *dev)
+{
+ board_info_t *db = dev->priv;
+ unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
- iow(db, DM9000_EPAR, offset);
- iow(db, DM9000_EPCR, EPCR_ERPRR);
+ if (netif_msg_ifup(db))
+ dev_dbg(db->dev, "enabling %s\n", dev->name);
- spin_unlock_irqrestore(&db->lock, flags);
+ /* If there is no IRQ type specified, default to something that
+ * may work, and tell the user that this is a problem */
- dm9000_wait_eeprom(db);
+ if (irqflags == IRQF_TRIGGER_NONE) {
+ dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
+ irqflags = DEFAULT_TRIGGER;
+ }
+
+ irqflags |= IRQF_SHARED;
- /* delay for at-least 150uS */
- msleep(1);
+ if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
+ return -EAGAIN;
- spin_lock_irqsave(&db->lock, flags);
+ /* Initialize DM9000 board */
+ dm9000_reset(db);
+ dm9000_init_dm9000(dev);
- iow(db, DM9000_EPCR, 0x0);
+ /* Init driver variable */
+ db->dbug_cnt = 0;
- to[0] = ior(db, DM9000_EPDRL);
- to[1] = ior(db, DM9000_EPDRH);
+ mii_check_media(&db->mii, netif_msg_link(db), 1);
+ netif_start_queue(dev);
+
+ dm9000_schedule_poll(db);
- spin_unlock_irqrestore(&db->lock, flags);
+ return 0;
+}
- mutex_unlock(&db->addr_lock);
+/*
+ * Sleep, either by using msleep() or if we are suspending, then
+ * use mdelay() to sleep.
+ */
+static void dm9000_msleep(board_info_t *db, unsigned int ms)
+{
+ if (db->in_suspend)
+ mdelay(ms);
+ else
+ msleep(ms);
}
/*
- * Write a word data to SROM
+ * Read a word from phyxcer
*/
-static void
-dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
+static int
+dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
{
+ board_info_t *db = (board_info_t *) dev->priv;
unsigned long flags;
-
- if (db->flags & DM9000_PLATF_NO_EEPROM)
- return;
+ unsigned int reg_save;
+ int ret;
mutex_lock(&db->addr_lock);
- spin_lock_irqsave(&db->lock, flags);
- iow(db, DM9000_EPAR, offset);
- iow(db, DM9000_EPDRH, data[1]);
- iow(db, DM9000_EPDRL, data[0]);
- iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
- spin_unlock_irqrestore(&db->lock, flags);
+ spin_lock_irqsave(&db->lock,flags);
- dm9000_wait_eeprom(db);
+ /* Save previous register address */
+ reg_save = readb(db->io_addr);
- mdelay(1); /* wait at least 150uS to clear */
+ /* Fill the phyxcer register into REG_0C */
+ iow(db, DM9000_EPAR, DM9000_PHY | reg);
- spin_lock_irqsave(&db->lock, flags);
- iow(db, DM9000_EPCR, 0);
- spin_unlock_irqrestore(&db->lock, flags);
+ iow(db, DM9000_EPCR, 0xc); /* Issue phyxcer read command */
- mutex_unlock(&db->addr_lock);
-}
-
-/*
- * Set DM9000 multicast address
- */
-static void
-dm9000_hash_table(struct net_device *dev)
-{
- board_info_t *db = (board_info_t *) dev->priv;
- struct dev_mc_list *mcptr = dev->mc_list;
- int mc_cnt = dev->mc_count;
- int i, oft;
- u32 hash_val;
- u16 hash_table[4];
- u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN;
- unsigned long flags;
-
- dm9000_dbg(db, 1, "entering %s\n", __func__);
-
- spin_lock_irqsave(&db->lock, flags);
-
- for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
- iow(db, oft, dev->dev_addr[i]);
-
- /* Clear Hash Table */
- for (i = 0; i < 4; i++)
- hash_table[i] = 0x0;
-
- /* broadcast address */
- hash_table[3] = 0x8000;
-
- if (dev->flags & IFF_PROMISC)
- rcr |= RCR_PRMSC;
-
- if (dev->flags & IFF_ALLMULTI)
- rcr |= RCR_ALL;
-
- /* the multicast address in Hash Table : 64 bits */
- for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
- hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f;
- hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
- }
-
- /* Write the hash table to MAC MD table */
- for (i = 0, oft = DM9000_MAR; i < 4; i++) {
- iow(db, oft++, hash_table[i]);
- iow(db, oft++, hash_table[i] >> 8);
- }
-
- iow(db, DM9000_RCR, rcr);
- spin_unlock_irqrestore(&db->lock, flags);
-}
-
-
-/*
- * Sleep, either by using msleep() or if we are suspending, then
- * use mdelay() to sleep.
- */
-static void dm9000_msleep(board_info_t *db, unsigned int ms)
-{
- if (db->in_suspend)
- mdelay(ms);
- else
- msleep(ms);
-}
-
-/*
- * Read a word from phyxcer
- */
-static int
-dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
-{
- board_info_t *db = (board_info_t *) dev->priv;
- unsigned long flags;
- unsigned int reg_save;
- int ret;
-
- mutex_lock(&db->addr_lock);
-
- spin_lock_irqsave(&db->lock,flags);
-
- /* Save previous register address */
- reg_save = readb(db->io_addr);
-
- /* Fill the phyxcer register into REG_0C */
- iow(db, DM9000_EPAR, DM9000_PHY | reg);
-
- iow(db, DM9000_EPCR, 0xc); /* Issue phyxcer read command */
-
- writeb(reg_save, db->io_addr);
- spin_unlock_irqrestore(&db->lock,flags);
+ writeb(reg_save, db->io_addr);
+ spin_unlock_irqrestore(&db->lock,flags);
dm9000_msleep(db, 1); /* Wait read complete */
@@ -1383,6 +1100,269 @@ dm9000_phy_write(struct net_device *dev,
mutex_unlock(&db->addr_lock);
}
+static void
+dm9000_shutdown(struct net_device *dev)
+{
+ board_info_t *db = dev->priv;
+
+ /* RESET device */
+ dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
+ iow(db, DM9000_GPR, 0x01); /* Power-Down PHY */
+ iow(db, DM9000_IMR, IMR_PAR); /* Disable all interrupt */
+ iow(db, DM9000_RCR, 0x00); /* Disable RX */
+}
+
+/*
+ * Stop the interface.
+ * The interface is stopped when it is brought.
+ */
+static int
+dm9000_stop(struct net_device *ndev)
+{
+ board_info_t *db = ndev->priv;
+
+ if (netif_msg_ifdown(db))
+ dev_dbg(db->dev, "shutting down %s\n", ndev->name);
+
+ cancel_delayed_work_sync(&db->phy_poll);
+
+ netif_stop_queue(ndev);
+ netif_carrier_off(ndev);
+
+ /* free interrupt */
+ free_irq(ndev->irq, ndev);
+
+ dm9000_shutdown(ndev);
+
+ return 0;
+}
+
+#define res_size(_r) (((_r)->end - (_r)->start) + 1)
+
+/*
+ * Search DM9000 board, allocate space and register it
+ */
+static int __devinit
+dm9000_probe(struct platform_device *pdev)
+{
+ struct dm9000_plat_data *pdata = pdev->dev.platform_data;
+ struct board_info *db; /* Point a board information structure */
+ struct net_device *ndev;
+ const unsigned char *mac_src;
+ int ret = 0;
+ int iosize;
+ int i;
+ u32 id_val;
+
+ /* Init network device */
+ ndev = alloc_etherdev(sizeof(struct board_info));
+ if (!ndev) {
+ dev_err(&pdev->dev, "could not allocate device.\n");
+ return -ENOMEM;
+ }
+
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ dev_dbg(&pdev->dev, "dm9000_probe()\n");
+
+ /* setup board info structure */
+ db = ndev->priv;
+ memset(db, 0, sizeof(*db));
+
+ db->dev = &pdev->dev;
+ db->ndev = ndev;
+
+ spin_lock_init(&db->lock);
+ mutex_init(&db->addr_lock);
+
+ INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);
+
+ db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+ if (db->addr_res == NULL || db->data_res == NULL ||
+ db->irq_res == NULL) {
+ dev_err(db->dev, "insufficient resources\n");
+ ret = -ENOENT;
+ goto out;
+ }
+
+ iosize = res_size(db->addr_res);
+ db->addr_req = request_mem_region(db->addr_res->start, iosize,
+ pdev->name);
+
+ if (db->addr_req == NULL) {
+ dev_err(db->dev, "cannot claim address reg area\n");
+ ret = -EIO;
+ goto out;
+ }
+
+ db->io_addr = ioremap(db->addr_res->start, iosize);
+
+ if (db->io_addr == NULL) {
+ dev_err(db->dev, "failed to ioremap address reg\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ iosize = res_size(db->data_res);
+ db->data_req = request_mem_region(db->data_res->start, iosize,
+ pdev->name);
+
+ if (db->data_req == NULL) {
+ dev_err(db->dev, "cannot claim data reg area\n");
+ ret = -EIO;
+ goto out;
+ }
+
+ db->io_data = ioremap(db->data_res->start, iosize);
+
+ if (db->io_data == NULL) {
+ dev_err(db->dev, "failed to ioremap data reg\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* fill in parameters for net-dev structure */
+ ndev->base_addr = (unsigned long)db->io_addr;
+ ndev->irq = db->irq_res->start;
+
+ /* ensure at least we have a default set of IO routines */
+ dm9000_set_io(db, iosize);
+
+ /* check to see if anything is being over-ridden */
+ if (pdata != NULL) {
+ /* check to see if the driver wants to over-ride the
+ * default IO width */
+
+ if (pdata->flags & DM9000_PLATF_8BITONLY)
+ dm9000_set_io(db, 1);
+
+ if (pdata->flags & DM9000_PLATF_16BITONLY)
+ dm9000_set_io(db, 2);
+
+ if (pdata->flags & DM9000_PLATF_32BITONLY)
+ dm9000_set_io(db, 4);
+
+ /* check to see if there are any IO routine
+ * over-rides */
+
+ if (pdata->inblk != NULL)
+ db->inblk = pdata->inblk;
+
+ if (pdata->outblk != NULL)
+ db->outblk = pdata->outblk;
+
+ if (pdata->dumpblk != NULL)
+ db->dumpblk = pdata->dumpblk;
+
+ db->flags = pdata->flags;
+ }
+
+ dm9000_reset(db);
+
+ /* try multiple times, DM9000 sometimes gets the read wrong */
+ for (i = 0; i < 8; i++) {
+ id_val = ior(db, DM9000_VIDL);
+ id_val |= (u32)ior(db, DM9000_VIDH) << 8;
+ id_val |= (u32)ior(db, DM9000_PIDL) << 16;
+ id_val |= (u32)ior(db, DM9000_PIDH) << 24;
+
+ if (id_val == DM9000_ID)
+ break;
+ dev_err(db->dev, "read wrong id 0x%08x\n", id_val);
+ }
+
+ if (id_val != DM9000_ID) {
+ dev_err(db->dev, "wrong id: 0x%08x\n", id_val);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ /* Identify what type of DM9000 we are working on */
+
+ id_val = ior(db, DM9000_CHIPR);
+ dev_dbg(db->dev, "dm9000 revision 0x%02x\n", id_val);
+
+ switch (id_val) {
+ case CHIPR_DM9000A:
+ db->type = TYPE_DM9000A;
+ break;
+ case CHIPR_DM9000B:
+ db->type = TYPE_DM9000B;
+ break;
+ default:
+ dev_dbg(db->dev, "ID %02x => defaulting to DM9000E\n", id_val);
+ db->type = TYPE_DM9000E;
+ }
+
+ /* from this point we assume that we have found a DM9000 */
+
+ /* driver system function */
+ ether_setup(ndev);
+
+ ndev->open = &dm9000_open;
+ ndev->hard_start_xmit = &dm9000_start_xmit;
+ ndev->tx_timeout = &dm9000_timeout;
+ ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
+ ndev->stop = &dm9000_stop;
+ ndev->set_multicast_list = &dm9000_hash_table;
+ ndev->ethtool_ops = &dm9000_ethtool_ops;
+ ndev->do_ioctl = &dm9000_ioctl;
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ ndev->poll_controller = &dm9000_poll_controller;
+#endif
+
+ db->msg_enable = NETIF_MSG_LINK;
+ db->mii.phy_id_mask = 0x1f;
+ db->mii.reg_num_mask = 0x1f;
+ db->mii.force_media = 0;
+ db->mii.full_duplex = 0;
+ db->mii.dev = ndev;
+ db->mii.mdio_read = dm9000_phy_read;
+ db->mii.mdio_write = dm9000_phy_write;
+
+ mac_src = "eeprom";
+
+ /* try reading the node address from the attached EEPROM */
+ for (i = 0; i < 6; i += 2)
+ dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
+
+ if (!is_valid_ether_addr(ndev->dev_addr)) {
+ /* try reading from mac */
+
+ mac_src = "chip";
+ for (i = 0; i < 6; i++)
+ ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
+ }
+
+ if (!is_valid_ether_addr(ndev->dev_addr))
+ dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
+ "set using ifconfig\n", ndev->name);
+
+ platform_set_drvdata(pdev, ndev);
+ ret = register_netdev(ndev);
+
+ if (ret == 0) {
+ DECLARE_MAC_BUF(mac);
+ printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %s (%s)\n",
+ ndev->name, dm9000_type_to_char(db->type),
+ db->io_addr, db->io_data, ndev->irq,
+ print_mac(mac, ndev->dev_addr), mac_src);
+ }
+ return 0;
+
+out:
+ dev_err(db->dev, "not found (%d).\n", ret);
+
+ dm9000_release_board(pdev, db);
+ free_netdev(ndev);
+
+ return ret;
+}
+
static int
dm9000_drv_suspend(struct platform_device *dev, pm_message_t state)
{
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 15+ messages in thread
* [patch v3 07/12] DM9000: Use NSR to determine link-status on internal PHY
2008-06-24 21:15 [patch v3 00/12] DM9000 for next kernel release Ben Dooks
` (5 preceding siblings ...)
2008-06-24 21:16 ` [patch v3 06/12] DM9000: Cleanup source code - remove forward declerations Ben Dooks
@ 2008-06-24 21:16 ` Ben Dooks
2008-06-24 21:16 ` [patch v3 08/12] DM9000: Allow the use of the NSR register to get link status Ben Dooks
` (4 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Ben Dooks @ 2008-06-24 21:16 UTC (permalink / raw)
To: netdev; +Cc: jeff, laurentp, Ben Dooks
[-- Attachment #1: simtec/simtec-drivers-net-dm9000-linkstatus1.patch --]
[-- Type: text/plain, Size: 1055 bytes --]
The DM9000_NSR register contains a copy of the internal PHY's
link status which we can use to determine if the link is up
or down. This eliminates the more costly (and sleeping) PHY
read when using the DM9000's own PHY.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Index: linux-2.6.26-rc6-quilt1/drivers/net/dm9000.c
===================================================================
--- linux-2.6.26-rc6-quilt1.orig/drivers/net/dm9000.c 2008-06-15 23:31:41.000000000 +0100
+++ linux-2.6.26-rc6-quilt1/drivers/net/dm9000.c 2008-06-15 23:38:55.000000000 +0100
@@ -473,7 +473,14 @@ static int dm9000_nway_reset(struct net_
static u32 dm9000_get_link(struct net_device *dev)
{
board_info_t *dm = to_dm9000_board(dev);
- return mii_link_ok(&dm->mii);
+ u32 ret;
+
+ if (dm->flags & DM9000_PLATF_EXT_PHY)
+ ret = mii_link_ok(&dm->mii);
+ else
+ ret = dm9000_read_locked(dm, DM9000_NSR) & NSR_LINKST ? 1 : 0;
+
+ return ret;
}
#define DM_EEPROM_MAGIC (0x444D394B)
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 15+ messages in thread
* [patch v3 08/12] DM9000: Allow the use of the NSR register to get link status.
2008-06-24 21:15 [patch v3 00/12] DM9000 for next kernel release Ben Dooks
` (6 preceding siblings ...)
2008-06-24 21:16 ` [patch v3 07/12] DM9000: Use NSR to determine link-status on internal PHY Ben Dooks
@ 2008-06-24 21:16 ` Ben Dooks
2008-06-24 21:16 ` [patch v3 09/12] DM9000: Add missing msleep() in EEPROM wait code Ben Dooks
` (3 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Ben Dooks @ 2008-06-24 21:16 UTC (permalink / raw)
To: netdev; +Cc: jeff, laurentp, Ben Dooks
[-- Attachment #1: simtec/simtec-drivers-net-dm9000-linkstatus2.patch --]
[-- Type: text/plain, Size: 4024 bytes --]
The DM9000's internal PHY reports a copy of the link status
in the NSR register of the chip. Reading the status when
polling for link status is faster as it eliminates the need
to sleep, but does not print as much information.
Add an platform flag to force this behaviour, and a Kconfig
option to allow it to be forced to the faster method always.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Index: linux-2.6.26-rc7-next20080624/drivers/net/Kconfig
===================================================================
--- linux-2.6.26-rc7-next20080624.orig/drivers/net/Kconfig 2008-06-24 22:09:38.000000000 +0100
+++ linux-2.6.26-rc7-next20080624/drivers/net/Kconfig 2008-06-24 22:09:39.000000000 +0100
@@ -938,6 +938,15 @@ config DM9000
To compile this driver as a module, choose M here. The module
will be called dm9000.
+config DM9000_FORCE_SIMPLE_PHY_POLL
+ bool "Force simple NSR based PHY polling"
+ depends on DM9000
+ ---help---
+ This configuration forces the DM9000 to use the NSR's LinkStatus
+ bit to determine if the link is up or down instead of the more
+ costly MII PHY reads. Note, this will not work if the chip is
+ operating with an external PHY.
+
config ENC28J60
tristate "ENC28J60 support"
depends on EXPERIMENTAL && SPI && NET_ETHERNET
Index: linux-2.6.26-rc7-next20080624/drivers/net/dm9000.c
===================================================================
--- linux-2.6.26-rc7-next20080624.orig/drivers/net/dm9000.c 2008-06-24 22:09:38.000000000 +0100
+++ linux-2.6.26-rc7-next20080624/drivers/net/dm9000.c 2008-06-24 22:09:39.000000000 +0100
@@ -552,15 +552,48 @@ static const struct ethtool_ops dm9000_e
.set_eeprom = dm9000_set_eeprom,
};
+static void dm9000_show_carrier(board_info_t *db,
+ unsigned carrier, unsigned nsr)
+{
+ struct net_device *ndev = db->ndev;
+ unsigned ncr = dm9000_read_locked(db, DM9000_NCR);
+
+ if (carrier)
+ dev_info(db->dev, "%s: link up, %dMbps, %s-duplex, no LPA\n",
+ ndev->name, (nsr & NSR_SPEED) ? 10 : 100,
+ (ncr & NCR_FDX) ? "full" : "half");
+ else
+ dev_info(db->dev, "%s: link down\n", ndev->name);
+}
+
static void
dm9000_poll_work(struct work_struct *w)
{
struct delayed_work *dw = container_of(w, struct delayed_work, work);
board_info_t *db = container_of(dw, board_info_t, phy_poll);
+ struct net_device *ndev = db->ndev;
- mii_check_media(&db->mii, netif_msg_link(db), 0);
+ if (db->flags & DM9000_PLATF_SIMPLE_PHY &&
+ !(db->flags & DM9000_PLATF_EXT_PHY)) {
+ unsigned nsr = dm9000_read_locked(db, DM9000_NSR);
+ unsigned old_carrier = netif_carrier_ok(ndev) ? 1 : 0;
+ unsigned new_carrier;
+
+ new_carrier = (nsr & NSR_LINKST) ? 1 : 0;
+
+ if (old_carrier != new_carrier) {
+ if (netif_msg_link(db))
+ dm9000_show_carrier(db, new_carrier, nsr);
+
+ if (!new_carrier)
+ netif_carrier_off(ndev);
+ else
+ netif_carrier_on(ndev);
+ }
+ } else
+ mii_check_media(&db->mii, netif_msg_link(db), 0);
- if (netif_running(db->ndev))
+ if (netif_running(ndev))
dm9000_schedule_poll(db);
}
@@ -1267,6 +1300,10 @@ dm9000_probe(struct platform_device *pde
db->flags = pdata->flags;
}
+#ifdef CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL
+ db->flags |= DM9000_PLATF_SIMPLE_PHY;
+#endif
+
dm9000_reset(db);
/* try multiple times, DM9000 sometimes gets the read wrong */
Index: linux-2.6.26-rc7-next20080624/include/linux/dm9000.h
===================================================================
--- linux-2.6.26-rc7-next20080624.orig/include/linux/dm9000.h 2008-06-24 22:09:38.000000000 +0100
+++ linux-2.6.26-rc7-next20080624/include/linux/dm9000.h 2008-06-24 22:09:39.000000000 +0100
@@ -21,6 +21,7 @@
#define DM9000_PLATF_32BITONLY (0x0004)
#define DM9000_PLATF_EXT_PHY (0x0008)
#define DM9000_PLATF_NO_EEPROM (0x0010)
+#define DM9000_PLATF_SIMPLE_PHY (0x0020) /* Use NSR to find LinkStatus */
/* platfrom data for platfrom device structure's platfrom_data field */
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 15+ messages in thread
* [patch v3 09/12] DM9000: Add missing msleep() in EEPROM wait code.
2008-06-24 21:15 [patch v3 00/12] DM9000 for next kernel release Ben Dooks
` (7 preceding siblings ...)
2008-06-24 21:16 ` [patch v3 08/12] DM9000: Allow the use of the NSR register to get link status Ben Dooks
@ 2008-06-24 21:16 ` Ben Dooks
2008-06-24 21:16 ` [patch v3 10/12] DM9000: Re-unit menuconfig entries for DM9000 driver Ben Dooks
` (2 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Ben Dooks @ 2008-06-24 21:16 UTC (permalink / raw)
To: netdev; +Cc: jeff, laurentp, Ben Dooks
[-- Attachment #1: simtec/simtec-drivers-net-dm9000-eeprom-delay.patch --]
[-- Type: text/plain, Size: 729 bytes --]
The msleep() call in the code that checks for the
EEPROM controller's busy status was missing.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Index: linux-2.6.26-rc6-quilt1/drivers/net/dm9000.c
===================================================================
--- linux-2.6.26-rc6-quilt1.orig/drivers/net/dm9000.c 2008-06-16 00:07:15.000000000 +0100
+++ linux-2.6.26-rc6-quilt1/drivers/net/dm9000.c 2008-06-16 00:07:44.000000000 +0100
@@ -343,6 +343,8 @@ static int dm9000_wait_eeprom(board_info
if ((status & EPCR_ERRE) == 0)
break;
+ msleep(1);
+
if (timeout-- < 0) {
dev_dbg(db->dev, "timeout waiting EEPROM\n");
break;
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 15+ messages in thread
* [patch v3 10/12] DM9000: Re-unit menuconfig entries for DM9000 driver
2008-06-24 21:15 [patch v3 00/12] DM9000 for next kernel release Ben Dooks
` (8 preceding siblings ...)
2008-06-24 21:16 ` [patch v3 09/12] DM9000: Add missing msleep() in EEPROM wait code Ben Dooks
@ 2008-06-24 21:16 ` Ben Dooks
2008-06-24 21:16 ` [patch v3 11/12] DM9000: Remove DEFAULT_TRIGGER for request_irq() flags Ben Dooks
2008-06-24 21:16 ` [patch v3 12/12] DM9000: Add documentation for the driver Ben Dooks
11 siblings, 0 replies; 15+ messages in thread
From: Ben Dooks @ 2008-06-24 21:16 UTC (permalink / raw)
To: netdev; +Cc: jeff, laurentp, Ben Dooks
[-- Attachment #1: simtec/simtec-drivers-net-dm9000-menuconfig.patch --]
[-- Type: text/plain, Size: 1363 bytes --]
The ENC28J60 driver ended up adding itself inbetween the
two DM9000 Kconfig entries, so re-unite the two together.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Index: linux-2.6.26-rc7-next20080620/drivers/net/Kconfig
===================================================================
--- linux-2.6.26-rc7-next20080620.orig/drivers/net/Kconfig 2008-06-22 21:12:24.000000000 +0100
+++ linux-2.6.26-rc7-next20080620/drivers/net/Kconfig 2008-06-22 21:12:34.000000000 +0100
@@ -938,6 +938,14 @@ config DM9000
To compile this driver as a module, choose M here. The module
will be called dm9000.
+config DM9000_DEBUGLEVEL
+ int "DM9000 maximum debug level"
+ depends on DM9000
+ default 4
+ help
+ The maximum level of debugging code compiled into the DM9000
+ driver.
+
config DM9000_FORCE_SIMPLE_PHY_POLL
bool "Force simple NSR based PHY polling"
depends on DM9000
@@ -964,14 +972,6 @@ config ENC28J60_WRITEVERIFY
Enable the verify after the buffer write useful for debugging purpose.
If unsure, say N.
-config DM9000_DEBUGLEVEL
- int "DM9000 maximum debug level"
- depends on DM9000
- default 4
- help
- The maximum level of debugging code compiled into the DM9000
- driver.
-
config SMC911X
tristate "SMSC LAN911[5678] support"
select CRC32
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 15+ messages in thread
* [patch v3 11/12] DM9000: Remove DEFAULT_TRIGGER for request_irq() flags.
2008-06-24 21:15 [patch v3 00/12] DM9000 for next kernel release Ben Dooks
` (9 preceding siblings ...)
2008-06-24 21:16 ` [patch v3 10/12] DM9000: Re-unit menuconfig entries for DM9000 driver Ben Dooks
@ 2008-06-24 21:16 ` Ben Dooks
2008-06-24 21:16 ` [patch v3 12/12] DM9000: Add documentation for the driver Ben Dooks
11 siblings, 0 replies; 15+ messages in thread
From: Ben Dooks @ 2008-06-24 21:16 UTC (permalink / raw)
To: netdev; +Cc: jeff, laurentp, Ben Dooks
[-- Attachment #1: simtec/simtec-drivers-net-dm9000-remove-default-trigger.patch --]
[-- Type: text/plain, Size: 1356 bytes --]
Currently all but one user (AT91SAM9261EK) of the dm9000
driver passes their IRQ flags through the resources attached
to the platform device. This means we can remove the use
of DEFAULT_TRIGGER as the blackfin machines all seem to
have their triggers set properly.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Index: linux-2.6.26-rc7-next20080624/drivers/net/dm9000.c
===================================================================
--- linux-2.6.26-rc7-next20080624.orig/drivers/net/dm9000.c 2008-06-24 22:09:43.000000000 +0100
+++ linux-2.6.26-rc7-next20080624/drivers/net/dm9000.c 2008-06-24 22:09:44.000000000 +0100
@@ -54,9 +54,6 @@
#define writesb outsb
#define writesw outsw
#define writesl outsl
-#define DEFAULT_TRIGGER IRQF_TRIGGER_HIGH
-#else
-#define DEFAULT_TRIGGER (0)
#endif
/*
@@ -1014,11 +1011,9 @@ dm9000_open(struct net_device *dev)
/* If there is no IRQ type specified, default to something that
* may work, and tell the user that this is a problem */
- if (irqflags == IRQF_TRIGGER_NONE) {
+ if (irqflags == IRQF_TRIGGER_NONE)
dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
- irqflags = DEFAULT_TRIGGER;
- }
-
+
irqflags |= IRQF_SHARED;
if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 15+ messages in thread
* [patch v3 12/12] DM9000: Add documentation for the driver.
2008-06-24 21:15 [patch v3 00/12] DM9000 for next kernel release Ben Dooks
` (10 preceding siblings ...)
2008-06-24 21:16 ` [patch v3 11/12] DM9000: Remove DEFAULT_TRIGGER for request_irq() flags Ben Dooks
@ 2008-06-24 21:16 ` Ben Dooks
11 siblings, 0 replies; 15+ messages in thread
From: Ben Dooks @ 2008-06-24 21:16 UTC (permalink / raw)
To: netdev; +Cc: jeff, laurentp, Ben Dooks
[-- Attachment #1: simtec/simtec-drivers-net-dm9000-add-documentation.patch --]
[-- Type: text/plain, Size: 5820 bytes --]
Add Documentation/networking/dm9000.txt for the DM9000
network driver.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Index: linux-2.6.26-rc7-next20080620/Documentation/networking/dm9000.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.26-rc7-next20080620/Documentation/networking/dm9000.txt 2008-06-24 17:23:55.000000000 +0100
@@ -0,0 +1,167 @@
+DM9000 Network driver
+=====================
+
+Copyright 2008 Simtec Electronics,
+ Ben Dooks <ben@simtec.co.uk> <ben-linux@fluff.org>
+
+
+Introduction
+------------
+
+This file describes how to use the DM9000 platform-device based network driver
+that is contained in the files drivers/net/dm9000.c and drivers/net/dm9000.h.
+
+The driver supports three DM9000 variants, the DM9000E which is the first chip
+supported as well as the newer DM9000A and DM9000B devices. It is currently
+maintained and tested by Ben Dooks, who should be CC: to any patches for this
+driver.
+
+
+Defining the platform device
+----------------------------
+
+The minimum set of resources attached to the platform device are as follows:
+
+ 1) The physical address of the address register
+ 2) The physical address of the data register
+ 3) The IRQ line the device's interrupt pin is connected to.
+
+These resources should be specified in that order, as the ordering of the
+two address regions is important (the driver expects these to be address
+and then data).
+
+An example from arch/arm/mach-s3c2410/mach-bast.c is:
+
+static struct resource bast_dm9k_resource[] = {
+ [0] = {
+ .start = S3C2410_CS5 + BAST_PA_DM9000,
+ .end = S3C2410_CS5 + BAST_PA_DM9000 + 3,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = S3C2410_CS5 + BAST_PA_DM9000 + 0x40,
+ .end = S3C2410_CS5 + BAST_PA_DM9000 + 0x40 + 0x3f,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_DM9000,
+ .end = IRQ_DM9000,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ }
+};
+
+static struct platform_device bast_device_dm9k = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bast_dm9k_resource),
+ .resource = bast_dm9k_resource,
+};
+
+Note the setting of the IRQ trigger flag in bast_dm9k_resource[2].flags,
+as this will generate a warning if it is not present. The trigger from
+the flags field will be passed to request_irq() when registering the IRQ
+handler to ensure that the IRQ is setup correctly.
+
+This shows a typical platform device, without the optional configuration
+platform data supplied. The next example uses the same resources, but adds
+the optional platform data to pass extra configuration data:
+
+static struct dm9000_plat_data bast_dm9k_platdata = {
+ .flags = DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device bast_device_dm9k = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bast_dm9k_resource),
+ .resource = bast_dm9k_resource,
+ .dev = {
+ .platform_data = &bast_dm9k_platdata,
+ }
+};
+
+The platform data is defined in include/linux/dm9000.h and described below.
+
+
+Platform data
+-------------
+
+Extra platform data for the DM9000 can describe the IO bus width to the
+device, whether or not an external PHY is attached to the device and
+the availability of an external configuration EEPROM.
+
+The flags for the platform data .flags field are as follows:
+
+DM9000_PLATF_8BITONLY
+
+ The IO should be done with 8bit operations.
+
+DM9000_PLATF_16BITONLY
+
+ The IO should be done with 16bit operations.
+
+DM9000_PLATF_32BITONLY
+
+ The IO should be done with 32bit operations.
+
+DM9000_PLATF_EXT_PHY
+
+ The chip is connected to an external PHY.
+
+DM9000_PLATF_NO_EEPROM
+
+ This can be used to signify that the board does not have an
+ EEPROM, or that the EEPROM should be hidden from the user.
+
+DM9000_PLATF_SIMPLE_PHY
+
+ Switch to using the simpler PHY polling method which does not
+ try and read the MII PHY state regularly. This is only available
+ when using the internal PHY. See the section on link state polling
+ for more information.
+
+ The config symbol DM9000_FORCE_SIMPLE_PHY_POLL, Kconfig entry
+ "Force simple NSR based PHY polling" allows this flag to be
+ forced on at build time.
+
+
+PHY Link state polling
+----------------------
+
+The driver keeps track of the link state and informs the network core
+about link (carrier) availablilty. This is managed by several methods
+depending on the version of the chip and on which PHY is being used.
+
+For the internal PHY, the original (and currently default) method is
+to read the MII state, either when the status changes if we have the
+necessary interrupt support in the chip or every two seconds via a
+periodic timer.
+
+To reduce the overhead for the internal PHY, there is now the option
+of using the DM9000_FORCE_SIMPLE_PHY_POLL config, or DM9000_PLATF_SIMPLE_PHY
+platform data option to read the summary information without the
+expensive MII accesses. This method is faster, but does not print
+as much information.
+
+When using an external PHY, the driver currently has to poll the MII
+link status as there is no method for getting an interrupt on link change.
+
+
+DM9000A / DM9000B
+-----------------
+
+These chips are functionally similar to the DM9000E and are supported easily
+by the same driver. The features are:
+
+ 1) Interrupt on internal PHY state change. This means that the periodic
+ polling of the PHY status may be disabled on these devices when using
+ the internal PHY.
+
+ 2) TCP/UDP checksum offloading, which the driver does not currently support.
+
+
+ethtool
+-------
+
+The driver supports the ethtool interface for access to the driver
+state information, the PHY state and the EEPROM.
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [patch v3 01/12] DM9000: Remove the 2 resources probe scheme.
2008-06-24 21:15 ` [patch v3 01/12] DM9000: Remove the 2 resources probe scheme Ben Dooks
@ 2008-06-25 3:06 ` Jeff Garzik
2008-06-26 12:42 ` Ben Dooks
0 siblings, 1 reply; 15+ messages in thread
From: Jeff Garzik @ 2008-06-25 3:06 UTC (permalink / raw)
To: Ben Dooks; +Cc: netdev, laurentp
Ben Dooks wrote:
> From: Laurent Pinchart <laurentp@cse-semaphore.com>
>
> The dm9000 driver accepts either 2 or 3 resources to describe the platform
> devices. The 2 resources case abuses the ioresource mechanism by passing
> ioremap()ed memory through the platform device resources. This patch removes
> that case and converts boards that were using it to the 3 resources scheme.
>
> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
> Signed-off-by: Laurent Pinchart <laurentp@cse-semaphore.com>
applied 1-12
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [patch v3 01/12] DM9000: Remove the 2 resources probe scheme.
2008-06-25 3:06 ` Jeff Garzik
@ 2008-06-26 12:42 ` Ben Dooks
0 siblings, 0 replies; 15+ messages in thread
From: Ben Dooks @ 2008-06-26 12:42 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Ben Dooks, netdev, laurentp
On Tue, Jun 24, 2008 at 11:06:37PM -0400, Jeff Garzik wrote:
> Ben Dooks wrote:
>> From: Laurent Pinchart <laurentp@cse-semaphore.com>
>>
>> The dm9000 driver accepts either 2 or 3 resources to describe the platform
>> devices. The 2 resources case abuses the ioresource mechanism by passing
>> ioremap()ed memory through the platform device resources. This patch removes
>> that case and converts boards that were using it to the 3 resources scheme.
>>
>> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
>> Signed-off-by: Laurent Pinchart <laurentp@cse-semaphore.com>
>
> applied 1-12
Great, thankyou.
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2008-06-26 12:42 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-24 21:15 [patch v3 00/12] DM9000 for next kernel release Ben Dooks
2008-06-24 21:15 ` [patch v3 01/12] DM9000: Remove the 2 resources probe scheme Ben Dooks
2008-06-25 3:06 ` Jeff Garzik
2008-06-26 12:42 ` Ben Dooks
2008-06-24 21:15 ` [patch v3 02/12] DM9000: Fixup blackfin after removing 2 resource usage Ben Dooks
2008-06-24 21:15 ` [patch v3 03/12] DM9000: Add support for DM9000A and DM9000B chips Ben Dooks
2008-06-24 21:16 ` [patch v3 04/12] DM9000: Cleanups after the resource changes Ben Dooks
2008-06-24 21:16 ` [patch v3 05/12] DM9000: Cleanup source code Ben Dooks
2008-06-24 21:16 ` [patch v3 06/12] DM9000: Cleanup source code - remove forward declerations Ben Dooks
2008-06-24 21:16 ` [patch v3 07/12] DM9000: Use NSR to determine link-status on internal PHY Ben Dooks
2008-06-24 21:16 ` [patch v3 08/12] DM9000: Allow the use of the NSR register to get link status Ben Dooks
2008-06-24 21:16 ` [patch v3 09/12] DM9000: Add missing msleep() in EEPROM wait code Ben Dooks
2008-06-24 21:16 ` [patch v3 10/12] DM9000: Re-unit menuconfig entries for DM9000 driver Ben Dooks
2008-06-24 21:16 ` [patch v3 11/12] DM9000: Remove DEFAULT_TRIGGER for request_irq() flags Ben Dooks
2008-06-24 21:16 ` [patch v3 12/12] DM9000: Add documentation for the driver Ben Dooks
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).