Deleted Added
full compact
if_wi.c (76457) if_wi.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

--- 78 unchanged lines hidden (view full) ---

87#include <pci/pcivar.h>
88
89#include <net/if.h>
90#include <net/if_arp.h>
91#include <net/ethernet.h>
92#include <net/if_dl.h>
93#include <net/if_media.h>
94#include <net/if_types.h>
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

--- 78 unchanged lines hidden (view full) ---

87#include <pci/pcivar.h>
88
89#include <net/if.h>
90#include <net/if_arp.h>
91#include <net/ethernet.h>
92#include <net/if_dl.h>
93#include <net/if_media.h>
94#include <net/if_types.h>
95#include <net/if_ieee80211.h>
95
96#include <netinet/in.h>
97#include <netinet/in_systm.h>
98#include <netinet/in_var.h>
99#include <netinet/ip.h>
100#include <netinet/if_ether.h>
101
102#include <net/bpf.h>
103
104#include <dev/pccard/pccardvar.h>
105#include <dev/pccard/pccarddevs.h>
106
107#include <dev/wi/if_wavelan_ieee.h>
108#include <dev/wi/if_wireg.h>
109
110#include "card_if.h"
111
112#if !defined(lint)
113static const char rcsid[] =
96
97#include <netinet/in.h>
98#include <netinet/in_systm.h>
99#include <netinet/in_var.h>
100#include <netinet/ip.h>
101#include <netinet/if_ether.h>
102
103#include <net/bpf.h>
104
105#include <dev/pccard/pccardvar.h>
106#include <dev/pccard/pccarddevs.h>
107
108#include <dev/wi/if_wavelan_ieee.h>
109#include <dev/wi/if_wireg.h>
110
111#include "card_if.h"
112
113#if !defined(lint)
114static const char rcsid[] =
114 "$FreeBSD: head/sys/dev/wi/if_wi.c 76457 2001-05-11 07:06:06Z grog $";
115 "$FreeBSD: head/sys/dev/wi/if_wi.c 77217 2001-05-26 09:27:08Z phk $";
115#endif
116
117#ifdef foo
118static u_int8_t wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 };
119#endif
120
121static void wi_intr __P((void *));
122static void wi_reset __P((struct wi_softc *));

--- 33 unchanged lines hidden (view full) ---

156static int wi_pccard_attach __P((device_t));
157static int wi_pci_attach __P((device_t));
158static int wi_pccard_detach __P((device_t));
159static void wi_shutdown __P((device_t));
160
161static int wi_alloc __P((device_t, int));
162static void wi_free __P((device_t));
163
116#endif
117
118#ifdef foo
119static u_int8_t wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 };
120#endif
121
122static void wi_intr __P((void *));
123static void wi_reset __P((struct wi_softc *));

--- 33 unchanged lines hidden (view full) ---

