Re: patch for wi driver
Thanks Yamamoto san ! This works really rather nicely and has reduce the number of tx errors tremendously (Though not completely and xmit failed/device timeout is still there). Thanks ! Dw. On Mon, 11 Dec 2000, YAMAMOTO Shigeru wrote: > Hi, all. > I send a patch for wi driver. > > Some cases, we have errors, > 'wi0: tx buffer allocation failed' > and > 'wi0: mgmt. buffer allocation failed' > > Thease errors are caused by bugs in wi driver. > #Current wi driver has initialization and resource allocation mistakes. > > And this patch includes WEP support code for PrismII chip. > Original WEP support code was writen by Onoe at NetBSD. > But WEP support code does not work many PrismII based cards on FreeBSD. > We need more hack. > > Thanks, > --- > YAMAMOTO Shigeru Internet Initiative Japan Inc. > <[EMAIL PROTECTED]> Network Engineering Div. > To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: patch for wi driver
[[ Followups to freebsd-mobile please ]] In message <[EMAIL PROTECTED]> YAMAMOTO Shigeru writes: : I send a patch for wi driver. Thank you yamamoto-san. I'll have to see if this works with the prism II based boards that I have here that aren't supported by the an driver. : #Current wi driver has initialization and resource allocation mistakes. I noticed that you fixed the bus_alloc_resource for the IOPORT to always be 64 bytes long, aligned on a 64-byte boundary. Are there other mistakes as well? : And this patch includes WEP support code for PrismII chip. : Original WEP support code was writen by Onoe at NetBSD. : But WEP support code does not work many PrismII based cards on FreeBSD. : We need more hack. Thanks for the update. I can report that my lucent gold card still works after these changes. I have a few questions about the code. : +#ifdef foo : wi_cmd(sc, WI_CMD_INI, 0); : DELAY(10); : wi_cmd(sc, WI_CMD_INI, 0); : +#endif : DELAY(10); : -#ifdef foo : if (wi_cmd(sc, WI_CMD_INI, 0)) : device_printf(sc->dev, "init failed\n"); : CSR_WRITE_2(sc, WI_INT_EN, 0); : @@ -633,7 +678,7 @@ : : /* Calibrate timer. */ : WI_SETVAL(WI_RID_TICK_TIME, 8); : -#endif : + : return; : } : If I'm reading this part of the patch collrectly, all wireset does is put a delay 10 (100ms) into the compiled in code. Is that right? Why did you do that? Also, is there some reason that tsleep can't be used instead (well, other than it being soon replaced with msleep)? : sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, : - 0, ~0, 1, RF_ACTIVE); : + 0, ~0, (1 << 6), : + rman_make_alignment_flags(1 << 6) | RF_ACTIVE); I've run into this problem and made hacks to pccardd to only try things on a "natural" boundary for the size of the i/o block. This likely is the right thing to do in the driver. BTW, here are my changes to pccardd. They also try to increase the verbosity of the reports. Down around the patch for lines 722(715) you'll find where I do the check. There's also some sprintf reductions in these changes. I've been running with them on my main wireless server for a few weeks now and they seem OK, but I hesitate to commit them. Does this mean that all of your wireless cards now work with FreeBSD? Or are there still some issues? Thank you again for your efforts. Warner Index: cardd.c === RCS file: /home/imp/FreeBSD/CVS/src/usr.sbin/pccard/pccardd/cardd.c,v retrieving revision 1.64 diff -u -r1.64 cardd.c --- cardd.c 2000/10/20 13:08:18 1.64 +++ cardd.c 2000/11/19 04:42:00 @@ -42,7 +42,7 @@ #include "cardd.h" static struct card_config *assign_driver(struct card *); -static int assign_io(struct slot *); +static char * assign_io(struct slot *); static int setup_slot(struct slot *); static void card_inserted(struct slot *); static void card_removed(struct slot *); @@ -279,7 +279,7 @@ card_inserted(struct slot *sp) { struct card *cp; - int err; + char *reason; usleep(pccard_init_sleep); sp->cis = readcis(sp->fd); @@ -362,27 +362,10 @@ } if ((sp->config = assign_driver(cp)) == NULL) return; - if (err = assign_io(sp)) { - char *reason; - - switch (err) { - case -1: - reason = "specified CIS was not found"; - break; - case -2: - reason = "memory block allocation failed"; - break; - case -3: - reason = "I/O block allocation failed"; - break; - default: - reason = "Unknown"; - break; - } -logmsg("Resource allocation failure for \"%s\"(\"%s\") " - "[%s] [%s]; Reason %s\n", -sp->cis->manuf, sp->cis->vers, -sp->cis->add_info1, sp->cis->add_info2, reason); + if ((reason = assign_io(sp)) != NULL) { +logmsg("Resource allocation failure for \"%s\"(\"%s\"): " +"%s\n", sp->cis->manuf, sp->cis->vers, reason); + free(reason); return; } @@ -593,11 +576,12 @@ * assign_io - Allocate resources to slot matching the * configuration index selected. */ -static int +static char * assign_io(struct slot *sp) { str
patch for wi driver
Hi, all. I send a patch for wi driver. Some cases, we have errors, 'wi0: tx buffer allocation failed' and 'wi0: mgmt. buffer allocation failed' Thease errors are caused by bugs in wi driver. #Current wi driver has initialization and resource allocation mistakes. And this patch includes WEP support code for PrismII chip. Original WEP support code was writen by Onoe at NetBSD. But WEP support code does not work many PrismII based cards on FreeBSD. We need more hack. Thanks, --- YAMAMOTO ShigeruInternet Initiative Japan Inc. <[EMAIL PROTECTED]> Network Engineering Div. Index: if_wi.c === RCS file: /share/cvsup/FreeBSD/current/usr/src/sys/i386/isa/if_wi.c,v retrieving revision 1.29 diff -u -r1.29 if_wi.c --- if_wi.c 2000/11/30 18:52:31 1.29 +++ if_wi.c 2000/12/11 04:46:37 @@ -231,10 +231,34 @@ struct wi_ltv_gen gen; struct ifnet*ifp; int error; + u_int32_t flags; sc = device_get_softc(dev); ifp = &sc->arpcom.ac_if; + /* +* XXX: quick hack to support Prism II chip. +* Currently, we need to set a flags in pccard.conf to specify +* which type chip is used. +* +* We need to replace this code in a future. +* It is better to use CIS than using a flag. +*/ + flags = device_get_flags(dev); +#defineWI_FLAGS_PRISM2 0x1 + if (flags & WI_FLAGS_PRISM2) { + sc->wi_prism2 = 1; + if (bootverbose) { + device_printf(dev, "found PrismII chip\n"); + } + } + else { + sc->wi_prism2 = 0; + if (bootverbose) { + device_printf(dev, "found Lucent chip\n"); + } + } + error = wi_alloc(dev); if (error) { device_printf(dev, "wi_alloc() failed! (%d)\n", error); @@ -320,6 +344,12 @@ wi_read_record(sc, &gen); sc->wi_has_wep = gen.wi_val; + if (bootverbose) { + device_printf(sc->dev, + __FUNCTION__ ":wi_has_wep = %d\n", + sc->wi_has_wep); + } + bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats)); wi_init(sc); @@ -589,7 +619,21 @@ { int i, s = 0; + /* wait for the busy bit to clear */ + for (i = 0; i < WI_TIMEOUT; i++) { + if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) { + break; + } + DELAY(10*1000); /* 10 m sec */ + } + + if (i == WI_TIMEOUT) { + return(ETIMEDOUT); + } + CSR_WRITE_2(sc, WI_PARAM0, val); + CSR_WRITE_2(sc, WI_PARAM1, 0); + CSR_WRITE_2(sc, WI_PARAM2, 0); CSR_WRITE_2(sc, WI_COMMAND, cmd); for (i = 0; i < WI_TIMEOUT; i++) { @@ -621,11 +665,12 @@ static void wi_reset(sc) struct wi_softc *sc; { +#ifdef foo wi_cmd(sc, WI_CMD_INI, 0); DELAY(10); wi_cmd(sc, WI_CMD_INI, 0); +#endif DELAY(10); -#ifdef foo if (wi_cmd(sc, WI_CMD_INI, 0)) device_printf(sc->dev, "init failed\n"); CSR_WRITE_2(sc, WI_INT_EN, 0); @@ -633,7 +678,7 @@ /* Calibrate timer. */ WI_SETVAL(WI_RID_TICK_TIME, 8); -#endif + return; } @@ -646,6 +691,23 @@ { u_int16_t *ptr; int i, len, code; + struct wi_ltv_gen *oltv, p2ltv; + + oltv = ltv; + if (sc->wi_prism2) { + switch (ltv->wi_type) { + case WI_RID_ENCRYPTION: + p2ltv.wi_type = WI_RID_P2_ENCRYPTION; + p2ltv.wi_len = 2; + ltv = &p2ltv; + break; + case WI_RID_TX_CRYPT_KEY: + p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; + p2ltv.wi_len = 2; + ltv = &p2ltv; + break; + } + } /* Tell the NIC to enter record read mode. */ if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type)) @@ -675,6 +737,35 @@ for (i = 0; i < ltv->wi_len - 1; i++) ptr[i] = CSR_READ_2(sc, WI_DATA1); + if (sc->wi_prism2) { + switch (oltv->wi_type) { + case WI_RID_TX_RATE: + case WI_RID_CUR_TX_RATE: + switch (ltv->wi_val) { + case 1: oltv->wi_val = 1; break; + case 2: oltv->wi_val = 2; break; +