Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Feb 2002 13:36:02 -0800
From:      Brooks Davis <brooks@one-eyed-alien.net>
To:        mobile@freebsd.org
Subject:   Linksys WMP11 support
Message-ID:  <20020205133602.A6294@Odin.AC.HMC.Edu>

next in thread | raw e-mail | index | archive | help

--SUOF0GtieIMvvwua
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

I plan to commit the following patch to current shortly.  It's support
for the Linksys WMP11 PCI wireless adaptor (it's actually a MiniPCI card
in a PCI-MiniPCI adaptor.)  Please test/review.

The work was done by Thomas Skibo <skibo@pacbell.net>.

-- Brooks

Index: if_wi.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/cvs/src/sys/dev/wi/if_wi.c,v
retrieving revision 1.71
diff -u -r1.71 if_wi.c
--- if_wi.c	21 Jan 2002 00:59:59 -0000	1.71
+++ if_wi.c	4 Feb 2002 19:35:10 -0000
@@ -223,11 +223,13 @@
=20
 static struct {
 	unsigned int vendor,device;
+	int bus_type;
 	char *desc;
 } pci_ids[] =3D {
-	{0x1638, 0x1100,	"PRISM2STA PCI WaveLAN/IEEE 802.11"},
-	{0x1385, 0x4100,	"Netgear MA301 PCI IEEE 802.11b"},
-	{0x16ab, 0x1102,	"Linksys WDT11 PCI IEEE 802.11b"},
+	{0x1638, 0x1100, WI_BUS_PCI_PLX, "PRISM2STA PCI WaveLAN/IEEE 802.11"},
+	{0x1385, 0x4100, WI_BUS_PCI_PLX, "Netgear MA301 PCI IEEE 802.11b"},
+	{0x16ab, 0x1102, WI_BUS_PCI_PLX, "Linksys WDT11 PCI IEEE 802.11b"},
+	{0x1260, 0x3873, WI_BUS_PCI_NATIVE, "Linksys WMP11 PCI Prism2.5"},
 	{0,	 0,	NULL}
 };
 #endif
@@ -290,6 +292,7 @@
=20
 	sc =3D device_get_softc(dev);
 	sc->wi_gone =3D 0;
+	sc->wi_bus_type =3D WI_BUS_PCCARD;
=20
 	error =3D wi_alloc(dev, 0);
 	if (error)
@@ -317,6 +320,7 @@
 		if ((pci_get_vendor(dev) =3D=3D pci_ids[i].vendor) &&
 			(pci_get_device(dev) =3D=3D pci_ids[i].device)) {
 			sc->wi_prism2 =3D 1;
+			sc->wi_bus_type =3D pci_ids[i].bus_type;
 			device_set_desc(dev, pci_ids[i].desc);
 			return (0);
 		}
@@ -382,6 +386,7 @@
 	u_int32_t		command, wanted;
 	u_int16_t		reg;
 	int			error;
+	int			timeout;
=20
 	sc =3D device_get_softc(dev);
=20
@@ -395,47 +400,77 @@
 		return (ENXIO);
 	}