157static int wi_pccard_attach __P((device_t));
158static int wi_pci_attach __P((device_t));
159static int wi_pccard_detach __P((device_t));
160static void wi_shutdown __P((device_t));
161
162static int wi_alloc __P((device_t, int));
163static void wi_free __P((device_t));
164
165static int wi_get_cur_ssid __P((struct wi_softc *, char *, int *));
166static int wi_media_change __P((struct ifnet *));
167static void wi_media_status __P((struct ifnet *, struct ifmediareq *));
168
164static device_method_t wi_pccard_methods[] = {
165 /* Device interface */
166 DEVMETHOD(device_probe, pccard_compat_probe),
167 DEVMETHOD(device_attach, pccard_compat_attach),
168 DEVMETHOD(device_detach, wi_pccard_detach),
169 DEVMETHOD(device_shutdown, wi_shutdown),
170
171 /* Card interface */

--- 105 unchanged lines hidden (view full) ---

277 if (sc->wi_gone) {
278 device_printf(dev, "already unloaded\n");
279 WI_UNLOCK(sc);
280 return(ENODEV);
281 }
282
283 wi_stop(sc);
284
169static device_method_t wi_pccard_methods[] = {
170 /* Device interface */
171 DEVMETHOD(device_probe, pccard_compat_probe),
172 DEVMETHOD(device_attach, pccard_compat_attach),
173 DEVMETHOD(device_detach, wi_pccard_detach),
174 DEVMETHOD(device_shutdown, wi_shutdown),
175
176 /* Card interface */

--- 105 unchanged lines hidden (view full) ---

282 if (sc->wi_gone) {
283 device_printf(dev, "already unloaded\n");
284 WI_UNLOCK(sc);
285 return(ENODEV);
286 }
287
288 wi_stop(sc);
289
290 /* Delete all remaining media. */
291 ifmedia_removeall(&sc->ifmedia);
292
285 ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
286 bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
287 wi_free(dev);
288 sc->wi_gone = 1;
289
290 WI_UNLOCK(sc);
291 mtx_destroy(&sc->wi_mtx);
292

--- 213 unchanged lines hidden (view full) ---

506 sc->wi_has_wep);
507 }
508
509 bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
510
511 wi_init(sc);
512 wi_stop(sc);
513
293 ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
294 bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
295 wi_free(dev);
296 sc->wi_gone = 1;
297
298 WI_UNLOCK(sc);
299 mtx_destroy(&sc->wi_mtx);
300

--- 213 unchanged lines hidden (view full) ---

514 sc->wi_has_wep);
515 }
516
517 bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
518
519 wi_init(sc);
520 wi_stop(sc);
521
522 ifmedia_init(&sc->ifmedia, 0, wi_media_change, wi_media_status);
523 /* XXX: Should read from card capabilities */
524#define ADD(m, c) ifmedia_add(&sc->ifmedia, (m), (c), NULL)
525 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
526 IFM_IEEE80211_ADHOC, 0), 0);
527 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0);
528 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
529 IFM_IEEE80211_ADHOC, 0), 0);
530 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0);
531 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
532 IFM_IEEE80211_ADHOC, 0), 0);
533 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0);
534 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
535 IFM_IEEE80211_ADHOC, 0), 0);
536 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0);
537 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
538 IFM_IEEE80211_ADHOC, 0), 0);
539 ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0);
540#undef ADD
541 ifmedia_set(&sc->ifmedia, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
542 0, 0));
543
544
514 /*
515 * Call MI attach routine.
516 */
517 ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
518 callout_handle_init(&sc->wi_stat_ch);
519 WI_UNLOCK(sc);
520
521 return(0);

--- 770 unchanged lines hidden (view full) ---

1292}
1293
1294static int wi_ioctl(ifp, command, data)
1295 struct ifnet *ifp;
1296 u_long command;
1297 caddr_t data;
1298{
1299 int error = 0;
545 /*
546 * Call MI attach routine.
547 */
548 ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
549 callout_handle_init(&sc->wi_stat_ch);
550 WI_UNLOCK(sc);
551
552 return(0);

--- 770 unchanged lines hidden (view full) ---

1323}
1324
1325static int wi_ioctl(ifp, command, data)
1326 struct ifnet *ifp;
1327 u_long command;
1328 caddr_t data;
1329{
1330 int error = 0;
1331 int len;
1332 u_int8_t tmpkey[14];
1333 char tmpssid[IEEE80211_NWID_LEN];
1300 struct wi_softc *sc;
1301 struct wi_req wreq;
1302 struct ifreq *ifr;
1334 struct wi_softc *sc;
1335 struct wi_req wreq;
1336 struct ifreq *ifr;
1337 struct ieee80211req *ireq;
1303 struct proc *p = curproc;
1304
1305 sc = ifp->if_softc;
1306 WI_LOCK(sc);
1307 ifr = (struct ifreq *)data;
1338 struct proc *p = curproc;
1339
1340 sc = ifp->if_softc;
1341 WI_LOCK(sc);
1342 ifr = (struct ifreq *)data;
1343 ireq = (struct ieee80211req *)data;
1308
1309 if (sc->wi_gone) {
1310 error = ENODEV;
1311 goto out;
1312 }
1313
1314 switch(command) {
1315 case SIOCSIFADDR:

--- 16 unchanged lines hidden (view full) ---

1332 } else {
1333 if (ifp->if_flags & IFF_RUNNING) {
1334 wi_stop(sc);
1335 }
1336 }
1337 sc->wi_if_flags = ifp->if_flags;
1338 error = 0;
1339 break;
1344
1345 if (sc->wi_gone) {
1346 error = ENODEV;
1347 goto out;
1348 }
1349
1350 switch(command) {
1351 case SIOCSIFADDR:

--- 16 unchanged lines hidden (view full) ---

1368 } else {
1369 if (ifp->if_flags & IFF_RUNNING) {
1370 wi_stop(sc);
1371 }
1372 }
1373 sc->wi_if_flags = ifp->if_flags;
1374 error = 0;
1375 break;
1376 case SIOCSIFMEDIA:
1377 case SIOCGIFMEDIA:
1378 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
1379 break;
1340 case SIOCADDMULTI:
1341 case SIOCDELMULTI:
1342 wi_setmulti(sc);
1343 error = 0;
1344 break;
1345 case SIOCGWAVELAN:
1346 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1347 if (error)

--- 45 unchanged lines hidden (view full) ---

1393 error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,
1394 wreq.wi_len);
1395 } else {
1396 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
1397 if (!error)
1398 wi_setdef(sc, &wreq);
1399 }
1400 break;
1380 case SIOCADDMULTI:
1381 case SIOCDELMULTI:
1382 wi_setmulti(sc);
1383 error = 0;
1384 break;
1385 case SIOCGWAVELAN:
1386 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1387 if (error)

--- 45 unchanged lines hidden (view full) ---

1433 error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,
1434 wreq.wi_len);
1435 } else {
1436 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
1437 if (!error)
1438 wi_setdef(sc, &wreq);
1439 }
1440 break;
1441 case SIOCG80211:
1442 switch(ireq->i_type) {
1443 case IEEE80211_IOC_SSID:
1444 if(ireq->i_val == -1) {
1445 bzero(tmpssid, IEEE80211_NWID_LEN);
1446 error = wi_get_cur_ssid(sc, tmpssid, &len);
1447 if (error != 0)
1448 break;
1449 error = copyout(tmpssid, ireq->i_data,
1450 IEEE80211_NWID_LEN);
1451 ireq->i_len = len;
1452 } else if (ireq->i_val == 0) {
1453 error = copyout(sc->wi_net_name,
1454 ireq->i_data,
1455 IEEE80211_NWID_LEN);
1456 ireq->i_len = IEEE80211_NWID_LEN;
1457 } else
1458 error = EINVAL;
1459 break;
1460 case IEEE80211_IOC_NUMSSIDS:
1461 ireq->i_val = 1;
1462 break;
1463 case IEEE80211_IOC_WEP:
1464 if(!sc->wi_has_wep) {
1465 ireq->i_val = IEEE80211_WEP_NOSUP;
1466 } else {
1467 if(sc->wi_use_wep) {
1468 ireq->i_val =
1469 IEEE80211_WEP_MIXED;
1470 } else {
1471 ireq->i_val =
1472 IEEE80211_WEP_OFF;
1473 }
1474 }
1475 break;
1476 case IEEE80211_IOC_WEPKEY:
1477 if(!sc->wi_has_wep ||
1478 ireq->i_val < 0 || ireq->i_val > 3) {
1479 error = EINVAL;
1480 break;
1481 }
1482 len = sc->wi_keys.wi_keys[ireq->i_val].wi_keylen;
1483 if (suser(p))
1484 bcopy(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat,
1485 tmpkey, len);
1486 else
1487 bzero(tmpkey, len);
1488
1489 ireq->i_len = len;
1490 error = copyout(tmpkey, ireq->i_data, len);
1491
1492 break;
1493 case IEEE80211_IOC_NUMWEPKEYS:
1494 if(!sc->wi_has_wep)
1495 error = EINVAL;
1496 else
1497 ireq->i_val = 4;
1498 break;
1499 case IEEE80211_IOC_WEPTXKEY:
1500 if(!sc->wi_has_wep)
1501 error = EINVAL;
1502 else
1503 ireq->i_val = sc->wi_tx_key;
1504 break;
1505 case IEEE80211_IOC_AUTHMODE:
1506 ireq->i_val = IEEE80211_AUTH_NONE;
1507 break;
1508 case IEEE80211_IOC_STATIONNAME:
1509 error = copyout(sc->wi_node_name,
1510 ireq->i_data, IEEE80211_NWID_LEN);
1511 ireq->i_len = IEEE80211_NWID_LEN;
1512 break;
1513 case IEEE80211_IOC_CHANNEL:
1514 wreq.wi_type = WI_RID_CURRENT_CHAN;
1515 wreq.wi_len = WI_MAX_DATALEN;
1516 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq))
1517 error = EINVAL;
1518 else {
1519 ireq->i_val = wreq.wi_val[0];
1520 }
1521 break;
1522 case IEEE80211_IOC_POWERSAVE:
1523 if(sc->wi_pm_enabled)
1524 ireq->i_val = IEEE80211_POWERSAVE_ON;
1525 else
1526 ireq->i_val = IEEE80211_POWERSAVE_OFF;
1527 break;
1528 case IEEE80211_IOC_POWERSAVESLEEP:
1529 ireq->i_val = sc->wi_max_sleep;
1530 break;
1531 default:
1532 error = EINVAL;
1533 }
1534 break;
1535 case SIOCS80211:
1536 if ((error = suser(p)))
1537 goto out;
1538 switch(ireq->i_type) {
1539 case IEEE80211_IOC_SSID:
1540 if (ireq->i_val != 0 ||
1541 ireq->i_len > IEEE80211_NWID_LEN) {
1542 error = EINVAL;
1543 break;
1544 }
1545 /* We set both of them */
1546 bzero(sc->wi_net_name, IEEE80211_NWID_LEN);
1547 error = copyin(ireq->i_data,
1548 sc->wi_net_name, ireq->i_len);
1549 bcopy(sc->wi_net_name, sc->wi_ibss_name, IEEE80211_NWID_LEN);
1550 break;
1551 case IEEE80211_IOC_WEP:
1552 /*
1553 * These cards only support one mode so
1554 * we just turn wep on what ever is
1555 * passed in if it's not OFF.
1556 */
1557 if (ireq->i_val == IEEE80211_WEP_OFF) {
1558 sc->wi_use_wep = 0;
1559 } else {
1560 sc->wi_use_wep = 1;
1561 }
1562 break;
1563 case IEEE80211_IOC_WEPKEY:
1564 if (ireq->i_val < 0 || ireq->i_val > 3 ||
1565 ireq->i_len > 13) {
1566 error = EINVAL;
1567 break;
1568 }
1569 bzero(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat, 13);
1570 error = copyin(ireq->i_data,
1571 sc->wi_keys.wi_keys[ireq->i_val].wi_keydat,
1572 ireq->i_len);
1573 if(error)
1574 break;
1575 sc->wi_keys.wi_keys[ireq->i_val].wi_keylen =
1576 ireq->i_len;
1577 break;
1578 case IEEE80211_IOC_WEPTXKEY:
1579 if (ireq->i_val < 0 || ireq->i_val > 3) {
1580 error = EINVAL;
1581 break;
1582 }
1583 sc->wi_tx_key = ireq->i_val;
1584 break;
1585 case IEEE80211_IOC_AUTHMODE:
1586 error = EINVAL;
1587 break;
1588 case IEEE80211_IOC_STATIONNAME:
1589 if (ireq->i_len > 32) {
1590 error = EINVAL;
1591 break;
1592 }
1593 bzero(sc->wi_node_name, 32);
1594 error = copyin(ireq->i_data,
1595 sc->wi_node_name, ireq->i_len);
1596 break;
1597 case IEEE80211_IOC_CHANNEL:
1598 /*
1599 * The actual range is 1-14, but if you
1600 * set it to 0 you get the default. So
1601 * we let that work too.
1602 */
1603 if (ireq->i_val < 0 || ireq->i_val > 14) {
1604 error = EINVAL;
1605 break;
1606 }
1607 sc->wi_channel = ireq->i_val;
1608 break;
1609 case IEEE80211_IOC_POWERSAVE:
1610 switch (ireq->i_val) {
1611 case IEEE80211_POWERSAVE_OFF:
1612 sc->wi_pm_enabled = 0;
1613 break;
1614 case IEEE80211_POWERSAVE_ON:
1615 sc->wi_pm_enabled = 1;
1616 break;
1617 default:
1618 error = EINVAL;
1619 break;
1620 }
1621 break;
1622 case IEEE80211_IOC_POWERSAVESLEEP:
1623 if (ireq->i_val < 0) {
1624 error = EINVAL;
1625 break;
1626 }
1627 sc->wi_max_sleep = ireq->i_val;
1628 break;
1629 default:
1630 error = EINVAL;
1631 break;
1632 }
1633
1634 /* Reinitialize WaveLAN. */
1635 wi_init(sc);
1636
1637 break;
1401 default:
1402 error = EINVAL;
1403 break;
1404 }
1405out:
1406 WI_UNLOCK(sc);
1407
1408 return(error);

