diff options
author | ambrisko <ambrisko@FreeBSD.org> | 2003-02-08 04:41:17 +0000 |
---|---|---|
committer | ambrisko <ambrisko@FreeBSD.org> | 2003-02-08 04:41:17 +0000 |
commit | f6f64762ea1ec1f1e406e129adfacabf344dfef0 (patch) | |
tree | 8d455a8cff76918f16b16bc8ed6beb10bbab41e6 | |
parent | cf07da2f1a9c11bd6217a035a0030e534abf083b (diff) | |
download | FreeBSD-src-f6f64762ea1ec1f1e406e129adfacabf344dfef0.zip FreeBSD-src-f6f64762ea1ec1f1e406e129adfacabf344dfef0.tar.gz |
- Fixes for suspend/resume code (MPI-350)
- Cache temp. keys so they are preserved across suspend/resume (MPI-350)
- Reads and writes are real fast to the MPI-350 causing early timeouts so
wait do some DELAYs to slow things down in the spin loops.
- Stream line setting RIDs when they are better to be set via another
function
- Add better support for setting home key via "ifconfig an0 wepkey 9:<key>"
Tested by: Peter Radcliffe <pir@pir.net> (in -stable)
myself in -current & -stable
MFC in: 3 days
-rw-r--r-- | sys/dev/an/if_an.c | 100 | ||||
-rw-r--r-- | sys/dev/an/if_anreg.h | 5 |
2 files changed, 54 insertions, 51 deletions
diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c index 7179943..c33c7c0 100644 --- a/sys/dev/an/if_an.c +++ b/sys/dev/an/if_an.c @@ -154,7 +154,6 @@ static int an_cmd_struct (struct an_softc *, struct an_command *, struct an_reply *); static int an_read_record (struct an_softc *, struct an_ltv_gen *); static int an_write_record (struct an_softc *, struct an_ltv_gen *); -static void an_kick (struct an_softc *); static int an_read_data (struct an_softc *, int, int, caddr_t, int); static int an_write_data (struct an_softc *, int, int, caddr_t, int); static int an_seek (struct an_softc *, int, int, int); @@ -205,7 +204,7 @@ static char an_conf_cache[256]; /* sysctl vars */ -SYSCTL_NODE(_machdep, OID_AUTO, an, CTLFLAG_RD, 0, "dump RID"); +SYSCTL_NODE(_hw, OID_AUTO, an, CTLFLAG_RD, 0, "Wireless driver parameters"); /* XXX violate ethernet/netgraph callback hooks */ extern void (*ng_ether_attach_p)(struct ifnet *ifp); @@ -264,7 +263,7 @@ sysctl_an_dump(SYSCTL_HANDLER_ARGS) return error; } -SYSCTL_PROC(_machdep, OID_AUTO, an_dump, CTLTYPE_STRING | CTLFLAG_RW, +SYSCTL_PROC(_hw_an, OID_AUTO, an_dump, CTLTYPE_STRING | CTLFLAG_RW, 0, sizeof(an_conf), sysctl_an_dump, "A", ""); static int @@ -302,7 +301,7 @@ sysctl_an_cache_mode(SYSCTL_HANDLER_ARGS) return error; } -SYSCTL_PROC(_machdep, OID_AUTO, an_cache_mode, CTLTYPE_STRING | CTLFLAG_RW, +SYSCTL_PROC(_hw_an, OID_AUTO, an_cache_mode, CTLTYPE_STRING | CTLFLAG_RW, 0, sizeof(an_conf_cache), sysctl_an_cache_mode, "A", ""); /* @@ -1235,31 +1234,6 @@ an_intr(xsc) return; } -static void -an_kick(sc) - struct an_softc *sc; -{ - int i; - - CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), AN_CMD_NOOP2); - - if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) { - CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD); - } else { - for (i = 0; i < AN_TIMEOUT; i++) { - if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)) - & AN_EV_CMD) - break; - } - if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) { - CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD); - } - CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD); - if (i == AN_TIMEOUT) { - printf ("COULDN'T CLEAR\n"); - } - } -} static int an_cmd_struct(sc, cmd, reply) @@ -1271,7 +1245,7 @@ an_cmd_struct(sc, cmd, reply) for (i = 0; i != AN_TIMEOUT; i++) { if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) { - DELAY(10); + DELAY(1000); } else break; } @@ -1288,11 +1262,9 @@ an_cmd_struct(sc, cmd, reply) for (i = 0; i < AN_TIMEOUT; i++) { if (CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350)) & AN_EV_CMD) break; + DELAY(1000); } - if (i == AN_TIMEOUT) - an_kick(sc); - reply->an_resp0 = CSR_READ_2(sc, AN_RESP0(sc->mpi350)); reply->an_resp1 = CSR_READ_2(sc, AN_RESP1(sc->mpi350)); reply->an_resp2 = CSR_READ_2(sc, AN_RESP2(sc->mpi350)); @@ -1554,8 +1526,10 @@ an_write_record(sc, ltv) CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4, ((u_int32_t*)&an_rid_desc)[i]); + DELAY(100000); + if ((i = an_cmd_struct(sc, &cmd, &reply))) { - printf("an%d: failed to write RID %x %x %x %x %x, %d\n", + printf("an%d: failed to write RID 1 %x %x %x %x %x, %d\n", sc->an_unit, ltv->an_type, reply.an_status, reply.an_resp0, @@ -1568,7 +1542,7 @@ an_write_record(sc, ltv) ptr = (u_int16_t *)buf; if (reply.an_status & AN_CMD_QUAL_MASK) { - printf("an%d: failed to write RID %x %x %x %x %x, %d\n", + printf("an%d: failed to write RID 2 %x %x %x %x %x, %d\n", sc->an_unit, ltv->an_type, reply.an_status, reply.an_resp0, @@ -1577,6 +1551,7 @@ an_write_record(sc, ltv) i); return(EIO); } + DELAY(100000); } return(0); @@ -1812,6 +1787,10 @@ an_setdef(sc, areq) sc->an_config.an_len = sizeof(struct an_ltv_genconfig); break; case AN_RID_WEP_TEMP: + /* Cache the temp keys */ + bcopy(areq, + &sc->an_temp_keys[((struct an_ltv_key *)areq)->kindex], + sizeof(struct an_ltv_key)); case AN_RID_WEP_PERM: case AN_RID_LEAPUSERNAME: case AN_RID_LEAPPASSWORD: @@ -2315,7 +2294,7 @@ an_ioctl(ifp, command, data) } break; case IEEE80211_IOC_WEPKEY: - if (ireq->i_val < 0 || ireq->i_val > 7 || + if (ireq->i_val < 0 || ireq->i_val > 8 || ireq->i_len > 13) { error = EINVAL; break; @@ -2323,27 +2302,35 @@ an_ioctl(ifp, command, data) error = copyin(ireq->i_data, tmpstr, 13); if (error != 0) break; + /* + * Map the 9th key into the home mode + * since that is how it is stored on + * the card + */ bzero(&sc->areq, sizeof(struct an_ltv_key)); sc->areq.an_len = sizeof(struct an_ltv_key); key->mac[0] = 1; /* The others are 0. */ - key->kindex = ireq->i_val % 4; - if (ireq->i_val < 4) + if (ireq->i_val < 4) { sc->areq.an_type = AN_RID_WEP_TEMP; - else + key->kindex = ireq->i_val; + } else { sc->areq.an_type = AN_RID_WEP_PERM; + key->kindex = ireq->i_val - 4; + } key->klen = ireq->i_len; bcopy(tmpstr, key->key, key->klen); break; case IEEE80211_IOC_WEPTXKEY: + if (ireq->i_val < 0 || ireq->i_val > 4) { + error = EINVAL; + break; + } + /* * Map the 5th key into the home mode * since that is how it is stored on * the card */ - if (ireq->i_val < 0 || ireq->i_val > 4) { - error = EINVAL; - break; - } sc->areq.an_len = sizeof(struct an_ltv_genconfig); sc->areq.an_type = AN_RID_ACTUALCFG; if (an_read_record(sc, @@ -2360,7 +2347,9 @@ an_ioctl(ifp, command, data) sc->an_config.an_home_product = config->an_home_product; - an_write_record(sc, (struct an_ltv_gen *)&sc->areq); + + /* update configuration */ + an_init(sc); bzero(&sc->areq, sizeof(struct an_ltv_key)); sc->areq.an_len = sizeof(struct an_ltv_key); @@ -2828,6 +2817,7 @@ an_shutdown(dev) sc = device_get_softc(dev); an_stop(sc); + sc->an_gone = 1; return; } @@ -2838,16 +2828,30 @@ an_resume(dev) { struct an_softc *sc; struct ifnet *ifp; + int i; + sc = device_get_softc(dev); + AN_LOCK(sc); ifp = &sc->arpcom.ac_if; + sc->an_gone = 0; an_reset(sc); if (sc->mpi350) an_init_mpi350_desc(sc); an_init(sc); + /* Recovery temporary keys */ + for (i = 0; i < 4; i++) { + sc->areq.an_type = AN_RID_WEP_TEMP; + sc->areq.an_len = sizeof(struct an_ltv_key); + bcopy(&sc->an_temp_keys[i], + &sc->areq, sizeof(struct an_ltv_key)); + an_setdef(sc, &sc->areq); + } + if (ifp->if_flags & IFF_UP) an_start(ifp); + AN_UNLOCK(sc); return; } @@ -2899,13 +2903,13 @@ int an_nextitem; /* index/# of entries */ * so ping/unicast anll work say anth pt. to pt. antennae setup. */ static int an_cache_mcastonly = 0; -SYSCTL_INT(_machdep, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW, +SYSCTL_INT(_hw_an, OID_AUTO, an_cache_mcastonly, CTLFLAG_RW, &an_cache_mcastonly, 0, ""); /* set true if you want to limit cache items to IP packets only */ static int an_cache_iponly = 1; -SYSCTL_INT(_machdep, OID_AUTO, an_cache_iponly, CTLFLAG_RW, +SYSCTL_INT(_hw_an, OID_AUTO, an_cache_iponly, CTLFLAG_RW, &an_cache_iponly, 0, ""); /* @@ -3102,8 +3106,8 @@ an_media_change(ifp) sc->an_config.an_len = sizeof(struct an_ltv_genconfig); } - if (otype != sc->an_config.an_opmode - || orate != sc->an_tx_rate) + if (otype != sc->an_config.an_opmode || + orate != sc->an_tx_rate) an_init(sc); return(0); diff --git a/sys/dev/an/if_anreg.h b/sys/dev/an/if_anreg.h index 165f760..0af4506 100644 --- a/sys/dev/an/if_anreg.h +++ b/sys/dev/an/if_anreg.h @@ -32,7 +32,7 @@ * $FreeBSD$ */ -#define AN_TIMEOUT 600000 +#define AN_TIMEOUT 65536 /* Default network name: <empty string> */ #define AN_DEFAULT_NETNAME "" @@ -460,8 +460,7 @@ struct an_softc { struct an_ltv_caps an_caps; struct an_ltv_ssidlist an_ssidlist; struct an_ltv_aplist an_aplist; - struct an_ltv_key an_temp_keys; - struct an_ltv_key an_perm_keys; + struct an_ltv_key an_temp_keys[4]; int an_tx_rate; int an_rxmode; int an_gone; |