=20
-	error =3D wi_alloc(dev, WI_PCI_IORES);
-	if (error)
-		return (error);
+	if (sc->wi_bus_type !=3D WI_BUS_PCI_NATIVE) {
+		error =3D wi_alloc(dev, WI_PCI_IORES);
+		if (error)
+			return (error);
=20
-	/* Make sure interrupts are disabled. */
-	CSR_WRITE_2(sc, WI_INT_EN, 0);
-	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
+		/* Make sure interrupts are disabled. */
+		CSR_WRITE_2(sc, WI_INT_EN, 0);
+		CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
=20
-	/* We have to do a magic PLX poke to enable interrupts */
-	sc->local_rid =3D WI_PCI_LOCALRES;
-	sc->local =3D bus_alloc_resource(dev, SYS_RES_IOPORT,
-		&sc->local_rid, 0, ~0, 1, RF_ACTIVE);
-	sc->wi_localtag =3D rman_get_bustag(sc->local);
-	sc->wi_localhandle =3D rman_get_bushandle(sc->local);
-	command =3D bus_space_read_4(sc->wi_localtag, sc->wi_localhandle,
-		WI_LOCAL_INTCSR);
-	command |=3D WI_LOCAL_INTEN;
-	bus_space_write_4(sc->wi_localtag, sc->wi_localhandle,
-		WI_LOCAL_INTCSR, command);
-	bus_release_resource(dev, SYS_RES_IOPORT, sc->local_rid, sc->local);
-	sc->local =3D NULL;
-
-	sc->mem_rid =3D WI_PCI_MEMRES;
-	sc->mem =3D bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid,
-				0, ~0, 1, RF_ACTIVE);
-	if (sc->mem =3D=3D NULL) {
-		device_printf(dev, "couldn't allocate memory\n");
-		wi_free(dev);
-		return (ENXIO);
-	}
-	sc->wi_bmemtag =3D rman_get_bustag(sc->mem);
-	sc->wi_bmemhandle =3D rman_get_bushandle(sc->mem);
+		/* We have to do a magic PLX poke to enable interrupts */
+		sc->local_rid =3D WI_PCI_LOCALRES;
+		sc->local =3D bus_alloc_resource(dev, SYS_RES_IOPORT,
+		    &sc->local_rid, 0, ~0, 1, RF_ACTIVE);
+		sc->wi_localtag =3D rman_get_bustag(sc->local);
+		sc->wi_localhandle =3D rman_get_bushandle(sc->local);
+		command =3D bus_space_read_4(sc->wi_localtag, sc->wi_localhandle,
+		    WI_LOCAL_INTCSR);
+		command |=3D WI_LOCAL_INTEN;
+		bus_space_write_4(sc->wi_localtag, sc->wi_localhandle,
+		    WI_LOCAL_INTCSR, command);
+		bus_release_resource(dev, SYS_RES_IOPORT, sc->local_rid,
+		    sc->local);
+		sc->local =3D NULL;
+
+		sc->mem_rid =3D WI_PCI_MEMRES;
+		sc->mem =3D bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid,
+					0, ~0, 1, RF_ACTIVE);
+		if (sc->mem =3D=3D NULL) {
+			device_printf(dev, "couldn't allocate memory\n");
+			wi_free(dev);
+			return (ENXIO);
+		}
+		sc->wi_bmemtag =3D rman_get_bustag(sc->mem);
+		sc->wi_bmemhandle =3D rman_get_bushandle(sc->mem);
=20
-	/*
-	 * From Linux driver:
-	 * Write COR to enable PC card
-	 * This is a subset of the protocol that the pccard bus code
-	 * would do.
-	 */
-	CSM_WRITE_1(sc, WI_COR_OFFSET, WI_COR_VALUE);=20
-	reg =3D CSM_READ_1(sc, WI_COR_OFFSET);
+		/*
+		 * From Linux driver:
+		 * Write COR to enable PC card
+		 * This is a subset of the protocol that the pccard bus code
+		 * would do.
+		 */
+		CSM_WRITE_1(sc, WI_COR_OFFSET, WI_COR_VALUE);=20
+		reg =3D CSM_READ_1(sc, WI_COR_OFFSET);
+		if (reg !=3D WI_COR_VALUE) {
+			device_printf(dev, "CSM_READ_1(WI_COR_OFFSET) "
+			    "wanted %d, got %d\n", WI_COR_VALUE, reg);
+			wi_free(dev);
+			return (ENXIO);
+		}
+	} else {
+		error =3D wi_alloc(dev, WI_PCI_LMEMRES);
+		if (error)
+			return (error);
+
+		CSR_WRITE_2(sc, WI_HFA384X_PCICOR_OFF, 0x0080);
+		DELAY(250000);
+
+		CSR_WRITE_2(sc, WI_HFA384X_PCICOR_OFF, 0x0000);
+		DELAY(500000);
+
+		timeout=3D2000000;
+		while ((--timeout > 0) &&
+		    (CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY))
+			DELAY(10);
+
+		if (timeout =3D=3D 0) {
+			device_printf(dev, "couldn't reset prism2.5 core.\n");
+			wi_free(dev);
+			return(ENXIO);
+		}
+	}
=20
 	CSR_WRITE_2(sc, WI_HFA384X_SWSUPPORT0_OFF, WI_PRISM2STA_MAGIC);
 	reg =3D CSR_READ_2(sc, WI_HFA384X_SWSUPPORT0_OFF);
