diff options
-rw-r--r-- | sys/dev/an/if_aironet_ieee.h | 2 | ||||
-rw-r--r-- | sys/dev/an/if_an.c | 219 | ||||
-rw-r--r-- | sys/dev/an/if_anreg.h | 2 |
3 files changed, 156 insertions, 67 deletions
diff --git a/sys/dev/an/if_aironet_ieee.h b/sys/dev/an/if_aironet_ieee.h index a1eeb26..b1ab4be 100644 --- a/sys/dev/an/if_aironet_ieee.h +++ b/sys/dev/an/if_aironet_ieee.h @@ -528,7 +528,7 @@ struct an_ltv_status { u_int16_t an_max_noise_prev_sec; /* 0x7A */ u_int16_t an_avg_noise_prev_min; /* 0x7C */ u_int16_t an_max_noise_prev_min; /* 0x7E */ - u_int16_t an_spare[3]; + u_int16_t an_spare[5]; }; #define AN_STATUS_OPMODE_CONFIGURED 0x0001 diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c index f7a383d..5f1262b 100644 --- a/sys/dev/an/if_an.c +++ b/sys/dev/an/if_an.c @@ -162,9 +162,13 @@ static void an_cache_store __P((struct an_softc *, struct ether_header *, struct mbuf *, unsigned short)); #endif +static void an_dump_record __P((struct an_softc *,struct an_ltv_gen *, + char *)); + static int an_media_change __P((struct ifnet *)); static void an_media_status __P((struct ifnet *, struct ifmediareq *)); +static int an_dump = 0; /* * We probe for an Aironet 4500/4800 card by attempting to * read the default SSID list. On reset, the first entry in @@ -181,7 +185,7 @@ int an_probe(dev) bzero((char *)&ssid, sizeof(ssid)); error = an_alloc_port(dev, 0, AN_IOSIZ); - if (error) + if (error != 0) return (0); /* can't do autoprobing */ @@ -393,12 +397,12 @@ int an_attach(sc, unit, flags) ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, IFM_IEEE80211_ADHOC, 0), 0); ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0); - if(sc->an_caps.an_rates[2] == AN_RATE_5_5MBPS) { + if (sc->an_caps.an_rates[2] == AN_RATE_5_5MBPS) { ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, IFM_IEEE80211_ADHOC, 0), 0); ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0); } - if(sc->an_caps.an_rates[3] == AN_RATE_11MBPS) { + if (sc->an_caps.an_rates[3] == AN_RATE_11MBPS) { ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, IFM_IEEE80211_ADHOC, 0), 0); ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0); @@ -490,7 +494,7 @@ static void an_rxeof(sc) error = an_read_data(sc, id, 0x44, (caddr_t)&(eh->ether_type), rx_frame_802_3.an_rx_802_3_payload_len); - if (error) { + if (error != 0) { m_freem(m); ifp->if_ierrors++; return; @@ -511,7 +515,7 @@ static void an_txeof(sc, status) int status; { struct ifnet *ifp; - int id; + int id, i; /* TX DONE enable lan monitor DJA an_enable_sniff(); @@ -529,12 +533,13 @@ static void an_txeof(sc, status) } else ifp->if_opackets++; - if (id != sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons]) - printf("an%d: id mismatch: expected %x, got %x\n", - sc->an_unit, - sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons], id); + for (i = 0; i < AN_TX_RING_CNT; i++) { + if (id == sc->an_rdata.an_tx_ring[i]) { + sc->an_rdata.an_tx_ring[i] = 0; + break; + } + } - sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons] = 0; AN_INC(sc->an_rdata.an_tx_cons, AN_TX_RING_CNT); return; @@ -720,9 +725,10 @@ static int an_read_record(sc, ltv) struct an_ltv_gen *ltv; { u_int16_t *ptr; + u_int8_t *ptr2; int i, len; - if (ltv->an_len == 0 || ltv->an_type == 0) + if (ltv->an_len < 4 || ltv->an_type == 0) return(EINVAL); /* Tell the NIC to enter record read mode. */ @@ -741,20 +747,29 @@ static int an_read_record(sc, ltv) * Read the length and record type and make sure they * match what we expect (this verifies that we have enough * room to hold all of the returned data). + * Length includes type but not length. */ len = CSR_READ_2(sc, AN_DATA1); if (len > (ltv->an_len - 2)) { printf("an%d: record length mismatch -- expected %d, " - "got %d\n", sc->an_unit, (ltv->an_len - 2), len); - len = (ltv->an_len - 2); + "got %d for Rid %x\n", sc->an_unit, + ltv->an_len - 2, len, ltv->an_type); + len = ltv->an_len - 2; + } else { + ltv->an_len = len + 2; } - ltv->an_len = len; - /* Now read the data. */ + len -= 2; /* skip the type */ ptr = <v->an_val; - for (i = 0; i < (ltv->an_len - 2) >> 1; i++) - ptr[i] = CSR_READ_2(sc, AN_DATA1); + for (i = len; i > 1; i -= 2) + *ptr++ = CSR_READ_2(sc, AN_DATA1); + if (i) { + ptr2 = (u_int8_t *)ptr; + *ptr2 = CSR_READ_1(sc, AN_DATA1); + } + if (an_dump) + an_dump_record(sc, ltv, "Read"); return(0); } @@ -767,19 +782,32 @@ static int an_write_record(sc, ltv) struct an_ltv_gen *ltv; { u_int16_t *ptr; - int i; + u_int8_t *ptr2; + int i, len; + + if (an_dump) + an_dump_record(sc, ltv, "Write"); if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) return(EIO); - + if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) return(EIO); - CSR_WRITE_2(sc, AN_DATA1, ltv->an_len-2); + /* + * Length includes type but not length. + */ + len = ltv->an_len - 2; + CSR_WRITE_2(sc, AN_DATA1, len); + len -= 2; /* skip the type */ ptr = <v->an_val; - for (i = 0; i < (ltv->an_len - 4) >> 1; i++) - CSR_WRITE_2(sc, AN_DATA1, ptr[i]); + for (i = len; i > 1; i -= 2) + CSR_WRITE_2(sc, AN_DATA1, *ptr++); + if (i) { + ptr2 = (u_int8_t *)ptr; + CSR_WRITE_1(sc, AN_DATA0, *ptr2); + } if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type)) return(EIO); @@ -787,6 +815,50 @@ static int an_write_record(sc, ltv) return(0); } +static void an_dump_record(sc, ltv, string) + struct an_softc *sc; + struct an_ltv_gen *ltv; + char *string; +{ + u_int8_t *ptr2; + int len; + int i; + int count = 0; + char buf[17], temp; + + len = ltv->an_len - 4; + printf("an%d: RID %4x, Length %4d, Mode %s\n", + sc->an_unit, ltv->an_type, ltv->an_len - 4, string); + + if (an_dump == 1 || (an_dump == ltv->an_type)) { + printf("an%d:\t", sc->an_unit); + bzero(buf,sizeof(buf)); + + ptr2 = (u_int8_t *)<v->an_val; + for (i = len; i > 0; i--) { + printf("%02x ", *ptr2); + + temp = *ptr2++; + if (temp >= ' ' && temp <= '~') + buf[count] = temp; + else if (temp >= 'A' && temp <= 'Z') + buf[count] = temp; + else + buf[count] = '.'; + if (++count == 16) { + count = 0; + printf("%s\n",buf); + printf("an%d:\t", sc->an_unit); + bzero(buf,sizeof(buf)); + } + } + for (; count != 16; count++) { + printf(" "); + } + printf(" %s\n",buf); + } +} + static int an_seek(sc, id, off, chan) struct an_softc *sc; int id, off, chan; @@ -838,12 +910,11 @@ static int an_read_data(sc, id, off, buf, len) } ptr = (u_int16_t *)buf; - for (i = 0; i < len / 2; i++) - ptr[i] = CSR_READ_2(sc, AN_DATA1); - i*=2; - if (i<len){ - ptr2 = (u_int8_t *)buf; - ptr2[i] = CSR_READ_1(sc, AN_DATA1); + for (i = len; i > 1; i -= 2) + *ptr++ = CSR_READ_2(sc, AN_DATA1); + if (i) { + ptr2 = (u_int8_t *)ptr; + *ptr2 = CSR_READ_1(sc, AN_DATA1); } return(0); @@ -865,12 +936,11 @@ static int an_write_data(sc, id, off, buf, len) } ptr = (u_int16_t *)buf; - for (i = 0; i < (len / 2); i++) - CSR_WRITE_2(sc, AN_DATA0, ptr[i]); - i*=2; - if (i<len){ - ptr2 = (u_int8_t *)buf; - CSR_WRITE_1(sc, AN_DATA0, ptr2[i]); + for (i = len; i > 1; i -= 2) + CSR_WRITE_2(sc, AN_DATA0, *ptr++); + if (i) { + ptr2 = (u_int8_t *)ptr; + CSR_WRITE_1(sc, AN_DATA0, *ptr2); } return(0); @@ -1076,7 +1146,7 @@ static int an_ioctl(ifp, command, data) break; case SIOCGAIRONET: error = copyin(ifr->ifr_data, &areq, sizeof(areq)); - if (error) + if (error != 0) break; #ifdef ANCACHE if (areq.an_type == AN_RID_ZERO_CACHE) { @@ -1104,7 +1174,7 @@ static int an_ioctl(ifp, command, data) if ((error = suser(p))) goto out; error = copyin(ifr->ifr_data, &areq, sizeof(areq)); - if (error) + if (error != 0) break; an_setdef(sc, &areq); break; @@ -1112,7 +1182,7 @@ static int an_ioctl(ifp, command, data) areq.an_len = sizeof(areq); switch(ireq->i_type) { case IEEE80211_IOC_SSID: - if(ireq->i_val == -1) { + if (ireq->i_val == -1) { areq.an_type = AN_RID_STATUS; if (an_read_record(sc, (struct an_ltv_gen *)&areq)) { @@ -1121,20 +1191,20 @@ static int an_ioctl(ifp, command, data) } len = status->an_ssidlen; tmpptr = status->an_ssid; - } else if(ireq->i_val >= 0) { + } else if (ireq->i_val >= 0) { areq.an_type = AN_RID_SSIDLIST; if (an_read_record(sc, (struct an_ltv_gen *)&areq)) { error = EINVAL; break; } - if(ireq->i_val == 0) { + if (ireq->i_val == 0) { len = ssids->an_ssid1_len; tmpptr = ssids->an_ssid1; - } else if(ireq->i_val == 1) { + } else if (ireq->i_val == 1) { len = ssids->an_ssid2_len; tmpptr = ssids->an_ssid3; - } else if(ireq->i_val == 1) { + } else if (ireq->i_val == 1) { len = ssids->an_ssid3_len; tmpptr = ssids->an_ssid3; } else { @@ -1145,7 +1215,7 @@ static int an_ioctl(ifp, command, data) error = EINVAL; break; } - if(len > IEEE80211_NWID_LEN) { + if (len > IEEE80211_NWID_LEN) { error = EINVAL; break; } @@ -1165,8 +1235,8 @@ static int an_ioctl(ifp, command, data) error = EINVAL; break; } - if(config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) { - if(config->an_authtype & + if (config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) { + if (config->an_authtype & AN_AUTHTYPE_ALLOW_UNENCRYPTED) ireq->i_val = IEEE80211_WEP_MIXED; else @@ -1183,27 +1253,27 @@ static int an_ioctl(ifp, command, data) * ancontrol so it will have to do until we get * access to actual Cisco code. */ - if(ireq->i_val < 0 || ireq->i_val > 7) { + if (ireq->i_val < 0 || ireq->i_val > 7) { error = EINVAL; break; } len = 0; - if(ireq->i_val < 4) { + if (ireq->i_val < 4) { areq.an_type = AN_RID_WEP_TEMP; - for(i=0; i<4; i++) { - areq.an_len = sizeof(areq); + for (i = 0; i < 5; i++) { if (an_read_record(sc, (struct an_ltv_gen *)&areq)) { error = EINVAL; break; } - len = key->klen; - if(i == ireq->i_val) + if (key->kindex == 0xffff) break; + if (key->kindex == ireq->i_val) + len = key->klen; /* Required to get next entry */ areq.an_type = AN_RID_WEP_PERM; } - if(error) + if (error != 0) break; } /* We aren't allowed to read the value of the @@ -1219,6 +1289,25 @@ static int an_ioctl(ifp, command, data) ireq->i_val = 8; break; case IEEE80211_IOC_WEPTXKEY: + /* + * For some strange reason, you have to read all + * keys before you can read the txkey. + */ + areq.an_type = AN_RID_WEP_TEMP; + for (i = 0; i < 5; i++) { + if (an_read_record(sc, + (struct an_ltv_gen *)&areq)) { + error = EINVAL; + break; + } + if (key->kindex == 0xffff) + break; + /* Required to get next entry */ + areq.an_type = AN_RID_WEP_PERM; + } + if (error != 0) + break; + areq.an_type = AN_RID_WEP_PERM; key->kindex = 0xffff; if (an_read_record(sc, @@ -1277,13 +1366,13 @@ static int an_ioctl(ifp, command, data) error = EINVAL; break; } - if(config->an_psave_mode == AN_PSAVE_NONE) { + if (config->an_psave_mode == AN_PSAVE_NONE) { ireq->i_val = IEEE80211_POWERSAVE_OFF; - } else if(config->an_psave_mode == AN_PSAVE_CAM) { + } else if (config->an_psave_mode == AN_PSAVE_CAM) { ireq->i_val = IEEE80211_POWERSAVE_CAM; - } else if(config->an_psave_mode == AN_PSAVE_PSP) { + } else if (config->an_psave_mode == AN_PSAVE_PSP) { ireq->i_val = IEEE80211_POWERSAVE_PSP; - } else if(config->an_psave_mode == AN_PSAVE_PSP_CAM) { + } else if (config->an_psave_mode == AN_PSAVE_PSP_CAM) { ireq->i_val = IEEE80211_POWERSAVE_PSP_CAM; } else error = EINVAL; @@ -1326,7 +1415,7 @@ static int an_ioctl(ifp, command, data) error = EINVAL; break; } - if(ireq->i_len > IEEE80211_NWID_LEN) { + if (ireq->i_len > IEEE80211_NWID_LEN) { error = EINVAL; break; } @@ -1381,13 +1470,13 @@ static int an_ioctl(ifp, command, data) break; } error = copyin(ireq->i_data, tmpstr, 13); - if(error) + if (error != 0) break; bzero(&areq, sizeof(struct an_ltv_key)); 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) areq.an_type = AN_RID_WEP_TEMP; else areq.an_type = AN_RID_WEP_PERM; @@ -1395,7 +1484,7 @@ static int an_ioctl(ifp, command, data) bcopy(tmpstr, key->key, key->klen); break; case IEEE80211_IOC_WEPTXKEY: - if(ireq->i_val < 0 || ireq->i_val > 3) { + if (ireq->i_val < 0 || ireq->i_val > 3) { error = EINVAL; break; } @@ -1424,7 +1513,7 @@ static int an_ioctl(ifp, command, data) } break; case IEEE80211_IOC_STATIONNAME: - if(ireq->i_len > 16) { + if (ireq->i_len > 16) { error = EINVAL; break; } @@ -1478,7 +1567,7 @@ static int an_ioctl(ifp, command, data) out: AN_UNLOCK(sc); - return(error); + return(error != 0); } static int an_init_tx_ring(sc) @@ -1647,7 +1736,7 @@ static void an_start(ifp) tx_frame_802_3.an_tx_802_3_payload_len, (caddr_t)&sc->an_txbuf); - txcontrol=AN_TXCTL_8023; + txcontrol = AN_TXCTL_8023; /* write the txcontrol only */ an_write_data(sc, id, 0x08, (caddr_t)&txcontrol, sizeof(txcontrol)); @@ -1827,7 +1916,7 @@ void an_cache_store (sc, eh, m, rx_quality) int i; static int cache_slot = 0; /* use this cache entry */ static int wrapindex = 0; /* next "free" cache entry */ - int saanp=0; + int saanp = 0; /* filters: * 1. ip only @@ -1868,7 +1957,7 @@ void an_cache_store (sc, eh, m, rx_quality) * . MAC address is 6 bytes, * . var w_nextitem holds total number of entries already cached */ - for(i = 0; i < sc->an_nextitem; i++) { + for (i = 0; i < sc->an_nextitem; i++) { if (! bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc, 6 )) { /* Match!, * so we already have this entry, @@ -1988,7 +2077,7 @@ static void an_media_status(ifp, imr) imr->ifm_status = IFM_AVALID|IFM_ACTIVE; } - if(sc->an_tx_rate == 0) { + if (sc->an_tx_rate == 0) { imr->ifm_active = IFM_IEEE80211|IFM_AUTO; if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC) imr->ifm_active |= IFM_IEEE80211_ADHOC; diff --git a/sys/dev/an/if_anreg.h b/sys/dev/an/if_anreg.h index e86e354..e26561f 100644 --- a/sys/dev/an/if_anreg.h +++ b/sys/dev/an/if_anreg.h @@ -532,7 +532,7 @@ struct an_ltv_status { u_int16_t an_max_noise_prev_sec; /* 0x7A */ u_int16_t an_avg_noise_prev_min; /* 0x7C */ u_int16_t an_max_noise_prev_min; /* 0x7E */ - u_int16_t an_spare[3]; + u_int16_t an_spare[5]; }; #define AN_STATUS_OPMODE_CONFIGURED 0x0001 |