From 8a189f1288b654e45f2ec9393abfb1390b261ae9 Mon Sep 17 00:00:00 2001
From: "Maciej W. Rozycki" <macro@linux-mips.org>
Date: Thu, 25 Sep 2014 11:06:39 +0100
Subject: [PATCH 1/3] defxx: Correct DEFEA's ESIC port I/O accesses

Reverse the order of arguments to `outb', data to write comes first.

Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/fddi/defxx.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c
index c44eaf019dea..6068db874281 100644
--- a/drivers/net/fddi/defxx.c
+++ b/drivers/net/fddi/defxx.c
@@ -719,28 +719,28 @@ static void dfx_bus_init(struct net_device *dev)
 
 		/* Set the decode range of the board.  */
 		val = ((bp->base.port >> 12) << PI_IO_CMP_V_SLOT);
-		outb(base_addr + PI_ESIC_K_IO_ADD_CMP_0_1, val);
-		outb(base_addr + PI_ESIC_K_IO_ADD_CMP_0_0, 0);
-		outb(base_addr + PI_ESIC_K_IO_ADD_CMP_1_1, val);
-		outb(base_addr + PI_ESIC_K_IO_ADD_CMP_1_0, 0);
+		outb(val, base_addr + PI_ESIC_K_IO_ADD_CMP_0_1);
+		outb(0, base_addr + PI_ESIC_K_IO_ADD_CMP_0_0);
+		outb(val, base_addr + PI_ESIC_K_IO_ADD_CMP_1_1);
+		outb(0, base_addr + PI_ESIC_K_IO_ADD_CMP_1_0);
 		val = PI_ESIC_K_CSR_IO_LEN - 1;
-		outb(base_addr + PI_ESIC_K_IO_ADD_MASK_0_1, (val >> 8) & 0xff);
-		outb(base_addr + PI_ESIC_K_IO_ADD_MASK_0_0, val & 0xff);
-		outb(base_addr + PI_ESIC_K_IO_ADD_MASK_1_1, (val >> 8) & 0xff);
-		outb(base_addr + PI_ESIC_K_IO_ADD_MASK_1_0, val & 0xff);
+		outb(val, base_addr + PI_ESIC_K_IO_ADD_MASK_0_1);
+		outb(0, base_addr + PI_ESIC_K_IO_ADD_MASK_0_0);
+		outb(val, base_addr + PI_ESIC_K_IO_ADD_MASK_1_1);
+		outb(0, base_addr + PI_ESIC_K_IO_ADD_MASK_1_0);
 
 		/* Enable the decoders.  */
 		val = PI_FUNCTION_CNTRL_M_IOCS1 | PI_FUNCTION_CNTRL_M_IOCS0;
 		if (dfx_use_mmio)
 			val |= PI_FUNCTION_CNTRL_M_MEMCS0;
-		outb(base_addr + PI_ESIC_K_FUNCTION_CNTRL, val);
+		outb(val, base_addr + PI_ESIC_K_FUNCTION_CNTRL);
 
 		/*
 		 * Enable access to the rest of the module
 		 * (including PDQ and packet memory).
 		 */
 		val = PI_SLOT_CNTRL_M_ENB;
-		outb(base_addr + PI_ESIC_K_SLOT_CNTRL, val);
+		outb(val, base_addr + PI_ESIC_K_SLOT_CNTRL);
 
 		/*
 		 * Map PDQ registers into memory or port space.  This is
@@ -751,12 +751,12 @@ static void dfx_bus_init(struct net_device *dev)
 			val |= PI_BURST_HOLDOFF_V_MEM_MAP;
 		else
 			val &= ~PI_BURST_HOLDOFF_V_MEM_MAP;
-		outb(base_addr + PI_DEFEA_K_BURST_HOLDOFF, val);
+		outb(val, base_addr + PI_DEFEA_K_BURST_HOLDOFF);
 
 		/* Enable interrupts at EISA bus interface chip (ESIC) */
 		val = inb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0);
 		val |= PI_CONFIG_STAT_0_M_INT_ENB;
-		outb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0, val);
+		outb(val, base_addr + PI_ESIC_K_IO_CONFIG_STAT_0);
 	}
 	if (dfx_bus_pci) {
 		struct pci_dev *pdev = to_pci_dev(bdev);
@@ -825,7 +825,7 @@ static void dfx_bus_uninit(struct net_device *dev)
 		/* Disable interrupts at EISA bus interface chip (ESIC) */
 		val = inb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0);
 		val &= ~PI_CONFIG_STAT_0_M_INT_ENB;
-		outb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0, val);
+		outb(val, base_addr + PI_ESIC_K_IO_CONFIG_STAT_0);
 	}
 	if (dfx_bus_pci) {
 		/* Disable interrupts at PCI bus interface chip (PFI) */
@@ -1917,7 +1917,7 @@ static irqreturn_t dfx_interrupt(int irq, void *dev_id)
 
 		/* Disable interrupts at the ESIC */
 		status &= ~PI_CONFIG_STAT_0_M_INT_ENB;
-		outb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0, status);
+		outb(status, base_addr + PI_ESIC_K_IO_CONFIG_STAT_0);
 
 		/* Call interrupt service routine for this adapter */
 		dfx_int_common(dev);
@@ -1925,7 +1925,7 @@ static irqreturn_t dfx_interrupt(int irq, void *dev_id)
 		/* Reenable interrupts at the ESIC */
 		status = inb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0);
 		status |= PI_CONFIG_STAT_0_M_INT_ENB;
-		outb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0, status);
+		outb(status, base_addr + PI_ESIC_K_IO_CONFIG_STAT_0);
 
 		spin_unlock(&bp->lock);
 	}

From b1a6d3ecf806457d3e76ac0044db424be3c9422d Mon Sep 17 00:00:00 2001
From: "Maciej W. Rozycki" <macro@linux-mips.org>
Date: Thu, 25 Sep 2014 11:06:45 +0100
Subject: [PATCH 2/3] defxx: DEFEA's Burst Holdoff register initialization fix

Use the mask rather than bit number macro to initialize the chip select
control bit for PDQ register space decoding in the Burst Holdoff register.

Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/fddi/defxx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c
index 6068db874281..15a18fbe30cf 100644
--- a/drivers/net/fddi/defxx.c
+++ b/drivers/net/fddi/defxx.c
@@ -748,9 +748,9 @@ static void dfx_bus_init(struct net_device *dev)
 		 */
 		val = inb(base_addr + PI_DEFEA_K_BURST_HOLDOFF);
 		if (dfx_use_mmio)
-			val |= PI_BURST_HOLDOFF_V_MEM_MAP;
+			val |= PI_BURST_HOLDOFF_M_MEM_MAP;
 		else
-			val &= ~PI_BURST_HOLDOFF_V_MEM_MAP;
+			val &= ~PI_BURST_HOLDOFF_M_MEM_MAP;
 		outb(val, base_addr + PI_DEFEA_K_BURST_HOLDOFF);
 
 		/* Enable interrupts at EISA bus interface chip (ESIC) */

From b98dfaf2b0a3e72fa5967dafb4f246442584a780 Mon Sep 17 00:00:00 2001
From: "Maciej W. Rozycki" <macro@linux-mips.org>
Date: Thu, 25 Sep 2014 11:06:55 +0100
Subject: [PATCH 3/3] defxx: DEFEA's ESIC port I/O decoding cleanup

Use the slot-specific I/O range for decoding accesses to PDQ ASIC
registers (IOCS0) and the discrete Burst Holdoff register (IOCS1) as per
the "HD64981F EISA Slave Interface Controller (ESIC)" datasheet.  Use
disjoint decode ranges now that the assignment of chip selects is known.
Update the span of the port I/O resource requested accordingly.

Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/fddi/defxx.c | 40 ++++++++++++++++++++++++++--------------
 drivers/net/fddi/defxx.h | 12 ++++++------
 2 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c
index 15a18fbe30cf..caed6eee289c 100644
--- a/drivers/net/fddi/defxx.c
+++ b/drivers/net/fddi/defxx.c
@@ -466,7 +466,8 @@ static void dfx_get_bars(struct device *bdev,
 			*bar_len = (bar | PI_MEM_ADD_MASK_M) + 1;
 		} else {
 			*bar_start = base_addr;
-			*bar_len = PI_ESIC_K_CSR_IO_LEN;
+			*bar_len = PI_ESIC_K_CSR_IO_LEN +
+				   PI_ESIC_K_BURST_HOLDOFF_LEN;
 		}
 	}
 	if (dfx_bus_tc) {
@@ -683,6 +684,9 @@ static void dfx_bus_init(struct net_device *dev)
 	if (dfx_bus_eisa) {
 		unsigned long base_addr = to_eisa_device(bdev)->base_addr;
 
+		/* Disable the board before fiddling with the decoders.  */
+		outb(0, base_addr + PI_ESIC_K_SLOT_CNTRL);
+
 		/* Get the interrupt level from the ESIC chip.  */
 		val = inb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0);
 		val &= PI_CONFIG_STAT_0_M_IRQ;
@@ -709,25 +713,33 @@ static void dfx_bus_init(struct net_device *dev)
 		/*
 		 * Enable memory decoding (MEMCS0) and/or port decoding
 		 * (IOCS1/IOCS0) as appropriate in Function Control
-		 * Register.  One of the port chip selects seems to be
-		 * used for the Burst Holdoff register, but this bit of
-		 * documentation is missing and as yet it has not been
-		 * determined which of the two.  This is also the reason
-		 * the size of the decoded port range is twice as large
-		 * as one required by the PDQ.
+		 * Register.  IOCS0 is used for PDQ registers, taking 16
+		 * 32-bit words, while IOCS1 is used for the Burst Holdoff
+		 * register, taking a single 32-bit word only.  We use the
+		 * slot-specific I/O range as per the ESIC spec, that is
+		 * set bits 15:12 in the mask registers to mask them out.
 		 */
 
 		/* Set the decode range of the board.  */
-		val = ((bp->base.port >> 12) << PI_IO_CMP_V_SLOT);
+		val = 0;
 		outb(val, base_addr + PI_ESIC_K_IO_ADD_CMP_0_1);
-		outb(0, base_addr + PI_ESIC_K_IO_ADD_CMP_0_0);
-		outb(val, base_addr + PI_ESIC_K_IO_ADD_CMP_1_1);
-		outb(0, base_addr + PI_ESIC_K_IO_ADD_CMP_1_0);
-		val = PI_ESIC_K_CSR_IO_LEN - 1;
+		val = PI_DEFEA_K_CSR_IO;
+		outb(val, base_addr + PI_ESIC_K_IO_ADD_CMP_0_0);
+
+		val = PI_IO_CMP_M_SLOT;
 		outb(val, base_addr + PI_ESIC_K_IO_ADD_MASK_0_1);
-		outb(0, base_addr + PI_ESIC_K_IO_ADD_MASK_0_0);
+		val = (PI_ESIC_K_CSR_IO_LEN - 1) & ~3;
+		outb(val, base_addr + PI_ESIC_K_IO_ADD_MASK_0_0);
+
+		val = 0;
+		outb(val, base_addr + PI_ESIC_K_IO_ADD_CMP_1_1);
+		val = PI_DEFEA_K_BURST_HOLDOFF;
+		outb(val, base_addr + PI_ESIC_K_IO_ADD_CMP_1_0);
+
+		val = PI_IO_CMP_M_SLOT;
 		outb(val, base_addr + PI_ESIC_K_IO_ADD_MASK_1_1);
-		outb(0, base_addr + PI_ESIC_K_IO_ADD_MASK_1_0);
+		val = (PI_ESIC_K_BURST_HOLDOFF_LEN - 1) & ~3;
+		outb(val, base_addr + PI_ESIC_K_IO_ADD_MASK_1_0);
 
 		/* Enable the decoders.  */
 		val = PI_FUNCTION_CNTRL_M_IOCS1 | PI_FUNCTION_CNTRL_M_IOCS0;
diff --git a/drivers/net/fddi/defxx.h b/drivers/net/fddi/defxx.h
index adb63f3f7b4a..9527f0182fd4 100644
--- a/drivers/net/fddi/defxx.h
+++ b/drivers/net/fddi/defxx.h
@@ -1479,8 +1479,10 @@ typedef union
 
 /* Define EISA controller register offsets */
 
-#define PI_ESIC_K_CSR_IO_LEN		0x80		/* 128 bytes */
+#define PI_ESIC_K_CSR_IO_LEN		0x40		/* 64 bytes */
+#define PI_ESIC_K_BURST_HOLDOFF_LEN	0x04		/* 4 bytes */
 
+#define PI_DEFEA_K_CSR_IO		0x000
 #define PI_DEFEA_K_BURST_HOLDOFF	0x040
 
 #define PI_ESIC_K_SLOT_ID            	0xC80
@@ -1558,11 +1560,9 @@ typedef union
 
 #define PI_MEM_ADD_MASK_M		0x3ff
 
-/*
- * Define the fields in the IO Compare registers.
- * The driver must initialize the slot field with the slot ID shifted by the
- * amount shown below.
- */
+/* Define the fields in the I/O Address Compare and Mask registers.  */
+
+#define PI_IO_CMP_M_SLOT		0xf0
 
 #define PI_IO_CMP_V_SLOT		4