⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wlandrv.c

📁 含有完整TCP/IP PPP协议的嵌入式操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
}/************************************************************//*  wi_read_nicid                                           *//************************************************************/static void wi_read_nicid(struct wi_softc *sc){    struct wi_card_ident *id;    char *p;    int len;    u_int16_t ver[4];    /*     * getting chip identity     */    memset(ver, 0, sizeof(ver));    len = sizeof(ver);    wi_read_rid(sc, WI_RID_CARD_ID, ver, &len);    Debug(("using "));    sc->sc_firmware_type = WI_NOTYPE;    for (id = wi_card_ident; id->card_name != NULL; id++) {        if (le16toh(ver[0]) == id->card_id) {            Debug(("%s", id->card_name));            sc->sc_firmware_type = id->firm_type;            break;        }    }    if (sc->sc_firmware_type == WI_NOTYPE) {        if (le16toh(ver[0]) & 0x8000) {            Debug(("Unknown PRISM2 chip"));            sc->sc_firmware_type = WI_INTERSIL;        } else {            Debug(("Unknown Lucent chip"));            sc->sc_firmware_type = WI_LUCENT;        }    }    /*     * get primary firmware version (Only Prism chips)     */    if (sc->sc_firmware_type != WI_LUCENT) {        memset(ver, 0, sizeof(ver));        len = sizeof(ver);        wi_read_rid(sc, WI_RID_PRI_IDENTITY, ver, &len);        sc->sc_pri_firmware_ver = le16toh(ver[2]) * 10000 + le16toh(ver[3]) * 100 + le16toh(ver[1]);    }    /*     * get station firmware version     */    memset(ver, 0, sizeof(ver));    len = sizeof(ver);    wi_read_rid(sc, WI_RID_STA_IDENTITY, ver, &len);    sc->sc_sta_firmware_ver = le16toh(ver[2]) * 10000 + le16toh(ver[3]) * 100 + le16toh(ver[1]);    if (sc->sc_firmware_type == WI_INTERSIL && (sc->sc_sta_firmware_ver == 10102 || sc->sc_sta_firmware_ver == 20102)) {        char ident[12];        memset(ident, 0, sizeof(ident));        len = sizeof(ident);        /*         * value should be the format like "V2.00-11"         */        if (wi_read_rid(sc, WI_RID_SYMBOL_IDENTITY, ident, &len) == 0 &&            *(p = (char *) ident) >= 'A' && p[2] == '.' && p[5] == '-' && p[8] == '\0') {            sc->sc_firmware_type = WI_SYMBOL;            sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 +                (p[3] - '0') * 1000 + (p[4] - '0') * 100 + (p[6] - '0') * 10 + (p[7] - '0');        }    }    Debug(("\n"));    Debug(("%s Firmware: ",           sc->sc_firmware_type == WI_LUCENT ? "Lucent" : (sc->sc_firmware_type == WI_SYMBOL ? "Symbol" : "Intersil")));    if (sc->sc_firmware_type != WI_LUCENT) {    /* XXX */        Debug(("Primary (%ld.%ld.%ld), ",               sc->sc_pri_firmware_ver / 10000, (sc->sc_pri_firmware_ver % 10000) / 100, sc->sc_pri_firmware_ver % 100));    }    Debug(("Station (%ld.%ld.%ld)\n",           sc->sc_sta_firmware_ver / 10000, (sc->sc_sta_firmware_ver % 10000) / 100, sc->sc_sta_firmware_ver % 100));}/************************************************************//*  wi_write_wep                                            *//************************************************************/static int wi_write_wep(struct wi_softc *sc){    struct ieee80211com *ic = &sc->sc_ic;    int error = 0;    int i, keylen;    u_int16_t val;    struct wi_key wkey[IEEE80211_WEP_NKID];    switch (sc->sc_firmware_type) {#if (WLAN_SUPPORT_LUCENT >= 1)    case WI_LUCENT:        val = (ic->ic_flags & IEEE80211_F_WEPON) ? 1 : 0;        error = wi_write_val(sc, WI_RID_ENCRYPTION, val);        if (error)            break;        error = wi_write_val(sc, WI_RID_TX_CRYPT_KEY, ic->ic_wep_txkey);        if (error)            break;        memset(wkey, 0, sizeof(wkey));        for (i = 0; i < IEEE80211_WEP_NKID; i++) {            keylen = ic->ic_nw_keys[i].wk_len;            wkey[i].wi_keylen = htole16(keylen);            memcpy(wkey[i].wi_keydat, ic->ic_nw_keys[i].wk_key, keylen);        }        error = wi_write_rid(sc, WI_RID_DEFLT_CRYPT_KEYS, wkey, sizeof(wkey));        break;#endif                          /* (WLAN_SUPPORT_LUCENT >= 1) */#if ((WLAN_SUPPORT_INTERSIL >= 1) || (WLAN_SUPPORT_SYMBOL >= 1))    case WI_INTERSIL:    case WI_SYMBOL:        if (ic->ic_flags & IEEE80211_F_WEPON) {            /*             * ONLY HWB3163 EVAL-CARD Firmware version             * less than 0.8 variant2             *             *   If promiscuous mode disable, Prism2 chip             *  does not work with WEP .             * It is under investigation for details.             * (ichiro@netbsd.org)             */            if (sc->sc_firmware_type == WI_INTERSIL && sc->sc_sta_firmware_ver < 802) {                /*                 * firm ver < 0.8 variant 2                 */                wi_write_val(sc, WI_RID_PROMISC, 1);            }            wi_write_val(sc, WI_RID_CNFAUTHMODE, sc->sc_cnfauthmode);            val = PRIVACY_INVOKED | EXCLUDE_UNENCRYPTED;            /*             * Encryption firmware has a bug for HostAP mode.             */            if (sc->sc_firmware_type == WI_INTERSIL && ic->ic_opmode == IEEE80211_M_HOSTAP) {                val |= HOST_ENCRYPT;            }        } else {            wi_write_val(sc, WI_RID_CNFAUTHMODE, IEEE80211_AUTH_OPEN);            val = HOST_ENCRYPT | HOST_DECRYPT;        }        error = wi_write_val(sc, WI_RID_P2_ENCRYPTION, val);        if (error) {            break;        }        error = wi_write_val(sc, WI_RID_P2_TX_CRYPT_KEY, ic->ic_wep_txkey);        if (error) {            break;        }        /*         * It seems that the firmware accept 104bit key only if         * all the keys have 104bit length.  We get the length of         * the transmit key and use it for all other keys.         * Perhaps we should use software WEP for such situation.         */        keylen = ic->ic_nw_keys[ic->ic_wep_txkey].wk_len;        if (keylen > IEEE80211_WEP_KEYLEN) {            keylen = 13;        /* 104bit keys */        } else {            keylen = IEEE80211_WEP_KEYLEN;        }        for (i = 0; i < IEEE80211_WEP_NKID; i++) {            error = wi_write_rid(sc, WI_RID_P2_CRYPT_KEY0 + i, ic->ic_nw_keys[i].wk_key, keylen);            if (error) {                break;            }        }        break;#endif                          /* ((WLAN_SUPPORT_INTERSIL >= 1) || (WLAN_SUPPORT_SYMBOL >= 1)) */    }    return error;}/*==========================================================*//*  DEFINE: All code exported                               *//*==========================================================*//************************************************************//*  wlandrv_ProbeDevice                                     *//*                                                          *//*  Make a HW-Reset and test if a card is available.        *//*                                                          *//*  Return: ERROR, OK                                       *//************************************************************/int wlandrv_ProbeDevice(void){    int error = -1;    u_int16_t Value;    /*     * Set RESET     */    RESET_EN_PORT |= RESET_BIT;    RESET_PORT |= RESET_BIT;    NutSleep(100);    /*     * Remove RESET     */    RESET_PORT &= ~RESET_BIT;    NutSleep(500);    /*     * Set the MAC into I/O mode     */    pcmcia_WriteMem(WI_COR_OFFSET, WI_COR_VALUE);    NutSleep(100);    /*     * Test if we can found a card     */    pcmcia_WriteReg(WI_HFA384X_SWSUPPORT0_OFF, WI_PRISM2STA_MAGIC);    Value = pcmcia_ReadReg(WI_HFA384X_SWSUPPORT0_OFF);    if (Value == WI_PRISM2STA_MAGIC) {        /*         * We found a card :-)         */        error = 0;    }    return (error);}/************************************************************//*  wlandrv_Attach                                          *//*                                                          *//*  Catch all information about the card which              *//*  could be found. And set some default parameter          *//*                                                          *//*  Return: ERROR, OK                                       *//************************************************************/int wlandrv_Attach(device_t dev){    struct wi_softc *sc = device_get_softc(dev);    struct ieee80211com *ic = &sc->sc_ic;    struct ieee80211_rateset *rs;    int i, nrates, buflen;    u_int16_t val;    u_int8_t ratebuf[2 + IEEE80211_RATE_SIZE];    //u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {    //  0x00, 0x00, 0x00, 0x00, 0x00, 0x00    //}; /* Harald: This is unused */    int error;    bDebugState = 2;    sc->wi_cmd_count = 500;    ic->ic_fixed_rate = -1;     /* auto */    /*     * Reset the NIC.     */    if (wi_reset(sc) != 0) {        return ENXIO;           /* XXX */    }    /*     * Read the station address.     * And do it twice. I've seen PRISM-based cards that return     * an error when trying to read it the first time, which causes     * the probe to fail.     */    buflen = IEEE80211_ADDR_LEN;    error = wi_read_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, &buflen);    if (error != 0) {        buflen = IEEE80211_ADDR_LEN;        error = wi_read_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, &buflen);    }    if (error != 0) {        Debug(("mac read failed %d\n", error));        return (error);    }    Debug(("802.11 address: %02X-%02X-%02X-%02X-%02X-%02X\n",           ic->ic_myaddr[0], ic->ic_myaddr[1], ic->ic_myaddr[2], ic->ic_myaddr[3], ic->ic_myaddr[4], ic->ic_myaddr[5]));    /*     * Read NIC identification     */    wi_read_nicid(sc);    ic->ic_opmode = IEEE80211_M_STA;    ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_AHDEMO;    ic->ic_state = IEEE80211_S_INIT;    /*     * Query the card for available channels.     */    buflen = sizeof(val);    if (wi_read_rid(sc, WI_RID_CHANNEL_LIST, &val, &buflen) != 0) {        val = htole16(0x1fff);  /* assume 1-13 */    }    if (val == 0) {        Debug(("wi_attach: no available channels listed!"));    }    ic->ChannelList = (val << 1);    /*     * Read the default channel from the NIC. This may vary     * depending on the country where the NIC was purchased, so     * we can't hard-code a default and expect it to work for     * everyone.     *     * If no channel is specified, let the 802.11 code select.     */    buflen = sizeof(val);    if (wi_read_rid(sc, WI_RID_OWN_CHNL, &val, &buflen) == 0) {        val = le16toh(val);        i = (1 << val);        if ((val > 16) || ((ic->ChannelList & i) == 0)) {            Debug(("wi_attach: invalid own channel %d!", val));        }        ic->ic_ibss_chan = val;    } else {        Debug(("WI_RID_OWN_CHNL failed, using first channel!\n"));        ic->ic_ibss_chan = 1;    }    /*     * Set flags based on firmware version.     */    switch (sc->sc_firmware_type) {#if (WLAN_SUPPORT_LUCENT >= 1)    case WI_LUCENT:        sc->sc_ntxbuf = 1;        sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;#ifdef WI_HERMES_AUTOINC_WAR        /*         * XXX: not confirmed, but never seen for recent firmware         */        if (sc->sc_sta_firmware_ver < 40000) {            sc->sc_flags |= WI_FLAGS_BUG_AUTOINC;        }#endif        if (sc->sc_sta_firmware_ver >= 60000) {            sc->sc_flags |= WI_FLAGS_HAS_MOR;        }        if (sc->sc_sta_firmware_ver >= 60006) {            ic->ic_caps |= IEEE80211_C_IBSS;            ic->ic_caps |= IEEE80211_C_MONITOR;        }        sc->sc_ibss_port = htole16(1);        sc->sc_min_rssi = WI_LUCENT_MIN_RSSI;        sc->sc_max_rssi = WI_LUCENT_MAX_RSSI;        sc->sc_dbm_offset = WI_LUCENT_DBM_OFFSET;        break;#endif                          /* (WLAN_SUPPORT_LUCENT >= 1) */#if (WLAN_SUPPORT_INTERSIL >= 1)    case WI_INTERSIL:        sc->sc_ntxbuf = WI_NTXBUF;        sc->sc_flags |= WI_FLAGS_HAS_FRAGTHR;        sc->sc_flags |= WI_FLAGS_HAS_ROAMING;        sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;        /*         * Old firmware are slow, so give peace a chance.         */        if (sc->sc_sta_firmware_ver < 10000) {            sc->wi_cmd_count = 5000;        }        if (sc->sc_sta_firmware_ver > 10101) {            sc->sc_flags |= WI_FLAGS_HAS_DBMADJUST;        }        if (sc->sc_sta_firmware_ver >= 800) {            ic->ic_caps |= IEEE80211_C_IBSS;            ic->ic_caps |= IEEE80211_C_MONITOR;        }        /*         * version 0.8.3 and newer are the only ones that are known         * to currently work.  Earlier versions can be made to work,         * at least according to the Linux driver.         */        if (sc->sc_sta_firmware_ver >= 803) {            ic->ic_caps |= IEEE80211_C_HOSTAP;        }        sc->sc_ibss_port = htole16(0);        sc->sc_min_rssi = WI_PRISM_MIN_RSSI;        sc->sc_max_rssi = WI_PRISM_MAX_RSSI;        sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET;        break;#endif                          /* (WLAN_SUPPORT_INTERSIL >= 1) */#if (WLAN_SUPPORT_SYMBOL >= 1)    case WI_SYMBOL:        sc->sc_ntxbuf = 1;        sc->sc_flags |= WI_FLAGS_HAS_DIVERSITY;        if (sc->sc_sta_firmware_ver >= 25000) {            ic->ic_caps |= IEEE80211_C_IBSS;        }        sc->sc_ibss_port = htole16(4);        sc->sc_min_rssi = WI_PRISM_MIN_RSSI;        sc->sc_max_rssi = WI_PRISM_MAX_RSSI;        sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -