From 9c1692cf037fa4c3ac2f137caa22428705a3c9e3 Mon Sep 17 00:00:00 2001
From: Kenneth R Westerback <krw@cvs.openbsd.org>
Date: Mon, 7 Mar 2005 13:31:41 +0000
Subject: Enable basic big-endian operation. i.e. now works on some big-endian
 machines (macppc) but not others (sparc64). No-op for little-endian
 architectures.

Diff from NetBSD with tweaks by drahn@.

ok brad@
---
 sys/dev/pci/if_bge.c    | 42 ++++++++++++++++--------------------
 sys/dev/pci/if_bgereg.h | 57 +++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 66 insertions(+), 33 deletions(-)

(limited to 'sys/dev/pci')

diff --git a/sys/dev/pci/if_bge.c b/sys/dev/pci/if_bge.c
index 88a673467d4..4c1afbdc1bb 100644
--- a/sys/dev/pci/if_bge.c
+++ b/sys/dev/pci/if_bge.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: if_bge.c,v 1.52 2005/03/04 00:55:44 krw Exp $	*/
+/*	$OpenBSD: if_bge.c,v 1.53 2005/03/07 13:31:40 krw Exp $	*/
 /*
  * Copyright (c) 2001 Wind River Systems
  * Copyright (c) 1997, 1998, 1999, 2001
@@ -1006,13 +1006,8 @@ bge_chipinit(sc)
 #endif
 
 	/* Set endianness before we access any non-PCI registers. */
-#if BYTE_ORDER == BIG_ENDIAN
 	pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL,
-	    BGE_BIGENDIAN_INIT);
-#else
-	pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL,
-	    BGE_LITTLEENDIAN_INIT);
-#endif
+	    BGE_INIT);
 
 	/*
 	 * Check the 'ROM failed' bit on the RX CPU to see if
@@ -1093,13 +1088,11 @@ bge_chipinit(sc)
 	 * Set up general mode register.
 	 */
 #ifndef BGE_CHECKSUM
-	CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_MODECTL_WORDSWAP_NONFRAME|
-		    BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA|
+	CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS|
 		    BGE_MODECTL_MAC_ATTN_INTR|BGE_MODECTL_HOST_SEND_BDS|
 		    BGE_MODECTL_TX_NO_PHDR_CSUM|BGE_MODECTL_RX_NO_PHDR_CSUM);
 #else
-	CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_MODECTL_WORDSWAP_NONFRAME|
-		    BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA|
+	CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS|
 		    BGE_MODECTL_MAC_ATTN_INTR|BGE_MODECTL_HOST_SEND_BDS);
 #endif
 
@@ -1135,6 +1128,8 @@ bge_blockinit(sc)
 	struct ifnet		*ifp = &sc->arpcom.ac_if;
 	vaddr_t			rcb_addr;
 	int			i;
+	bge_hostaddr		taddr;
+
 
 	/*
 	 * Initialize the memory window pointer register so that
@@ -1303,9 +1298,9 @@ bge_blockinit(sc)
 
 	/* Configure TX RCB 0 (we use only the first ring) */
 	rcb_addr = BGE_MEMWIN_START + BGE_SEND_RING_RCB;
-	RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, 0);
-	RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo,
-		    BGE_RING_DMA_ADDR(sc, bge_tx_ring));
+	BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_tx_ring));
+	RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
+	RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
 	RCB_WRITE_4(sc, rcb_addr, bge_nicaddr,
 		    BGE_NIC_TXRING_ADDR(0, BGE_TX_RING_CNT));
 	if ((sc->bge_quirks & BGE_QUIRK_5705_CORE) == 0)
@@ -1338,9 +1333,9 @@ bge_blockinit(sc)
 	 * nicaddr field in the RCB isn't used.
 	 */
 	rcb_addr = BGE_MEMWIN_START + BGE_RX_RETURN_RING_RCB;
-	RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, 0);
-	RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo,
-		    BGE_RING_DMA_ADDR(sc, bge_rx_return_ring));
+	BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_rx_return_ring));
+	RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
+	RCB_WRITE_4(sc, rcb_addr, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
 	RCB_WRITE_4(sc, rcb_addr, bge_nicaddr, 0x00000000);
 	RCB_WRITE_4(sc, rcb_addr, bge_maxlen_flags,
 	    BGE_RCB_MAXLEN_FLAGS(sc->bge_return_ring_cnt, 0));
@@ -1411,9 +1406,9 @@ bge_blockinit(sc)
 	}
 
 	/* Set up address of status block */
-	CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_ADDR_HI, 0);
-	CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_ADDR_LO,
-		    BGE_RING_DMA_ADDR(sc, bge_status_block));
+	BGE_HOSTADDR(taddr, BGE_RING_DMA_ADDR(sc, bge_status_block));
+	CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_ADDR_HI, taddr.bge_addr_hi);
+	CSR_WRITE_4(sc, BGE_HCC_STATUSBLK_ADDR_LO, taddr.bge_addr_lo);
 
 	sc->bge_rdata->bge_status_block.bge_idx[0].bge_rx_prod_idx = 0;
 	sc->bge_rdata->bge_status_block.bge_idx[0].bge_tx_cons_idx = 0;
@@ -2063,7 +2058,7 @@ bge_reset(sc)
 
 	pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL,
 	    BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR|
-	    BGE_PCIMISCCTL_ENDIAN_WORDSWAP|BGE_PCIMISCCTL_PCISTATE_RW);
+	    BGE_HIF_SWAP_OPTIONS|BGE_PCIMISCCTL_PCISTATE_RW);
 
 	reset = BGE_MISCCFG_RESET_CORE_CLOCKS|(65<<1);
 
@@ -2099,7 +2094,7 @@ bge_reset(sc)
 	/* Reset some of the PCI state that got zapped by reset */
 	pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL,
 	    BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR|
-	    BGE_PCIMISCCTL_ENDIAN_WORDSWAP|BGE_PCIMISCCTL_PCISTATE_RW);
+	    BGE_HIF_SWAP_OPTIONS|BGE_PCIMISCCTL_PCISTATE_RW);
 	pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_CACHESZ, cachesize);
 	pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD, command);
 	bge_writereg_ind(sc, BGE_MISC_CFG, (65 << 1));
@@ -2156,8 +2151,7 @@ bge_reset(sc)
 	}
 
 	/* Fix up byte swapping */
-	CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_MODECTL_BYTESWAP_NONFRAME|
-	    BGE_MODECTL_BYTESWAP_DATA);
+	CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS);
 
 	CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
 
diff --git a/sys/dev/pci/if_bgereg.h b/sys/dev/pci/if_bgereg.h
index 5da661f5a06..2e525283cc4 100644
--- a/sys/dev/pci/if_bgereg.h
+++ b/sys/dev/pci/if_bgereg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bgereg.h,v 1.19 2005/03/04 00:55:44 krw Exp $ */
+/* $OpenBSD: if_bgereg.h,v 1.20 2005/03/07 13:31:40 krw Exp $ */
 /*
  * Copyright (c) 2001 Wind River Systems
  * Copyright (c) 1997, 1998, 1999, 2001
@@ -208,14 +208,20 @@
 #define BGE_PCIMISCCTL_INDIRECT_ACCESS	0x00000080
 #define BGE_PCIMISCCTL_ASICREV		0xFFFF0000
 
-#define BGE_BIGENDIAN_INIT						\
-	(BGE_PCIMISCCTL_ENDIAN_BYTESWAP|				\
-	BGE_PCIMISCCTL_ENDIAN_WORDSWAP|BGE_PCIMISCCTL_CLEAR_INTA|	\
-	BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR)
+#define BGE_HIF_SWAP_OPTIONS	(BGE_PCIMISCCTL_ENDIAN_WORDSWAP)
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define BGE_DMA_SWAP_OPTIONS \
+	BGE_MODECTL_WORDSWAP_NONFRAME| \
+	BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA
+#else
+#define BGE_DMA_SWAP_OPTIONS \
+	BGE_MODECTL_WORDSWAP_NONFRAME|BGE_MODECTL_BYTESWAP_NONFRAME| \
+	BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA
+#endif
 
-#define BGE_LITTLEENDIAN_INIT						\
-	(BGE_PCIMISCCTL_CLEAR_INTA|BGE_PCIMISCCTL_MASK_PCI_INTR|	\
-	BGE_PCIMISCCTL_ENDIAN_WORDSWAP|BGE_PCIMISCCTL_INDIRECT_ACCESS)
+#define BGE_INIT \
+	(BGE_HIF_SWAP_OPTIONS|BGE_PCIMISCCTL_CLEAR_INTA| \
+	 BGE_PCIMISCCTL_MASK_PCI_INTR|BGE_PCIMISCCTL_INDIRECT_ACCESS)
 
 #define BGE_CHIPID_TIGON_I		0x40000000
 #define BGE_CHIPID_TIGON_II		0x60000000
@@ -1758,7 +1764,10 @@ typedef struct {
 #define BGE_HOSTADDR(x,y)						\
 	do {								\
 		(x).bge_addr_lo = ((u_int64_t) (y) & 0xffffffff);	\
-		(x).bge_addr_hi = ((u_int64_t) (y) >> 32);		\
+		if (sizeof(bus_addr_t) == 8)				\
+			(x).bge_addr_hi = ((u_int64_t) (y) >> 32);	\
+		else							\
+			(x).bge_addr_hi = 0;				\
 	} while(0)
 
 /* Ring control block structure */
