Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic * Add "wi_flags" to the softc to indicate capabil...



details:   https://anonhg.NetBSD.org/src/rev/9642c5f8a384
branches:  trunk
changeset: 535131:9642c5f8a384
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sun Aug 11 01:30:28 2002 +0000

description:
* Add "wi_flags" to the softc to indicate capabilities of the card.  Fill
  in this info based on firmware type and version.  Replace "wi_has_wep"
  with a flag.
* For cards which support IBSS, add "ibss" has a media option.
* For cards which support CREATE_IBSS, add "ibss-master" as a media
  option.
* Use the "ibss" and "ibss-master" media options to determine if
  we should go into IBSS mode and/or create the IBSS.
* Internally convert between the generic WI_PORTTYPE_IBSS and the
  value the firmware wants to use for IBSS.
* When setting the IBSS name, if a desired-SSID is set, and we're
  an ibss-master, write the desired-SSID into the own-SSID slot.
  This ensures that "ifconfig wi0 nwid FOO" will do the expected
  thing.
* Only set the roaming mode if the card supports roaming.

>From OpenBSD.

diffstat:

 sys/dev/ic/wi.c    |  189 ++++++++++++++++++++++++++++++++++++++++++++--------
 sys/dev/ic/wivar.h |   16 +++-
 2 files changed, 173 insertions(+), 32 deletions(-)

diffs (truncated from 410 to 300 lines):

diff -r 8ead85c0bc79 -r 9642c5f8a384 sys/dev/ic/wi.c
--- a/sys/dev/ic/wi.c   Sun Aug 11 00:11:52 2002 +0000
+++ b/sys/dev/ic/wi.c   Sun Aug 11 01:30:28 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wi.c,v 1.76 2002/08/11 00:11:52 thorpej Exp $  */
+/*     $NetBSD: wi.c,v 1.77 2002/08/11 01:30:28 thorpej Exp $  */
 
 /*
  * Copyright (c) 1997, 1998, 1999
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.76 2002/08/11 00:11:52 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.77 2002/08/11 01:30:28 thorpej Exp $");
 
 #define WI_HERMES_AUTOINC_WAR  /* Work around data write autoinc bug. */
 #define WI_HERMES_STATS_WAR    /* Work around stats counter bug. */
@@ -272,16 +272,52 @@
 
        /* AP info was filled with 0 */
        memset((char *)&sc->wi_aps, 0, sizeof(sc->wi_aps));
-       sc->wi_scanning=0;
-       sc->wi_naps=0;
+       sc->wi_scanning = 0;
+       sc->wi_naps = 0;
+
+       /*
+        * Set flags based on firmware version.
+        */
+       switch (sc->sc_firmware_type) {
+       case WI_LUCENT:
+               sc->wi_flags |= WI_FLAGS_HAS_ROAMING;
+               if (sc->sc_sta_firmware_ver >= 60000)
+                       sc->wi_flags |= WI_FLAGS_HAS_MOR;
+               if (sc->sc_sta_firmware_ver >= 60006) {
+                       sc->wi_flags |= WI_FLAGS_HAS_IBSS; 
+                       sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS;
+               }
+               sc->wi_ibss_port = htole16(1);
+               break;
+
+       case WI_INTERSIL:
+               sc->wi_flags |= WI_FLAGS_HAS_ROAMING;
+               if (sc->sc_sta_firmware_ver >= 800) {
+                       sc->wi_flags |= WI_FLAGS_HAS_HOSTAP;
+                       sc->wi_flags |= WI_FLAGS_HAS_IBSS;
+                       sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS;
+               }
+               sc->wi_ibss_port = htole16(0);
+               break;
+
+       case WI_SYMBOL:
+               sc->wi_flags |= WI_FLAGS_HAS_DIVERSITY;
+               if (sc->sc_sta_firmware_ver >= 20000)
+                       sc->wi_flags |= WI_FLAGS_HAS_IBSS;
+               if (sc->sc_sta_firmware_ver >= 25000)
+                       sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS;
+               sc->wi_ibss_port = htole16(4);
+               break;
+       }
 
        /*
         * Find out if we support WEP on this card.
         */
        gen.wi_type = WI_RID_WEP_AVAIL;
        gen.wi_len = 2;
-       wi_read_record(sc, &gen);
-       sc->wi_has_wep = le16toh(gen.wi_val);
+       if (wi_read_record(sc, &gen) == 0 &&
+           gen.wi_val != le16toh(0))
+               sc->wi_flags |= WI_FLAGS_HAS_WEP;
 
        /* Find supported rates (Prism2 only). */
        gen.wi_type = WI_RID_SUPPORT_RATE;
@@ -299,29 +335,59 @@
 #define        PRINT(n)        printf("%s%s", sep, (n)); sep = ", "
        ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0);
        ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_ADHOC, 0), 0);
+       if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
+               ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_IBSS,
+                   0), 0);
+       if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
+               ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
+                   IFM_IEEE80211_IBSSMASTER, 0), 0);
        if (sc->wi_supprates & WI_SUPPRATES_1M) {
                PRINT("1Mbps");
                ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0);
                ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
                    IFM_IEEE80211_ADHOC, 0), 0);
+               if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
+                       ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
+                           IFM_IEEE80211_IBSS, 0), 0);
+               if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
+                       ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
+                           IFM_IEEE80211_IBSSMASTER, 0), 0);
        }
        if (sc->wi_supprates & WI_SUPPRATES_2M) {
                PRINT("2Mbps");
                ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0);
                ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
                    IFM_IEEE80211_ADHOC, 0), 0);
+               if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
+                       ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
+                           IFM_IEEE80211_IBSS, 0), 0);
+               if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
+                       ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
+                           IFM_IEEE80211_IBSSMASTER, 0), 0);
        }
        if (sc->wi_supprates & WI_SUPPRATES_5M) {
                PRINT("5.5Mbps");
                ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0);
                ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
                    IFM_IEEE80211_ADHOC, 0), 0);
+               if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
+                       ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
+                           IFM_IEEE80211_IBSS, 0), 0);
+               if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
+                       ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
+                           IFM_IEEE80211_IBSSMASTER, 0), 0);
        }
        if (sc->wi_supprates & WI_SUPPRATES_11M) {
                PRINT("11Mbps");
                ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0);
                ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
                    IFM_IEEE80211_ADHOC, 0), 0);
+               if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
+                       ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
+                           IFM_IEEE80211_IBSS, 0), 0);
+               if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
+                       ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
+                           IFM_IEEE80211_IBSSMASTER, 0), 0);
                ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_MANUAL, 0, 0), 0);
        }
        if (sc->wi_supprates != 0)
@@ -956,7 +1022,16 @@
        if (ltv->wi_len > 1)
                CSR_READ_MULTI_STREAM_2(sc, WI_DATA1, ptr, ltv->wi_len - 1);
 