--- 552 unchanged lines hidden (view full) ---

1961 noise = rx_quality & 0xFF;
1962 sc->wi_sigcache[cache_slot].signal = sig - 149;
1963 sc->wi_sigcache[cache_slot].noise = noise - 149;
1964 sc->wi_sigcache[cache_slot].quality = sig - noise;
1965
1966 return;
1967}
1968#endif
1638 default:
1639 error = EINVAL;
1640 break;
1641 }
1642out:
1643 WI_UNLOCK(sc);
1644
1645 return(error);

--- 552 unchanged lines hidden (view full) ---

2198 noise = rx_quality & 0xFF;
2199 sc->wi_sigcache[cache_slot].signal = sig - 149;
2200 sc->wi_sigcache[cache_slot].noise = noise - 149;
2201 sc->wi_sigcache[cache_slot].quality = sig - noise;
2202
2203 return;
2204}
2205#endif
2206
2207static int wi_get_cur_ssid(sc, ssid, len)
2208 struct wi_softc *sc;
2209 char *ssid;
2210 int *len;
2211{
2212 int error = 0;
2213 struct wi_req wreq;
2214
2215 wreq.wi_len = WI_MAX_DATALEN;
2216 switch (sc->wi_ptype) {
2217 case WI_PORTTYPE_ADHOC:
2218 wreq.wi_type = WI_RID_CURRENT_SSID;
2219 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq);
2220 if (error != 0)
2221 break;
2222 if (wreq.wi_val[0] > IEEE80211_NWID_LEN) {
2223 error = EINVAL;
2224 break;
2225 }
2226 *len = wreq.wi_val[0];
2227 bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN);
2228 break;
2229 case WI_PORTTYPE_BSS:
2230 wreq.wi_type = WI_RID_COMMQUAL;
2231 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq);
2232 if (error != 0)
2233 break;
2234 if (wreq.wi_val[0] != 0) /* associated */ {
2235 wreq.wi_type = WI_RID_CURRENT_SSID;
2236 wreq.wi_len = WI_MAX_DATALEN;
2237 error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq);
2238 if (error != 0)
2239 break;
2240 if (wreq.wi_val[0] > IEEE80211_NWID_LEN) {
2241 error = EINVAL;
2242 break;
2243 }
2244 *len = wreq.wi_val[0];
2245 bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN);
2246 } else {
2247 *len = IEEE80211_NWID_LEN;
2248 bcopy(sc->wi_net_name, ssid, IEEE80211_NWID_LEN);
2249 }
2250 break;
2251 default:
2252 error = EINVAL;
2253 break;
2254 }
2255
2256 return error;
2257}
2258
2259static int wi_media_change(ifp)
2260 struct ifnet *ifp;
2261{
2262 struct wi_softc *sc = ifp->if_softc;
2263 int otype = sc->wi_ptype;
2264 int orate = sc->wi_tx_rate;
2265
2266 if ((sc->ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0)
2267 sc->wi_ptype = WI_PORTTYPE_ADHOC;
2268 else
2269 sc->wi_ptype = WI_PORTTYPE_BSS;
2270
2271 switch (IFM_SUBTYPE(sc->ifmedia.ifm_cur->ifm_media)) {
2272 case IFM_IEEE80211_DS1:
2273 sc->wi_tx_rate = 1;
2274 break;
2275 case IFM_IEEE80211_DS2:
2276 sc->wi_tx_rate = 2;
2277 break;
2278 case IFM_IEEE80211_DS5:
2279 sc->wi_tx_rate = 5;
2280 break;
2281 case IFM_IEEE80211_DS11:
2282 sc->wi_tx_rate = 11;
2283 break;
2284 case IFM_AUTO:
2285 sc->wi_tx_rate = 3;
2286 break;
2287 }
2288
2289 if (otype != sc->wi_ptype ||
2290 orate != sc->wi_tx_rate)
2291 wi_init(sc);
2292
2293 return(0);
2294}
2295
2296static void wi_media_status(ifp, imr)
2297 struct ifnet *ifp;
2298 struct ifmediareq *imr;
2299{
2300 struct wi_req wreq;
2301 struct wi_softc *sc = ifp->if_softc;
2302
2303 if (sc->wi_tx_rate == 3) {
2304 imr->ifm_active = IFM_IEEE80211|IFM_AUTO;
2305 if (sc->wi_ptype == WI_PORTTYPE_ADHOC)
2306 imr->ifm_active |= IFM_IEEE80211_ADHOC;
2307 wreq.wi_type = WI_RID_CUR_TX_RATE;
2308 wreq.wi_len = WI_MAX_DATALEN;
2309 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0) {
2310 switch(wreq.wi_val[0]) {
2311 case 1:
2312 imr->ifm_active |= IFM_IEEE80211_DS1;
2313 break;
2314 case 2:
2315 imr->ifm_active |= IFM_IEEE80211_DS2;
2316 break;
2317 case 6:
2318 imr->ifm_active |= IFM_IEEE80211_DS5;
2319 break;
2320 case 11:
2321 imr->ifm_active |= IFM_IEEE80211_DS11;
2322 break;
2323 }
2324 }
2325 } else {
2326 imr->ifm_active = sc->ifmedia.ifm_cur->ifm_media;
2327 }
2328
2329 imr->ifm_status = IFM_AVALID;
2330 if (sc->wi_ptype == WI_PORTTYPE_ADHOC)
2331 /*
2332 * XXX: It would be nice if we could give some actually
2333 * useful status like whether we joined another IBSS or
2334 * created one ourselves.
2335 */
2336 imr->ifm_status |= IFM_ACTIVE;
2337 else {
2338 wreq.wi_type = WI_RID_COMMQUAL;
2339 wreq.wi_len = WI_MAX_DATALEN;
2340 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0 &&
2341 wreq.wi_val[0] != 0)
2342 imr->ifm_status |= IFM_ACTIVE;
2343 }
2344}