if_an.c (74698) | if_an.c (77217) |
---|---|
1/* 2 * Copyright (c) 1997, 1998, 1999 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 * | 1/* 2 * Copyright (c) 1997, 1998, 1999 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 * |
32 * $FreeBSD: head/sys/dev/an/if_an.c 74698 2001-03-23 17:46:32Z archie $ | 32 * $FreeBSD: head/sys/dev/an/if_an.c 77217 2001-05-26 09:27:08Z phk $ |
33 */ 34 35/* 36 * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD. 37 * 38 * Written by Bill Paul <wpaul@ctr.columbia.edu> 39 * Electrical Engineering Department 40 * Columbia University, New York City --- 67 unchanged lines hidden (view full) --- 108#include <sys/mutex.h> 109#include <machine/resource.h> 110 111#include <net/if.h> 112#include <net/if_arp.h> 113#include <net/ethernet.h> 114#include <net/if_dl.h> 115#include <net/if_types.h> | 33 */ 34 35/* 36 * Aironet 4500/4800 802.11 PCMCIA/ISA/PCI driver for FreeBSD. 37 * 38 * Written by Bill Paul <wpaul@ctr.columbia.edu> 39 * Electrical Engineering Department 40 * Columbia University, New York City --- 67 unchanged lines hidden (view full) --- 108#include <sys/mutex.h> 109#include <machine/resource.h> 110 111#include <net/if.h> 112#include <net/if_arp.h> 113#include <net/ethernet.h> 114#include <net/if_dl.h> 115#include <net/if_types.h> |
116#include <net/if_ieee80211.h> 117#include <net/if_media.h> |
|
116 117#ifdef INET 118#include <netinet/in.h> 119#include <netinet/in_systm.h> 120#include <netinet/in_var.h> 121#include <netinet/ip.h> 122#endif 123 124#include <net/bpf.h> 125 126#include <machine/md_var.h> 127 128#include <dev/an/if_aironet_ieee.h> 129#include <dev/an/if_anreg.h> 130 131#if !defined(lint) 132static const char rcsid[] = | 118 119#ifdef INET 120#include <netinet/in.h> 121#include <netinet/in_systm.h> 122#include <netinet/in_var.h> 123#include <netinet/ip.h> 124#endif 125 126#include <net/bpf.h> 127 128#include <machine/md_var.h> 129 130#include <dev/an/if_aironet_ieee.h> 131#include <dev/an/if_anreg.h> 132 133#if !defined(lint) 134static const char rcsid[] = |
133 "$FreeBSD: head/sys/dev/an/if_an.c 74698 2001-03-23 17:46:32Z archie $"; | 135 "$FreeBSD: head/sys/dev/an/if_an.c 77217 2001-05-26 09:27:08Z phk $"; |
134#endif 135 136/* These are global because we need them in sys/pci/if_an_p.c. */ 137static void an_reset __P((struct an_softc *)); 138static int an_ioctl __P((struct ifnet *, u_long, caddr_t)); 139static void an_init __P((void *)); 140static int an_init_tx_ring __P((struct an_softc *)); 141static void an_start __P((struct ifnet *)); --- 13 unchanged lines hidden (view full) --- 155static int an_alloc_nicmem __P((struct an_softc *, int, int *)); 156static void an_stats_update __P((void *)); 157static void an_setdef __P((struct an_softc *, struct an_req *)); 158#ifdef ANCACHE 159static void an_cache_store __P((struct an_softc *, struct ether_header *, 160 struct mbuf *, unsigned short)); 161#endif 162 | 136#endif 137 138/* These are global because we need them in sys/pci/if_an_p.c. */ 139static void an_reset __P((struct an_softc *)); 140static int an_ioctl __P((struct ifnet *, u_long, caddr_t)); 141static void an_init __P((void *)); 142static int an_init_tx_ring __P((struct an_softc *)); 143static void an_start __P((struct ifnet *)); --- 13 unchanged lines hidden (view full) --- 157static int an_alloc_nicmem __P((struct an_softc *, int, int *)); 158static void an_stats_update __P((void *)); 159static void an_setdef __P((struct an_softc *, struct an_req *)); 160#ifdef ANCACHE 161static void an_cache_store __P((struct an_softc *, struct ether_header *, 162 struct mbuf *, unsigned short)); 163#endif 164 |
165static int an_media_change __P((struct ifnet *)); 166static void an_media_status __P((struct ifnet *, struct ifmediareq *)); 167 |
|
163/* 164 * We probe for an Aironet 4500/4800 card by attempting to 165 * read the default SSID list. On reset, the first entry in 166 * the SSID list will contain the name "tsunami." If we don't 167 * find this, then there's no card present. 168 */ 169int an_probe(dev) 170 device_t dev; --- 204 unchanged lines hidden (view full) --- 375 sc->an_ssidlist.an_ssid1_len = strlen(AN_DEFAULT_NETNAME); 376 377 sc->an_config.an_opmode = 378 AN_OPMODE_INFRASTRUCTURE_STATION; 379 380 sc->an_tx_rate = 0; 381 bzero((char *)&sc->an_stats, sizeof(sc->an_stats)); 382 | 168/* 169 * We probe for an Aironet 4500/4800 card by attempting to 170 * read the default SSID list. On reset, the first entry in 171 * the SSID list will contain the name "tsunami." If we don't 172 * find this, then there's no card present. 173 */ 174int an_probe(dev) 175 device_t dev; --- 204 unchanged lines hidden (view full) --- 380 sc->an_ssidlist.an_ssid1_len = strlen(AN_DEFAULT_NETNAME); 381 382 sc->an_config.an_opmode = 383 AN_OPMODE_INFRASTRUCTURE_STATION; 384 385 sc->an_tx_rate = 0; 386 bzero((char *)&sc->an_stats, sizeof(sc->an_stats)); 387 |
388 ifmedia_init(&sc->an_ifmedia, 0, an_media_change, an_media_status); 389#define ADD(m, c) ifmedia_add(&sc->an_ifmedia, (m), (c), NULL) 390 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 391 IFM_IEEE80211_ADHOC, 0), 0); 392 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0); 393 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 394 IFM_IEEE80211_ADHOC, 0), 0); 395 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0); 396 if(sc->an_caps.an_rates[2] == AN_RATE_5_5MBPS) { 397 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 398 IFM_IEEE80211_ADHOC, 0), 0); 399 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0); 400 } 401 if(sc->an_caps.an_rates[3] == AN_RATE_11MBPS) { 402 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 403 IFM_IEEE80211_ADHOC, 0), 0); 404 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0); 405 } 406 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 407 IFM_IEEE80211_ADHOC, 0), 0); 408 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0); 409#undef ADD 410 ifmedia_set(&sc->an_ifmedia, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 411 0, 0)); 412 |
|
383 /* 384 * Call MI attach routine. 385 */ 386 ether_ifattach(ifp, ETHER_BPF_SUPPORTED); 387 callout_handle_init(&sc->an_stat_ch); 388 AN_UNLOCK(sc); 389 390 return(0); --- 317 unchanged lines hidden (view full) --- 708 } 709 710 /* 711 * Read the length and record type and make sure they 712 * match what we expect (this verifies that we have enough 713 * room to hold all of the returned data). 714 */ 715 len = CSR_READ_2(sc, AN_DATA1); | 413 /* 414 * Call MI attach routine. 415 */ 416 ether_ifattach(ifp, ETHER_BPF_SUPPORTED); 417 callout_handle_init(&sc->an_stat_ch); 418 AN_UNLOCK(sc); 419 420 return(0); --- 317 unchanged lines hidden (view full) --- 738 } 739 740 /* 741 * Read the length and record type and make sure they 742 * match what we expect (this verifies that we have enough 743 * room to hold all of the returned data). 744 */ 745 len = CSR_READ_2(sc, AN_DATA1); |
716 if (len > ltv->an_len) { | 746 if (len > (ltv->an_len - 2)) { |
717 printf("an%d: record length mismatch -- expected %d, " | 747 printf("an%d: record length mismatch -- expected %d, " |
718 "got %d\n", sc->an_unit, ltv->an_len, len); 719 return(ENOSPC); | 748 "got %d\n", sc->an_unit, (ltv->an_len - 2), len); 749 len = (ltv->an_len - 2); |
720 } 721 722 ltv->an_len = len; 723 724 /* Now read the data. */ 725 ptr = <v->an_val; 726 for (i = 0; i < (ltv->an_len - 2) >> 1; i++) 727 ptr[i] = CSR_READ_2(sc, AN_DATA1); --- 248 unchanged lines hidden (view full) --- 976} 977 978static int an_ioctl(ifp, command, data) 979 struct ifnet *ifp; 980 u_long command; 981 caddr_t data; 982{ 983 int error = 0; | 750 } 751 752 ltv->an_len = len; 753 754 /* Now read the data. */ 755 ptr = <v->an_val; 756 for (i = 0; i < (ltv->an_len - 2) >> 1; i++) 757 ptr[i] = CSR_READ_2(sc, AN_DATA1); --- 248 unchanged lines hidden (view full) --- 1006} 1007 1008static int an_ioctl(ifp, command, data) 1009 struct ifnet *ifp; 1010 u_long command; 1011 caddr_t data; 1012{ 1013 int error = 0; |
1014 int len; 1015 int i; |
|
984 struct an_softc *sc; 985 struct an_req areq; 986 struct ifreq *ifr; 987 struct proc *p = curproc; | 1016 struct an_softc *sc; 1017 struct an_req areq; 1018 struct ifreq *ifr; 1019 struct proc *p = curproc; |
1020 struct ieee80211req *ireq; 1021 u_int8_t tmpstr[IEEE80211_NWID_LEN*2]; 1022 u_int8_t *tmpptr; 1023 struct an_ltv_genconfig *config; 1024 struct an_ltv_key *key; 1025 struct an_ltv_status *status; 1026 struct an_ltv_ssidlist *ssids; |
|
988 989 sc = ifp->if_softc; 990 AN_LOCK(sc); 991 ifr = (struct ifreq *)data; | 1027 1028 sc = ifp->if_softc; 1029 AN_LOCK(sc); 1030 ifr = (struct ifreq *)data; |
1031 ireq = (struct ieee80211req *)data; |
|
992 | 1032 |
1033 config = (struct an_ltv_genconfig *)&areq; 1034 key = (struct an_ltv_key *)&areq; 1035 status = (struct an_ltv_status *)&areq; 1036 ssids = (struct an_ltv_ssidlist *)&areq; 1037 |
|
993 if (sc->an_gone) { 994 error = ENODEV; 995 goto out; 996 } 997 998 switch(command) { 999 case SIOCSIFADDR: 1000 case SIOCGIFADDR: --- 14 unchanged lines hidden (view full) --- 1015 an_init(sc); 1016 } else { 1017 if (ifp->if_flags & IFF_RUNNING) 1018 an_stop(sc); 1019 } 1020 sc->an_if_flags = ifp->if_flags; 1021 error = 0; 1022 break; | 1038 if (sc->an_gone) { 1039 error = ENODEV; 1040 goto out; 1041 } 1042 1043 switch(command) { 1044 case SIOCSIFADDR: 1045 case SIOCGIFADDR: --- 14 unchanged lines hidden (view full) --- 1060 an_init(sc); 1061 } else { 1062 if (ifp->if_flags & IFF_RUNNING) 1063 an_stop(sc); 1064 } 1065 sc->an_if_flags = ifp->if_flags; 1066 error = 0; 1067 break; |
1068 case SIOCSIFMEDIA: 1069 case SIOCGIFMEDIA: 1070 error = ifmedia_ioctl(ifp, ifr, &sc->an_ifmedia, command); 1071 break; |
|
1023 case SIOCADDMULTI: 1024 case SIOCDELMULTI: 1025 /* The Aironet has no multicast filter. */ 1026 error = 0; 1027 break; 1028 case SIOCGAIRONET: 1029 error = copyin(ifr->ifr_data, &areq, sizeof(areq)); 1030 if (error) --- 23 unchanged lines hidden (view full) --- 1054 case SIOCSAIRONET: 1055 if ((error = suser(p))) 1056 goto out; 1057 error = copyin(ifr->ifr_data, &areq, sizeof(areq)); 1058 if (error) 1059 break; 1060 an_setdef(sc, &areq); 1061 break; | 1072 case SIOCADDMULTI: 1073 case SIOCDELMULTI: 1074 /* The Aironet has no multicast filter. */ 1075 error = 0; 1076 break; 1077 case SIOCGAIRONET: 1078 error = copyin(ifr->ifr_data, &areq, sizeof(areq)); 1079 if (error) --- 23 unchanged lines hidden (view full) --- 1103 case SIOCSAIRONET: 1104 if ((error = suser(p))) 1105 goto out; 1106 error = copyin(ifr->ifr_data, &areq, sizeof(areq)); 1107 if (error) 1108 break; 1109 an_setdef(sc, &areq); 1110 break; |
1111 case SIOCG80211: 1112 areq.an_len = sizeof(areq); 1113 switch(ireq->i_type) { 1114 case IEEE80211_IOC_SSID: 1115 if(ireq->i_val == -1) { 1116 areq.an_type = AN_RID_STATUS; 1117 if (an_read_record(sc, 1118 (struct an_ltv_gen *)&areq)) { 1119 error = EINVAL; 1120 break; 1121 } 1122 len = status->an_ssidlen; 1123 tmpptr = status->an_ssid; 1124 } else if(ireq->i_val >= 0) { 1125 areq.an_type = AN_RID_SSIDLIST; 1126 if (an_read_record(sc, 1127 (struct an_ltv_gen *)&areq)) { 1128 error = EINVAL; 1129 break; 1130 } 1131 if(ireq->i_val == 0) { 1132 len = ssids->an_ssid1_len; 1133 tmpptr = ssids->an_ssid1; 1134 } else if(ireq->i_val == 1) { 1135 len = ssids->an_ssid2_len; 1136 tmpptr = ssids->an_ssid3; 1137 } else if(ireq->i_val == 1) { 1138 len = ssids->an_ssid3_len; 1139 tmpptr = ssids->an_ssid3; 1140 } else { 1141 error = EINVAL; 1142 break; 1143 } 1144 } else { 1145 error = EINVAL; 1146 break; 1147 } 1148 if(len > IEEE80211_NWID_LEN) { 1149 error = EINVAL; 1150 break; 1151 } 1152 ireq->i_len = len; 1153 bzero(tmpstr, IEEE80211_NWID_LEN); 1154 bcopy(tmpptr, tmpstr, len); 1155 error = copyout(tmpstr, ireq->i_data, 1156 IEEE80211_NWID_LEN); 1157 break; 1158 case IEEE80211_IOC_NUMSSIDS: 1159 ireq->i_val = 3; 1160 break; 1161 case IEEE80211_IOC_WEP: 1162 areq.an_type = AN_RID_ACTUALCFG; 1163 if (an_read_record(sc, 1164 (struct an_ltv_gen *)&areq)) { 1165 error = EINVAL; 1166 break; 1167 } 1168 if(config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) { 1169 if(config->an_authtype & 1170 AN_AUTHTYPE_ALLOW_UNENCRYPTED) 1171 ireq->i_val = IEEE80211_WEP_MIXED; 1172 else 1173 ireq->i_val = IEEE80211_WEP_ON; 1174 1175 } else { 1176 ireq->i_val = IEEE80211_WEP_OFF; 1177 } 1178 break; 1179 case IEEE80211_IOC_WEPKEY: 1180 /* 1181 * XXX: I'm not entierly convinced this is 1182 * correct, but it's what is implemented in 1183 * ancontrol so it will have to do until we get 1184 * access to actual Cisco code. 1185 */ 1186 if(ireq->i_val < 0 || ireq->i_val > 7) { 1187 error = EINVAL; 1188 break; 1189 } 1190 len = 0; 1191 if(ireq->i_val < 4) { 1192 areq.an_type = AN_RID_WEP_TEMP; 1193 for(i=0; i<4; i++) { 1194 areq.an_len = sizeof(areq); 1195 if (an_read_record(sc, 1196 (struct an_ltv_gen *)&areq)) { 1197 error = EINVAL; 1198 break; 1199 } 1200 len = key->klen; 1201 if(i == ireq->i_val) 1202 break; 1203 /* Required to get next entry */ 1204 areq.an_type = AN_RID_WEP_PERM; 1205 } 1206 if(error) 1207 break; 1208 } 1209 /* We aren't allowed to read the value of the 1210 * key from the card so we just output zeros 1211 * like we would if we could read the card, but 1212 * denied the user access. 1213 */ 1214 bzero(tmpstr, len); 1215 ireq->i_len = len; 1216 error = copyout(tmpstr, ireq->i_data, len); 1217 break; 1218 case IEEE80211_IOC_NUMWEPKEYS: 1219 ireq->i_val = 8; 1220 break; 1221 case IEEE80211_IOC_WEPTXKEY: 1222 areq.an_type = AN_RID_WEP_PERM; 1223 key->kindex = 0xffff; 1224 if (an_read_record(sc, 1225 (struct an_ltv_gen *)&areq)) { 1226 error = EINVAL; 1227 break; 1228 } 1229 ireq->i_val = key->mac[0]; 1230 break; 1231 case IEEE80211_IOC_AUTHMODE: 1232 areq.an_type = AN_RID_ACTUALCFG; 1233 if (an_read_record(sc, 1234 (struct an_ltv_gen *)&areq)) { 1235 error = EINVAL; 1236 break; 1237 } 1238 if ((config->an_authtype & AN_AUTHTYPE_MASK) == 1239 AN_AUTHTYPE_NONE) { 1240 ireq->i_val = IEEE80211_AUTH_NONE; 1241 } else if ((config->an_authtype & AN_AUTHTYPE_MASK) == 1242 AN_AUTHTYPE_OPEN) { 1243 ireq->i_val = IEEE80211_AUTH_OPEN; 1244 } else if ((config->an_authtype & AN_AUTHTYPE_MASK) == 1245 AN_AUTHTYPE_SHAREDKEY) { 1246 ireq->i_val = IEEE80211_AUTH_SHARED; 1247 } else 1248 error = EINVAL; 1249 break; 1250 case IEEE80211_IOC_STATIONNAME: 1251 areq.an_type = AN_RID_ACTUALCFG; 1252 if (an_read_record(sc, 1253 (struct an_ltv_gen *)&areq)) { 1254 error = EINVAL; 1255 break; 1256 } 1257 ireq->i_len = sizeof(config->an_nodename); 1258 tmpptr = config->an_nodename; 1259 bzero(tmpstr, IEEE80211_NWID_LEN); 1260 bcopy(tmpptr, tmpstr, ireq->i_len); 1261 error = copyout(tmpstr, ireq->i_data, 1262 IEEE80211_NWID_LEN); 1263 break; 1264 case IEEE80211_IOC_CHANNEL: 1265 areq.an_type = AN_RID_STATUS; 1266 if (an_read_record(sc, 1267 (struct an_ltv_gen *)&areq)) { 1268 error = EINVAL; 1269 break; 1270 } 1271 ireq->i_val = status->an_cur_channel; 1272 break; 1273 case IEEE80211_IOC_POWERSAVE: 1274 areq.an_type = AN_RID_ACTUALCFG; 1275 if (an_read_record(sc, 1276 (struct an_ltv_gen *)&areq)) { 1277 error = EINVAL; 1278 break; 1279 } 1280 if(config->an_psave_mode == AN_PSAVE_NONE) { 1281 ireq->i_val = IEEE80211_POWERSAVE_OFF; 1282 } else if(config->an_psave_mode == AN_PSAVE_CAM) { 1283 ireq->i_val = IEEE80211_POWERSAVE_CAM; 1284 } else if(config->an_psave_mode == AN_PSAVE_PSP) { 1285 ireq->i_val = IEEE80211_POWERSAVE_PSP; 1286 } else if(config->an_psave_mode == AN_PSAVE_PSP_CAM) { 1287 ireq->i_val = IEEE80211_POWERSAVE_PSP_CAM; 1288 } else 1289 error = EINVAL; 1290 break; 1291 case IEEE80211_IOC_POWERSAVESLEEP: 1292 areq.an_type = AN_RID_ACTUALCFG; 1293 if (an_read_record(sc, 1294 (struct an_ltv_gen *)&areq)) { 1295 error = EINVAL; 1296 break; 1297 } 1298 ireq->i_val = config->an_listen_interval; 1299 break; 1300 } 1301 break; 1302 case SIOCS80211: 1303 if ((error = suser(p))) 1304 goto out; 1305 areq.an_len = sizeof(areq); 1306 /* 1307 * We need a config structure for everything but the WEP 1308 * key management and SSIDs so we get it now so avoid 1309 * duplicating this code every time. 1310 */ 1311 if (ireq->i_type != IEEE80211_IOC_SSID && 1312 ireq->i_type != IEEE80211_IOC_WEPKEY && 1313 ireq->i_type != IEEE80211_IOC_WEPTXKEY) { 1314 areq.an_type = AN_RID_GENCONFIG; 1315 if (an_read_record(sc, 1316 (struct an_ltv_gen *)&areq)) { 1317 error = EINVAL; 1318 break; 1319 } 1320 } 1321 switch(ireq->i_type) { 1322 case IEEE80211_IOC_SSID: 1323 areq.an_type = AN_RID_SSIDLIST; 1324 if (an_read_record(sc, 1325 (struct an_ltv_gen *)&areq)) { 1326 error = EINVAL; 1327 break; 1328 } 1329 if(ireq->i_len > IEEE80211_NWID_LEN) { 1330 error = EINVAL; 1331 break; 1332 } 1333 switch (ireq->i_val) { 1334 case 0: 1335 error = copyin(ireq->i_data, 1336 ssids->an_ssid1, ireq->i_len); 1337 ssids->an_ssid1_len = ireq->i_len; 1338 break; 1339 case 1: 1340 error = copyin(ireq->i_data, 1341 ssids->an_ssid2, ireq->i_len); 1342 ssids->an_ssid2_len = ireq->i_len; 1343 break; 1344 case 2: 1345 error = copyin(ireq->i_data, 1346 ssids->an_ssid3, ireq->i_len); 1347 ssids->an_ssid3_len = ireq->i_len; 1348 break; 1349 default: 1350 error = EINVAL; 1351 break; 1352 } 1353 break; 1354 case IEEE80211_IOC_WEP: 1355 switch (ireq->i_val) { 1356 case IEEE80211_WEP_OFF: 1357 config->an_authtype &= 1358 ~(AN_AUTHTYPE_PRIVACY_IN_USE | 1359 AN_AUTHTYPE_ALLOW_UNENCRYPTED); 1360 break; 1361 case IEEE80211_WEP_ON: 1362 config->an_authtype |= 1363 AN_AUTHTYPE_PRIVACY_IN_USE; 1364 config->an_authtype &= 1365 ~AN_AUTHTYPE_ALLOW_UNENCRYPTED; 1366 break; 1367 case IEEE80211_WEP_MIXED: 1368 config->an_authtype |= 1369 AN_AUTHTYPE_PRIVACY_IN_USE | 1370 AN_AUTHTYPE_ALLOW_UNENCRYPTED; 1371 break; 1372 default: 1373 error = EINVAL; 1374 break; 1375 } 1376 break; 1377 case IEEE80211_IOC_WEPKEY: 1378 if (ireq->i_val < 0 || ireq->i_val > 7 || 1379 ireq->i_len > 13) { 1380 error = EINVAL; 1381 break; 1382 } 1383 error = copyin(ireq->i_data, tmpstr, 13); 1384 if(error) 1385 break; 1386 bzero(&areq, sizeof(struct an_ltv_key)); 1387 areq.an_len = sizeof(struct an_ltv_key); 1388 key->mac[0] = 1; /* The others are 0. */ 1389 key->kindex = ireq->i_val % 4; 1390 if(ireq->i_val < 4) 1391 areq.an_type = AN_RID_WEP_TEMP; 1392 else 1393 areq.an_type = AN_RID_WEP_PERM; 1394 key->klen = ireq->i_len; 1395 bcopy(tmpstr, key->key, key->klen); 1396 break; 1397 case IEEE80211_IOC_WEPTXKEY: 1398 if(ireq->i_val < 0 || ireq->i_val > 3) { 1399 error = EINVAL; 1400 break; 1401 } 1402 bzero(&areq, sizeof(struct an_ltv_key)); 1403 areq.an_len = sizeof(struct an_ltv_key); 1404 areq.an_type = AN_RID_WEP_PERM; 1405 key->kindex = 0xffff; 1406 key->mac[0] = ireq->i_val; 1407 break; 1408 case IEEE80211_IOC_AUTHMODE: 1409 switch (ireq->i_val) { 1410 case IEEE80211_AUTH_NONE: 1411 config->an_authtype = AN_AUTHTYPE_NONE | 1412 (config->an_authtype & ~AN_AUTHTYPE_MASK); 1413 break; 1414 case IEEE80211_AUTH_OPEN: 1415 config->an_authtype = AN_AUTHTYPE_OPEN | 1416 (config->an_authtype & ~AN_AUTHTYPE_MASK); 1417 break; 1418 case IEEE80211_AUTH_SHARED: 1419 config->an_authtype = AN_AUTHTYPE_SHAREDKEY | 1420 (config->an_authtype & ~AN_AUTHTYPE_MASK); 1421 break; 1422 default: 1423 error = EINVAL; 1424 } 1425 break; 1426 case IEEE80211_IOC_STATIONNAME: 1427 if(ireq->i_len > 16) { 1428 error = EINVAL; 1429 break; 1430 } 1431 bzero(config->an_nodename, 16); 1432 error = copyin(ireq->i_data, 1433 config->an_nodename, ireq->i_len); 1434 break; 1435 case IEEE80211_IOC_CHANNEL: 1436 /* 1437 * The actual range is 1-14, but if you set it 1438 * to 0 you get the default so we let that work 1439 * too. 1440 */ 1441 if (ireq->i_val < 0 || ireq->i_val >14) { 1442 error = EINVAL; 1443 break; 1444 } 1445 config->an_ds_channel = ireq->i_val; 1446 break; 1447 case IEEE80211_IOC_POWERSAVE: 1448 switch (ireq->i_val) { 1449 case IEEE80211_POWERSAVE_OFF: 1450 config->an_psave_mode = AN_PSAVE_NONE; 1451 break; 1452 case IEEE80211_POWERSAVE_CAM: 1453 config->an_psave_mode = AN_PSAVE_CAM; 1454 break; 1455 case IEEE80211_POWERSAVE_PSP: 1456 config->an_psave_mode = AN_PSAVE_PSP; 1457 break; 1458 case IEEE80211_POWERSAVE_PSP_CAM: 1459 config->an_psave_mode = AN_PSAVE_PSP_CAM; 1460 break; 1461 default: 1462 error = EINVAL; 1463 break; 1464 } 1465 break; 1466 case IEEE80211_IOC_POWERSAVESLEEP: 1467 config->an_listen_interval = ireq->i_val; 1468 break; 1469 } 1470 1471 if (!error) 1472 an_setdef(sc, &areq); 1473 break; |
|
1062 default: 1063 error = EINVAL; 1064 break; 1065 } 1066out: 1067 AN_UNLOCK(sc); 1068 1069 return(error); --- 341 unchanged lines hidden (view full) --- 1411 struct mbuf *m; 1412 unsigned short rx_quality; 1413{ 1414 struct ip *ip = 0; 1415 int i; 1416 static int cache_slot = 0; /* use this cache entry */ 1417 static int wrapindex = 0; /* next "free" cache entry */ 1418 int saanp=0; | 1474 default: 1475 error = EINVAL; 1476 break; 1477 } 1478out: 1479 AN_UNLOCK(sc); 1480 1481 return(error); --- 341 unchanged lines hidden (view full) --- 1823 struct mbuf *m; 1824 unsigned short rx_quality; 1825{ 1826 struct ip *ip = 0; 1827 int i; 1828 static int cache_slot = 0; /* use this cache entry */ 1829 static int wrapindex = 0; /* next "free" cache entry */ 1830 int saanp=0; |
1831 int sig, noise; |
|
1419 1420 /* filters: 1421 * 1. ip only 1422 * 2. configurable filter to throw out unicast packets, 1423 * keep multicast only. 1424 */ 1425 1426 if ((ntohs(eh->ether_type) == 0x800)) { --- 91 unchanged lines hidden (view full) --- 1518 } 1519 bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc, 6); 1520 1521 sc->an_sigcache[cache_slot].signal = rx_quality; 1522 1523 return; 1524} 1525#endif | 1832 1833 /* filters: 1834 * 1. ip only 1835 * 2. configurable filter to throw out unicast packets, 1836 * keep multicast only. 1837 */ 1838 1839 if ((ntohs(eh->ether_type) == 0x800)) { --- 91 unchanged lines hidden (view full) --- 1931 } 1932 bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc, 6); 1933 1934 sc->an_sigcache[cache_slot].signal = rx_quality; 1935 1936 return; 1937} 1938#endif |
1939 1940static int an_media_change(ifp) 1941 struct ifnet *ifp; 1942{ 1943 struct an_softc *sc = ifp->if_softc; 1944 int otype = sc->an_config.an_opmode; 1945 int orate = sc->an_tx_rate; 1946 1947 if ((sc->an_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0) 1948 sc->an_config.an_opmode = AN_OPMODE_IBSS_ADHOC; 1949 else 1950 sc->an_config.an_opmode = AN_OPMODE_INFRASTRUCTURE_STATION; 1951 1952 switch (IFM_SUBTYPE(sc->an_ifmedia.ifm_cur->ifm_media)) { 1953 case IFM_IEEE80211_DS1: 1954 sc->an_tx_rate = AN_RATE_1MBPS; 1955 break; 1956 case IFM_IEEE80211_DS2: 1957 sc->an_tx_rate = AN_RATE_2MBPS; 1958 break; 1959 case IFM_IEEE80211_DS5: 1960 sc->an_tx_rate = AN_RATE_5_5MBPS; 1961 break; 1962 case IFM_IEEE80211_DS11: 1963 sc->an_tx_rate = AN_RATE_11MBPS; 1964 break; 1965 case IFM_AUTO: 1966 sc->an_tx_rate = 0; 1967 break; 1968 } 1969 1970 if (otype != sc->an_config.an_opmode || 1971 orate != sc->an_tx_rate) 1972 an_init(sc); 1973 1974 return(0); 1975} 1976 1977static void an_media_status(ifp, imr) 1978 struct ifnet *ifp; 1979 struct ifmediareq *imr; 1980{ 1981 struct an_ltv_status status; 1982 struct an_softc *sc = ifp->if_softc; 1983 1984 status.an_len = sizeof(status); 1985 status.an_type = AN_RID_STATUS; 1986 if (an_read_record(sc, (struct an_ltv_gen *)&status)) { 1987 /* If the status read fails, just lie. */ 1988 imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media; 1989 imr->ifm_status = IFM_AVALID|IFM_ACTIVE; 1990 } 1991 1992 if(sc->an_tx_rate == 0) { 1993 imr->ifm_active = IFM_IEEE80211|IFM_AUTO; 1994 if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC) 1995 imr->ifm_active |= IFM_IEEE80211_ADHOC; 1996 switch(status.an_current_tx_rate) { 1997 case AN_RATE_1MBPS: 1998 imr->ifm_active |= IFM_IEEE80211_DS1; 1999 break; 2000 case AN_RATE_2MBPS: 2001 imr->ifm_active |= IFM_IEEE80211_DS2; 2002 break; 2003 case AN_RATE_5_5MBPS: 2004 imr->ifm_active |= IFM_IEEE80211_DS5; 2005 break; 2006 case AN_RATE_11MBPS: 2007 imr->ifm_active |= IFM_IEEE80211_DS11; 2008 break; 2009 } 2010 } else { 2011 imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media; 2012 } 2013 2014 imr->ifm_status = IFM_AVALID; 2015 if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC) 2016 imr->ifm_status |= IFM_ACTIVE; 2017 else if (status.an_opmode & AN_STATUS_OPMODE_ASSOCIATED) 2018 imr->ifm_status |= IFM_ACTIVE; 2019} |
|