Deleted Added
full compact
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 = &ltv->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 = &ltv->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}