-       if (sc->sc_firmware_type != WI_LUCENT) {
+       if (ltv->wi_type == WI_RID_PORTTYPE &&
+           sc->wi_ptype == WI_PORTTYPE_IBSS &&
+           ltv->wi_val == sc->wi_ibss_port) {
+               /*
+                * Convert vendor IBSS port type to WI_PORTTYPE_IBSS.
+                * Since Lucent uses port type 1 for BSS *and* IBSS we
+                * have to rely on wi_ptype to distinguish this for us.
+                */
+               ltv->wi_val = htole16(WI_PORTTYPE_IBSS);
+       } else if (sc->sc_firmware_type != WI_LUCENT) {
                int v;
 
                switch (oltv->wi_type) {
@@ -1009,7 +1084,14 @@
        int                     i;
        struct wi_ltv_gen       p2ltv;
 
-       if (sc->sc_firmware_type != WI_LUCENT) {
+       if (ltv->wi_type == WI_RID_PORTTYPE &&
+           ltv->wi_val == le16toh(WI_PORTTYPE_IBSS)) {
+               /* Convert WI_PORTTYPE_IBSS to vendor IBSS port type. */
+               p2ltv.wi_type = WI_RID_PORTTYPE;
+               p2ltv.wi_len = 2;
+               p2ltv.wi_val = sc->wi_ibss_port;
+               ltv = &p2ltv;
+       } else if (sc->sc_firmware_type != WI_LUCENT) {
                int v;
 
                switch (ltv->wi_type) {
@@ -1313,10 +1395,12 @@
                memcpy(LLADDR(sdl), (char *)&wreq->wi_val, ETHER_ADDR_LEN);
                break;
        case WI_RID_PORTTYPE:
-               error = wi_sync_media(sc, le16toh(wreq->wi_val[0]), sc->wi_tx_rate);
+               error = wi_sync_media(sc, le16toh(wreq->wi_val[0]),
+                   sc->wi_tx_rate);
                break;
        case WI_RID_TX_RATE:
-               error = wi_sync_media(sc, sc->wi_ptype, le16toh(wreq->wi_val[0]));
+               error = wi_sync_media(sc, sc->wi_ptype,
+                   le16toh(wreq->wi_val[0]));
                break;
        case WI_RID_MAX_DATALEN:
                sc->wi_max_data_len = le16toh(wreq->wi_val[0]);
@@ -1328,8 +1412,8 @@
                sc->wi_ap_density = le16toh(wreq->wi_val[0]);
                break;
        case WI_RID_CREATE_IBSS:
-               if (sc->sc_firmware_type != WI_INTERSIL)
-                       sc->wi_create_ibss = le16toh(wreq->wi_val[0]);
+               sc->wi_create_ibss = le16toh(wreq->wi_val[0]);
+               error = wi_sync_media(sc, sc->wi_ptype, sc->wi_tx_rate);
                break;
        case WI_RID_OWN_CHNL:
                sc->wi_channel = le16toh(wreq->wi_val[0]);
@@ -1414,8 +1498,7 @@
                wreq->wi_val[0] = htole16(sc->wi_ap_density);
                break;
        case WI_RID_CREATE_IBSS:
-               if (sc->sc_firmware_type != WI_INTERSIL)
-                       wreq->wi_val[0] = htole16(sc->wi_create_ibss);
+               wreq->wi_val[0] = htole16(sc->wi_create_ibss);
                break;
        case WI_RID_OWN_CHNL:
                wreq->wi_val[0] = htole16(sc->wi_channel);
@@ -1445,7 +1528,8 @@
                wreq->wi_val[0] = htole16(sc->wi_roaming);
                break;
        case WI_RID_WEP_AVAIL:
-               wreq->wi_val[0] = htole16(sc->wi_has_wep);
+               wreq->wi_val[0] = (sc->wi_flags & WI_FLAGS_HAS_WEP) ?
+                   htole16(1) : htole16(0);
                break;
        case WI_RID_ENCRYPTION:
                wreq->wi_val[0] = htole16(sc->wi_use_wep);
@@ -1634,6 +1718,18 @@
                                }
                        }
                } else {
+                       /*
+                        * Filter stuff out based on what the
+                        * card can do.
+                        */
+                       if ((wreq.wi_type == WI_RID_ROAMING_MODE &&
+                            (sc->wi_flags & WI_FLAGS_HAS_ROAMING) == 0) ||
+                           (wreq.wi_type == WI_RID_CREATE_IBSS &&
+                            (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) == 0) ||
+                           (wreq.wi_type == WI_RID_MICROWAVE_OVEN &&
+                            (sc->wi_flags & WI_FLAGS_HAS_MOR) == 0))
+                               break;
+
                        if (wreq.wi_len > WI_MAX_DATALEN)
                                error = EINVAL;
                        else if (sc->sc_enabled != 0)
@@ -1728,8 +1824,7 @@
        WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
 
        /* Enable/disable IBSS creation. */
-       if (sc->sc_firmware_type != WI_INTERSIL)
-               WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
+       WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
 
        /* Set the port type. */
        WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
@@ -1750,14 +1845,19 @@
        WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
 
        /* Roaming type */
-       WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming);
-
-       /* Specify the IBSS name */
-       wi_write_ssid(sc, WI_RID_OWN_SSID, &wreq, &sc->wi_ibssid);
+       if (sc->wi_flags & WI_FLAGS_HAS_ROAMING)
+               WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming);
 
        /* Specify the network name */
        wi_write_ssid(sc, WI_RID_DESIRED_SSID, &wreq, &sc->wi_netid);
 
+       /* Specify the IBSS name */
+       if (sc->wi_netid.i_len != 0 &&
+           (sc->wi_create_ibss && sc->wi_ptype == WI_PORTTYPE_IBSS))
+               wi_write_ssid(sc, WI_RID_OWN_SSID, &wreq, &sc->wi_netid);
+       else
+               wi_write_ssid(sc, WI_RID_OWN_SSID, &wreq, &sc->wi_ibssid);
+
        /* Specify the frequency to use */
        WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel);
 
@@ -1778,7 +1878,7 @@
        }
 
        /* Configure WEP. */
-       if (sc->wi_has_wep) {
+       if (sc->wi_flags & WI_FLAGS_HAS_WEP) {
                WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
                WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
                sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1;
@@ -2267,12 +2367,20 @@
                subtype = IFM_MANUAL;           /* Unable to represent */
                break;
        }
+
+       options &= ~IFM_OMASK;
        switch (ptype) {
+       case WI_PORTTYPE_BSS:
+               /* default port type */
+               break;
        case WI_PORTTYPE_ADHOC:
                options |= IFM_IEEE80211_ADHOC;
                break;
-       case WI_PORTTYPE_BSS:
-               options &= ~IFM_IEEE80211_ADHOC;
+       case WI_PORTTYPE_IBSS:
+               if (sc->wi_create_ibss)
+                       options |= IFM_IEEE80211_IBSSMASTER;
+               else
+                       options |= IFM_IEEE80211_IBSS;
                break;
        default:
                subtype = IFM_MANUAL;           /* Unable to represent */



Home | Main Index | Thread Index | Old Index