@@ -954,6 +989,7 @@
 		DELAY(10*1000);	/* 10 m sec */
 	}
 	if (i =3D=3D 0) {
+		device_printf(sc->dev, "wi_cmd: busy bit won't clear.\n" );
 		return(ETIMEDOUT);
 	}
=20
@@ -967,8 +1003,8 @@
 		 * Wait for 'command complete' bit to be
 		 * set in the event status register.
 		 */
-		s =3D CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD;
-		if (s) {
+		s =3D CSR_READ_2(sc, WI_EVENT_STAT);
+		if (s & WI_EV_CMD) {
 			/* Ack the event and read result code. */
 			s =3D CSR_READ_2(sc, WI_STATUS);
 			CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
@@ -980,12 +1016,14 @@
 				return(EIO);
 			break;
 		}
-		if (cmd =3D=3D WI_CMD_INI)
-			DELAY(100);
+		DELAY(WI_DELAY);
 	}
=20
-	if (i =3D=3D WI_TIMEOUT)
+	if (i =3D=3D WI_TIMEOUT) {
+		device_printf(sc->dev,
+		    "timeout in wi_cmd %x; event status %x\n", cmd, s);
 		return(ETIMEDOUT);
+	}
=20
 	return(0);
 }
@@ -1000,7 +1038,7 @@
 	for (i =3D 0; i < WI_INIT_TRIES; i++) {
 		if (wi_cmd(sc, WI_CMD_INI, 0) =3D=3D 0)
 			break;
-		DELAY(50 * 1000);	/* 50ms */
+		DELAY(WI_DELAY * 1000);
 	}
 	if (i =3D=3D WI_INIT_TRIES)
 		device_printf(sc->dev, "init failed\n");
@@ -1215,6 +1253,7 @@
 		status =3D CSR_READ_2(sc, offreg);
 		if (!(status & (WI_OFF_BUSY|WI_OFF_ERR)))
 			break;
+		DELAY(WI_DELAY);
 	}
