[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: wi(4) fixes
Hi,
Has anyone had any luck getting software WEP to work in HostAP mode on a prism 2.5 card?
dmesg snipped:
wi0 at pci0 dev 13 function 0 "Intersil PRISM2.5 Mini-PCI WLAN" rev 0x01: irq 10
wi0: PRISM2.5 ISL3874A(Mini-PCI), Firmware 1.1.0 (primary), 1.4.9 (station), address 00:02:6f:06:6b
:2b
Once I turn on software wep with wicontrol -x1, the connection fails to reassociate.
Sorry to hijack this thread, I'm hoping that someone from those who read this thread might have done this.
Thanks.
Rgds,
Anwar.
Begin On Tue, 02 Mar 2004 09:50:16 -0700, "Todd C. Miller" <Todd.Miller@courtesan.com> wrote:
> The following diff, relative to OpenBSD 3.4 (-current will require
> simple hand-patching for one hunk), makes HostAP work on Prism cards
> with newer firmware (1.7.0 and higher) and fixes some timing issues
> that caused some prism-based cards to be unstable.
>
> If you have been having intermittent problems with a wireless card
> that uses the wi(4) driver I would be interested in hearing whether
> or not this helps things. I'm especially interested in hearing
> about native PCI-based cards (ie: not using a host adapter) since
> I don't own any of that type.
>
> - todd
>
> Index: sys/dev/ic/if_wi.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/ic/if_wi.c,v
> retrieving revision 1.98
> diff -u -r1.98 if_wi.c
> --- sys/dev/ic/if_wi.c 6 Sep 2003 20:53:57 -0000 1.98
> +++ sys/dev/ic/if_wi.c 2 Mar 2004 15:50:30 -0000
> @@ -188,6 +188,8 @@
> struct ifnet *ifp;
> int error;
>
> + sc->wi_cmd_count = 500;
> +
> wi_reset(sc);
>
> /* Read the station address. */
> @@ -264,6 +266,9 @@
> break;
> case WI_INTERSIL:
> sc->wi_flags |= WI_FLAGS_HAS_ROAMING;
> + /* older prism firmware is slow so crank the count */
> + if (sc->sc_sta_firmware_ver < 10000)
> + sc->wi_cmd_count = 5000;
> if (sc->sc_sta_firmware_ver >= 800) {
> #ifndef SMALL_KERNEL
> sc->wi_flags |= WI_FLAGS_HAS_HOSTAP;
> @@ -472,7 +477,7 @@
> struct ether_header *eh;
> struct mbuf *m;
> caddr_t olddata;
> - u_int16_t msg_type;
> + u_int16_t ftype;
> int maxlen;
> int id;
>
> @@ -581,8 +586,8 @@
> return;
> }
>
> - /* Stash message type in host byte order for later use */
> - msg_type = letoh16(rx_frame.wi_status) & WI_RXSTAT_MSG_TYPE;
> + /* Stash frame type in host byte order for later use */
> + ftype = letoh16(rx_frame.wi_frame_ctl) & WI_FCTL_FTYPE;
>
> MGETHDR(m, M_DONTWAIT, MT_DATA);
> if (m == NULL) {
> @@ -605,7 +610,7 @@
> maxlen = MCLBYTES - (m->m_data - olddata);
> m->m_pkthdr.rcvif = ifp;
>
> - if (msg_type == WI_STAT_MGMT &&
> + if (ftype == WI_FTYPE_MGMT &&
> sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
>
> u_int16_t rxlen = letoh16(rx_frame.wi_dat_len);
> @@ -643,7 +648,7 @@
> return;
> }
>
> - switch (msg_type) {
> + switch (letoh16(rx_frame.wi_status) & WI_RXSTAT_MSG_TYPE) {
> case WI_STAT_1042:
> case WI_STAT_TUNNEL:
> case WI_STAT_WMP_MSG:
> @@ -877,10 +882,15 @@
> int i, s = 0;
>
> /* Wait for the busy bit to clear. */
> - for (i = 0; i < WI_TIMEOUT; i++) {
> + for (i = sc->wi_cmd_count; i--; DELAY(1000)) {
> if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY))
> break;
> - DELAY(10);
> + }
> + if (i < 0) {
> + if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
> + printf(WI_PRT_FMT ": wi_cmd_io: busy bit won't clear\n",
> + WI_PRT_ARG(sc));
> + return(ETIMEDOUT);
> }
>
> CSR_WRITE_2(sc, WI_PARAM0, val0);
> @@ -888,7 +898,7 @@
> CSR_WRITE_2(sc, WI_PARAM2, val2);
> CSR_WRITE_2(sc, WI_COMMAND, cmd);
>
> - for (i = WI_TIMEOUT; i--; DELAY(10)) {
> + for (i = WI_TIMEOUT; i--; DELAY(WI_DELAY)) {
> /*
> * Wait for 'command complete' bit to be
> * set in the event status register.
> @@ -898,18 +908,19 @@
> /* Ack the event and read result code. */
> s = CSR_READ_2(sc, WI_STATUS);
> CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
> -#ifdef foo
> - if ((s & WI_CMD_CODE_MASK) != (cmd & WI_CMD_CODE_MASK))
> - return(EIO);
> -#endif
> if (s & WI_STAT_CMD_RESULT)
> return(EIO);
> break;
> }
> }
>
> - if (i < 0)
> + if (i < 0) {
> + if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
> + printf(WI_PRT_FMT
> + ": timeout in wi_cmd 0x%04x; event status 0x%04x\n",
> + WI_PRT_ARG(sc), cmd, s);
> return(ETIMEDOUT);
> + }
>
> return(0);
> }
> @@ -918,17 +929,26 @@
> wi_reset(sc)
> struct wi_softc *sc;
> {
> + int error, tries = 3;
> +
> DPRINTF(WID_RESET, ("wi_reset: sc %p\n", sc));
>
> /* Symbol firmware cannot be initialized more than once. */
> - if (sc->sc_firmware_type == WI_SYMBOL &&
> - (sc->wi_flags & WI_FLAGS_INITIALIZED))
> - return;
> + if (sc->sc_firmware_type == WI_SYMBOL) {
> + if (sc->wi_flags & WI_FLAGS_INITIALIZED)
> + return;
> + tries = 1;
> + }
>
> - if (wi_cmd(sc, WI_CMD_INI, 0, 0, 0))
> + for (; tries--; DELAY(WI_DELAY * 1000)) {
> + if ((error = wi_cmd(sc, WI_CMD_INI, 0, 0, 0)) == 0)
> + break;
> + }
> + if (tries < 0) {
> printf(WI_PRT_FMT ": init failed\n", WI_PRT_ARG(sc));
> - else
> - sc->wi_flags |= WI_FLAGS_INITIALIZED;
> + return;
> + }
> + sc->wi_flags |= WI_FLAGS_INITIALIZED;
>
> CSR_WRITE_2(sc, WI_INT_EN, 0);
> CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
> @@ -1217,7 +1237,7 @@
> CSR_WRITE_2(sc, selreg, id);
> CSR_WRITE_2(sc, offreg, off);
>
> - for (i = WI_TIMEOUT; i--; DELAY(10))
> + for (i = WI_TIMEOUT; i--; DELAY(1))
> if (!(CSR_READ_2(sc, offreg) & (WI_OFF_BUSY|WI_OFF_ERR)))
> break;
>
> @@ -1309,7 +1329,7 @@
> return(ENOMEM);
> }
>
> - for (i = WI_TIMEOUT; i--; DELAY(10)) {
> + for (i = WI_TIMEOUT; i--; DELAY(1)) {
> if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
> break;
> }
> Index: sys/dev/ic/if_wi_hostap.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/ic/if_wi_hostap.c,v
> retrieving revision 1.26
> diff -u -r1.26 if_wi_hostap.c
> --- sys/dev/ic/if_wi_hostap.c 15 Aug 2003 20:32:17 -0000 1.26
> +++ sys/dev/ic/if_wi_hostap.c 2 Mar 2004 15:49:50 -0000
> @@ -1109,11 +1109,18 @@
> struct wihap_sta_info *sta;
> int mcast, s;
>
> - /* TODS flag must be set. */
> - if (!(rxfrm->wi_frame_ctl & htole16(WI_FCTL_TODS))) {
> + /*
> + * TODS flag must be set. However, Lucent cards set NULLFUNC but
> + * not TODS when probing an AP to see if it is alive after it has
> + * been down for a while. We accept these probe packets and send a
> + * disassoc packet later on if the station is not already associated.
> + */
> + if (!(rxfrm->wi_frame_ctl & htole16(WI_FCTL_TODS)) &&
> + !(rxfrm->wi_frame_ctl & WI_STYPE_NULLFUNC)) {
> if (ifp->if_flags & IFF_DEBUG)
> - printf("wihap_data_input: no TODS src=%s\n",
> - ether_sprintf(rxfrm->wi_addr2));
> + printf("wihap_data_input: no TODS src=%s, fctl=0x%x\n",
> + ether_sprintf(rxfrm->wi_addr2),
> + letoh16(rxfrm->wi_frame_ctl));
> m_freem(m);
> return (1);
> }
> Index: sys/dev/ic/if_wi_ieee.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/ic/if_wi_ieee.h,v
> retrieving revision 1.17
> diff -u -r1.17 if_wi_ieee.h
> --- sys/dev/ic/if_wi_ieee.h 24 Aug 2003 12:23:57 -0000 1.17
> +++ sys/dev/ic/if_wi_ieee.h 2 Mar 2004 15:49:50 -0000
> @@ -131,6 +131,15 @@
> #define WI_STYPE_CTL_CFEND 0x00E0
> #define WI_STYPE_CTL_CFENDACK 0x00F0
>
> +#define WI_STYPE_DATA 0x0000
> +#define WI_STYPE_DATA_CFACK 0x0010
> +#define WI_STYPE_DATA_CFPOLL 0x0020
> +#define WI_STYPE_DATA_CFACKPOLL 0x0030
> +#define WI_STYPE_NULLFUNC 0x0040
> +#define WI_STYPE_CFACK 0x0050
> +#define WI_STYPE_CFPOLL 0x0060
> +#define WI_STYPE_CFACKPOLL 0x0070
> +
> struct wi_mgmt_hdr {
> u_int16_t frame_ctl;
> u_int16_t duration;
> Index: sys/dev/ic/if_wireg.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/ic/if_wireg.h,v
> retrieving revision 1.32
> diff -u -r1.32 if_wireg.h
> --- sys/dev/ic/if_wireg.h 25 Jun 2003 17:38:55 -0000 1.32
> +++ sys/dev/ic/if_wireg.h 2 Mar 2004 15:49:53 -0000
> @@ -34,7 +34,8 @@
> * From: if_wireg.h,v 1.8.2.2 2001/08/25 00:48:25 nsayer Exp $
> */
>
> -#define WI_TIMEOUT 50000 /* 10x XXX just a guess at a good value. */
> +#define WI_DELAY 5
> +#define WI_TIMEOUT (500000/WI_DELAY) /* 500ms */
>
> #define WI_PORT0 0
> #define WI_PORT1 1
> Index: sys/dev/ic/if_wivar.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/ic/if_wivar.h,v
> retrieving revision 1.21
> diff -u -r1.21 if_wivar.h
> --- sys/dev/ic/if_wivar.h 6 Sep 2003 20:53:57 -0000 1.21
> +++ sys/dev/ic/if_wivar.h 2 Mar 2004 15:49:53 -0000
> @@ -51,6 +51,7 @@
> int wi_tx_mgmt_id;
> int wi_flags;
> int wi_if_flags;
> + int wi_cmd_count;
> u_int16_t wi_procframe;
> u_int16_t wi_ptype;
> u_int16_t wi_portnum;
- References:
- wi(4) fixes
- From: "Todd C. Miller" <Todd.Miller@courtesan.com>