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>