=20
 	if (i =3D=3D WI_TIMEOUT) {
@@ -1321,6 +1360,7 @@
 	for (i =3D 0; i < WI_TIMEOUT; i++) {
 		if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
 			break;
+		DELAY(WI_DELAY);
 	}
=20
 	if (i =3D=3D WI_TIMEOUT) {
@@ -2076,24 +2116,45 @@
 }
=20
 static int
-wi_alloc(dev, io_rid)
+wi_alloc(dev, rid)
 	device_t		dev;
-	int				io_rid;
+	int			rid;
 {
 	struct wi_softc		*sc =3D device_get_softc(dev);
=20
-	sc->iobase_rid =3D io_rid;
-	sc->iobase =3D bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->iobase_rid,
-				0, ~0, (1 << 6),
-				rman_make_alignment_flags(1 << 6) | RF_ACTIVE);
-	if (!sc->iobase) {
-		device_printf(dev, "No I/O space?!\n");
-		return (ENXIO);
+	if (sc->wi_bus_type !=3D WI_BUS_PCI_NATIVE) {
+		sc->iobase_rid =3D rid;
+		sc->iobase =3D bus_alloc_resource(dev, SYS_RES_IOPORT,
+		    &sc->iobase_rid, 0, ~0, (1 << 6),
+		    rman_make_alignment_flags(1 << 6) | RF_ACTIVE);
+		if (!sc->iobase) {
+			device_printf(dev, "No I/O space?!\n");
+			return (ENXIO);
+		}
+
+		sc->wi_io_addr =3D rman_get_start(sc->iobase);
+		sc->wi_btag =3D rman_get_bustag(sc->iobase);
+		sc->wi_bhandle =3D rman_get_bushandle(sc->iobase);
+	} else {
+		sc->mem_rid =3D rid;
+		sc->mem =3D bus_alloc_resource(dev, SYS_RES_MEMORY,
+		    &sc->mem_rid, 0, ~0, 1, RF_ACTIVE);
+
+		if (!sc->mem) {
+			device_printf(dev, "No Mem space on prism2.5?\n");
+			return (ENXIO);
+		}
+
+		sc->wi_btag =3D rman_get_bustag(sc->mem);
+		sc->wi_bhandle =3D rman_get_bushandle(sc->mem);
 	}
=20
+
 	sc->irq_rid =3D 0;
 	sc->irq =3D bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
-				     0, ~0, 1, RF_ACTIVE);
+	    0, ~0, 1, RF_ACTIVE |
+	    ((sc->wi_bus_type =3D=3D WI_BUS_PCCARD) ? 0 : RF_SHAREABLE));
+
 	if (!sc->irq) {
 		wi_free(dev);
 		device_printf(dev, "No irq?!\n");
@@ -2102,9 +2163,6 @@
=20
 	sc->dev =3D dev;
 	sc->wi_unit =3D device_get_unit(dev);
-	sc->wi_io_addr =3D rman_get_start(sc->iobase);
-	sc->wi_btag =3D rman_get_bustag(sc->iobase);
-	sc->wi_bhandle =3D rman_get_bushandle(sc->iobase);
=20
 	return (0);
 }
Index: if_wireg.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/cvs/src/sys/dev/wi/if_wireg.h,v
retrieving revision 1.17
diff -u -r1.17 if_wireg.h
--- if_wireg.h	5 Dec 2001 08:57:36 -0000	1.17
+++ if_wireg.h	4 Feb 2002 23:46:32 -0000
@@ -137,12 +137,14 @@
 	struct mtx		wi_mtx;
 	int			wi_prism2;
 	int			wi_prism2_ver;
+	int			wi_bus_type;	/* Bus attachment type */
 };
=20
 #define	WI_LOCK(_sc)
 #define	WI_UNLOCK(_sc)
=20
-#define WI_TIMEOUT	65536
+#define WI_DELAY	5
+#define WI_TIMEOUT	(500000/WI_DELAY)	/* 500 ms */
=20
 #define WI_PORT0	0
 #define WI_PORT1	1
@@ -151,6 +153,7 @@
 #define WI_PORT4	4
 #define WI_PORT5	5
=20
+#define WI_PCI_LMEMRES	0x10	/* PCI Memory (native PCI implementations) */
 #define WI_PCI_LOCALRES	0x14	/* The PLX chip's local registers */
 #define WI_PCI_MEMRES	0x18	/* The PCCard's attribute memory */
 #define WI_PCI_IORES	0x1C	/* The PCCard's I/O space */
@@ -159,6 +162,7 @@
 #define WI_LOCAL_INTEN		0x40
 #define WI_HFA384X_SWSUPPORT0_OFF	0x28
 #define WI_PRISM2STA_MAGIC		0x4A2D
+#define WI_HFA384X_PCICOR_OFF		0x26
=20
 /* Default port: 0 (only 0 exists on stations) */
 #define WI_DEFAULT_PORT	(WI_PORT0 << 8)
@@ -187,29 +191,38 @@
=20
 #define WI_DEFAULT_CHAN		3
=20
+#define WI_BUS_PCCARD		0	/* pccard device */
+#define WI_BUS_PCI_PLX		1	/* PCI card w/ PLX PCI/PCMICA bridge */
+#define WI_BUS_PCI_NATIVE	2	/* native PCI device (Prism 2.5) */
+
 /*
  * register space access macros
  */
-#define CSR_WRITE_4(sc, reg, val)	\
-	bus_space_write_4(sc->wi_btag, sc->wi_bhandle, reg, val)
-#define CSR_WRITE_2(sc, reg, val)	\
-	bus_space_write_2(sc->wi_btag, sc->wi_bhandle, reg, val)
-#define CSR_WRITE_1(sc, reg, val)	\
-	bus_space_write_1(sc->wi_btag, sc->wi_bhandle, reg, val)
-
-#define CSR_READ_4(sc, reg)		\
-	bus_space_read_4(sc->wi_btag, sc->wi_bhandle, reg)
-#define CSR_READ_2(sc, reg)		\
-	bus_space_read_2(sc->wi_btag, sc->wi_bhandle, reg)
-#define CSR_READ_1(sc, reg)		\
-	bus_space_read_1(sc->wi_btag, sc->wi_bhandle, reg)
+#define CSR_WRITE_4(sc, reg, val)				\
+	bus_space_write_4((sc)->wi_btag, (sc)->wi_bhandle, 	\
+	    (sc)->wi_bus_type =3D=3D WI_BUS_PCI_NATIVE ? (reg)*2 : (reg), val)
+#define CSR_WRITE_2(sc, reg, val)				\
+	bus_space_write_2((sc)->wi_btag, (sc)->wi_bhandle,	\
+ 	    (sc)->wi_bus_type =3D=3D WI_BUS_PCI_NATIVE ? (reg)*2 : (reg), val)
+#define CSR_WRITE_1(sc, reg, val)				\
+	bus_space_write_1((sc)->wi_btag, (sc)->wi_bhandle,	\
+ 	    (sc)->wi_bus_type =3D=3D WI_BUS_PCI_NATIVE ? (reg)*2 : (reg), val)
+
+#define CSR_READ_4(sc, reg)					\
+	bus_space_read_4((sc)->wi_btag, (sc)->wi_bhandle,	\
+ 	    (sc)->wi_bus_type =3D=3D WI_BUS_PCI_NATIVE ? (reg)*2 : (reg))
+#define CSR_READ_2(sc, reg)					\
+	bus_space_read_2((sc)->wi_btag, (sc)->wi_bhandle,	\
+ 	    (sc)->wi_bus_type =3D=3D WI_BUS_PCI_NATIVE ? (reg)*2 : (reg))
+#define CSR_READ_1(sc, reg)					\
+	bus_space_read_1((sc)->wi_btag, (sc)->wi_bhandle,	\
+ 	    (sc)->wi_bus_type =3D=3D WI_BUS_PCI_NATIVE ? (reg)*2 : (reg))
=20
 #define CSM_WRITE_1(sc, off, val)	\
-	bus_space_write_1(sc->wi_bmemtag, sc->wi_bmemhandle, off, val)
+	bus_space_write_1((sc)->wi_bmemtag, (sc)->wi_bmemhandle, off, val)
=20
 #define CSM_READ_1(sc, off)		\
-	bus_space_read_1(sc->wi_bmemtag, sc->wi_bmemhandle, off)
-
+	bus_space_read_1((sc)->wi_bmemtag, (sc)->wi_bmemhandle, off)
=20
 /*
  * The WaveLAN/IEEE cards contain an 802.11 MAC controller which Lucent

--=20
Any statement of the form "X is the one, true Y" is FALSE.
PGP fingerprint 655D 519C 26A7 82E7 2529  9BF0 5D8E 8BE9 F238 1AD4

--SUOF0GtieIMvvwua
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE8YFBBXY6L6fI4GtQRAluxAJ4x4iaYCTFpC3HgW9IzVR/upDrADgCeNnL4
mpUOtHyLF/B5Oo2zYnU6XEc=
=4g96
-----END PGP SIGNATURE-----

--SUOF0GtieIMvvwua--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-mobile" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020205133602.A6294>