@@ -1783,10 +1792,17 @@ struct bge_rcb {
 
 struct bge_tx_bd {
 	bge_hostaddr		bge_addr;
+#if BYTE_ORDER == LITTLE_ENDIAN
 	u_int16_t		bge_flags;
 	u_int16_t		bge_len;
 	u_int16_t		bge_vlan_tag;
 	u_int16_t		bge_rsvd;
+#else
+	u_int16_t		bge_len;
+	u_int16_t		bge_flags;
+	u_int16_t		bge_rsvd;
+	u_int16_t		bge_vlan_tag;
+#endif
 };
 
 #define BGE_TXBDFLAG_TCP_UDP_CSUM	0x0001
@@ -1808,6 +1824,7 @@ struct bge_tx_bd {
 
 struct bge_rx_bd {
 	bge_hostaddr		bge_addr;
+#if BYTE_ORDER == LITTLE_ENDIAN
 	u_int16_t		bge_len;
 	u_int16_t		bge_idx;
 	u_int16_t		bge_flags;
@@ -1816,6 +1833,16 @@ struct bge_rx_bd {
 	u_int16_t		bge_ip_csum;
 	u_int16_t		bge_vlan_tag;
 	u_int16_t		bge_error_flag;
+#else
+	u_int16_t		bge_idx;
+	u_int16_t		bge_len;
+	u_int16_t		bge_type;
+	u_int16_t		bge_flags;
+	u_int16_t		bge_ip_csum;
+	u_int16_t		bge_tcp_udp_csum;
+	u_int16_t		bge_error_flag;
+	u_int16_t		bge_vlan_tag;
+#endif
 	u_int32_t		bge_rsvd;
 	u_int32_t		bge_opaque;
 };
@@ -1839,17 +1866,29 @@ struct bge_rx_bd {
 #define BGE_RXERRFLAG_GIANT		0x0080
 
 struct bge_sts_idx {
+#if BYTE_ORDER == LITTLE_ENDIAN
 	u_int16_t		bge_rx_prod_idx;
 	u_int16_t		bge_tx_cons_idx;
+#else
+	u_int16_t		bge_tx_cons_idx;
+	u_int16_t		bge_rx_prod_idx;
+#endif
 };
 
 struct bge_status_block {
 	u_int32_t		bge_status;
 	u_int32_t		bge_rsvd0;
+#if BYTE_ORDER == LITTLE_ENDIAN
 	u_int16_t		bge_rx_jumbo_cons_idx;
 	u_int16_t		bge_rx_std_cons_idx;
 	u_int16_t		bge_rx_mini_cons_idx;
 	u_int16_t		bge_rsvd1;
+#else
+	u_int16_t		bge_rx_std_cons_idx;
+	u_int16_t		bge_rx_jumbo_cons_idx;
+	u_int16_t		bge_rsvd1;
+	u_int16_t		bge_rx_mini_cons_idx;
+#endif
 	struct bge_sts_idx	bge_idx[16];
 };
 
-- 
cgit v1.2.3