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

📄 wlandrv.c

📁 含有完整TCP/IP PPP协议的嵌入式操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
                }                break;            }            if (ic->ic_opmode == IEEE80211_M_STA) {                sc->sc_flags |= WI_FLAGS_OUTRANGE;            }            break;        case WI_INFO_LINK_STAT_DISCONNECTED:        case WI_INFO_LINK_STAT_ASSOC_FAILED:            if (ic->ic_opmode == IEEE80211_M_STA) {                ieee80211_new_state(ic, IEEE80211_S_INIT, -1);            }            break;        }        break;    case WI_INFO_COUNTERS:#if 0                           //@@MF later        /*         * I think we does not need the counter,         * therefore it can be take longer to implement it.         */        /*         * some card versions have a larger stats structure         */        len = min(le16toh(ltbuf[0]) - 1, sizeof(sc->sc_stats) / 4);        ptr = (u_int32_t *) & sc->sc_stats;        off = sizeof(ltbuf);        for (i = 0; i < len; i++, off += 2, ptr++) {            wi_read_bap(sc, fid, off, &stat, sizeof(stat));#ifdef WI_HERMES_STATS_WAR            if (stat & 0xf000) {                stat = ~stat;            }#endif            *ptr += stat;        }        ifp->if_collisions = sc->sc_stats.wi_tx_single_retries + sc->sc_stats.wi_tx_multi_retries + sc->sc_stats.wi_tx_retry_limit;#endif                          /* later */        break;#if 0                           //@@MF later    case WI_INFO_SCAN_RESULTS:    case WI_INFO_HOST_SCAN_RESULTS:        wi_scan_result(sc, fid, le16toh(ltbuf[0]));        break;#endif                          /* later */    default:        Debug(("wi_info_intr: got fid %x type %x len %d\n", fid, le16toh(ltbuf[1]), le16toh(ltbuf[0])));        break;    }    CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);}/************************************************************//*  wi_rx_intr                                              *//************************************************************/static NETBUF *wi_rx_intr(struct wi_softc *sc){    // struct ieee80211com *ic = &sc->sc_ic; /* Harald: Not used */    struct wi_frame frmhdr;    int fid, len, off;    u_int16_t status;    int error;    NETBUF *nb = 0;    LLCS_SNAP_HEADER *pLLCSSNAPHeader;    ETHERHDR LABBuffer;    ETHERHDR MAC802_3;    u_int8_t *pFrameBuffer = 0; /* Harald: Missing init */    u_int8_t *pBytePointer;    int copy_size = 0;          /* Harald: Missing init */    int size;    int IPFrame = 0;    if (sc->wi_gone) {        Debug(("wi_rx_intr gone\r\n"));        return (0);    }    fid = CSR_READ_2(sc, WI_RX_FID);    /*     * First read in the frame header     */    if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr))) {        CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);        Debug(("wi_rx_intr: read fid %x failed\n", fid));        return 0;    }    /*     * Drop undecryptable or packets with receive errors here     */    status = le16toh(frmhdr.wi_status);    if (status & WI_STAT_ERRSTAT) {        CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);        Debug(("wi_rx_intr: fid %x error status %x\n", fid, status));        return 0;    }    /*     * Catch the MAC 802.3 header     */    memcpy(MAC802_3.ether_dhost, frmhdr.wi_ehdr.ether_dhost, IEEE80211_ADDR_LEN);    memcpy(MAC802_3.ether_shost, frmhdr.wi_ehdr.ether_shost, IEEE80211_ADDR_LEN);    /*     * The ether_type comes later     */    /*     * Get the frame length, at this point I don't know     * if it is a RFC1024 or RFC894 frame. But Ethernut need     * an RFC894 frame! So we will alloc the NetBuffer later.     */    len = le16toh(frmhdr.wi_dat_len);    off = sizeof(frmhdr);    /*     * Sometimes the PRISM2.x returns bogusly large frames. Except     * in monitor mode, just throw them away.     */    if (len > WLAN_MAX_ETHERNET_FRAME_LEN) {        CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);        Debug(("wi_rx_intr: oversized packet\n"));        return (0);    }    /*     * First read the LookAheadBuffer     */    error = wi_read_bap(sc, fid, off, &LABBuffer, sizeof(LABBuffer));    off += sizeof(LABBuffer);    if (error == 0) {        /*         * Check if this is a 802.2 LLC 802.2 SNAP IP-Header RFC1024         */        pLLCSSNAPHeader = (LLCS_SNAP_HEADER *) & LABBuffer;        if ((pLLCSSNAPHeader->DSAPSSAP == 0xAAAA) && (pLLCSSNAPHeader->Control == 0x0003) && (pLLCSSNAPHeader->MustZero == 0x0000)) {            if ((pLLCSSNAPHeader->Type == 0x0608) || (pLLCSSNAPHeader->Type == 0x0008)) {#if (WLAN_ENABLE_RX_FRAME_DUMP >= 1)                Debug(("RFC1024 IP-Frame\n"));#endif                IPFrame = 1;                MAC802_3.ether_type = pLLCSSNAPHeader->Type;                /*                 * Now we can calculate the wFrameLength.                 * It is a RFC1042 Frame, and we must discard the:                 * DSAP, SSAP, cntl, and the org. code                 *  1  +  1  +  1        +  3  = 6                 */                len -= 6;                /*                 * The Ethernut need the dest and source address,                 * therefore add 12 again.                 */                len += 12;                /*                 * The MAC can not handle odd counts, test it.                 *                 */                len += 1;                len &= ~1;                /*                 * Now alloc the NetBuffer for Ethernut.                 */                nb = NutNetBufAlloc(0, NBAF_DATALINK, len);                if (nb != 0) {                    pFrameBuffer = nb->nb_dl.vp;                    /*                     * We must copy wFrameLength out of the MAC                     */                    copy_size = len;                    /*                     * Copy the MAC 802.3 Header                     */                    memcpy(pFrameBuffer, &MAC802_3, sizeof(MAC802_3));                    pFrameBuffer += sizeof(MAC802_3);                    copy_size -= sizeof(MAC802_3);      /* This was already in the WLANHeader */                    /*                     * Now we have some data in our LABBuffer which we need                     */                    pBytePointer = (BYTE *) & LABBuffer;                    /*                     * jump over the header                     */                    pBytePointer += sizeof(LLCS_SNAP_HEADER);                    /*                     * and copy the rest                     */                    size = sizeof(LABBuffer) - sizeof(LLCS_SNAP_HEADER);                    memcpy(pFrameBuffer, pBytePointer, size);                    /*                     * Change the pointer for the "global copy"                     */                    pFrameBuffer += size;                    copy_size -= size;  /* This was already in the LookAheadBuffer */                } else {                    IPFrame = 0;                }            }                   /* only ARP and IP */        } else {            /*             * Check if this is a RFX894 Frame             */            if ((LABBuffer.ether_type == 0x0608) || (LABBuffer.ether_type == 0x0008)) {#if (WLAN_ENABLE_RX_FRAME_DUMP >= 1)                Debug(("RFC894 IP-Frame\n"));#endif                IPFrame = 1;                /*                 * The MAC can not handle odd counts, test it.                 *                 */                len += 1;                len &= ~1;                /*                 * The FrameLength is now the correct length for an RFC894 Frame,                 * Now alloc the NetBuffer for Ethernut.                 */                nb = NutNetBufAlloc(0, NBAF_DATALINK, len);                if (nb != 0) {                    pFrameBuffer = nb->nb_dl.vp;                    /*                     * We must copy wFrameLength out of the MAC                     */                    copy_size = len;                    /*                     * The LookAheadBuffer is the MAC-Header                     */                    memcpy(pFrameBuffer, &LABBuffer, sizeof(LABBuffer));                    pFrameBuffer += sizeof(LABBuffer);                    copy_size -= sizeof(LABBuffer);     /* This was our LookAheadBuffer */                } else {                    IPFrame = 0;                }               /* NutNetBufAlloc */            }                   /* RFC894 Frame */        }                       /* Error read LookAheadBuffer */        /*         * Do the rest here, "global copy"         */        if (IPFrame == 1) {            error = wi_read_bap(sc, fid, off, pFrameBuffer, copy_size);            if (error != 0) {                NutNetBufFree(nb);                nb = NULL;            } else {#if (WLAN_ENABLE_RX_FRAME_DUMP >= 1)                Debug(("RxFrame: %d\n", len));                DumpWlanData(nb->nb_dl.vp, nb->nb_dl.sz);#endif            }        }    }    /*     * At least, send a ack for the event     */    CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);    return (nb);}/************************************************************//*  RxThread                                                *//************************************************************/THREAD(RxThread, arg){    NUTDEVICE *dev;    IFNET *ifn;    NETBUF *nb;    struct wi_softc *sc;    u_int16_t EventStatus;    dev = arg;    ifn = (IFNET *) dev->dev_icb;    sc = (struct wi_softc *) dev->dev_dcb;    for (;;) {        /*         * Wait for the arrival of new packets or check         * the receiver every two second.         */        NutEventWait(&sc->InterruptEvent, 2000);        EventStatus = sc->EventStatus;        /*         * Clear the sc-EventStatus. If the next time the         * EventStatus is 0, it was the timeout and not         * an interrupt.         */        sc->EventStatus = 0;        if (EventStatus != 0) {            if (EventStatus & WI_EV_RX) {                WI_LOCK(sc);                nb = wi_rx_intr(sc);                WI_UNLOCK(sc);                if (nb != 0) {                    (*ifn->if_recv) (dev, nb);                }            }            if (EventStatus & WI_EV_ALLOC) {                WI_LOCK(sc);                wi_tx_intr(sc);                WI_UNLOCK(sc);            }            if (EventStatus & WI_EV_INFO) {                WI_LOCK(sc);                wi_info_intr(sc);                WI_UNLOCK(sc);            }            if (EventStatus & WI_EV_TX_EXC) {                Debug(("WI_EV_TX_EXC\n"));            }            CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);        } else {            /*             * It was the timeout, check if the card is alive             */            if ((sc->sc_enabled == 1) && (sc->wi_gone == 1)) {                /*                 * The card was enabled but we has lost the card, reinit...                 */                Debug(("Houston, we have a problem...\n"));                sc->wi_gone = 0;                wlandrv_Init(dev);            }        }                       /* (EventStatus != 0) */    }                           /* for */}/************************************************************//*  wi_alloc_fid                                            *//************************************************************/static int wi_alloc_fid(struct wi_softc *sc, int len, int *idp){    unsigned long i;                     /* Harald: Changed from int to long */    									 /* Oliver: Changed from signed to unsigned */    if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) {        Debug(("failed to allocate %d bytes on NIC\n", len));        return ENOMEM;    }    for (i = 0; i < WI_TIMEOUT; i++) {        if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC) {            break;        }        if (i == WI_TIMEOUT) {            Debug(("timeout in alloc\n"));            return ETIMEDOUT;        }        DELAY(1);    }    *idp = CSR_READ_2(sc, WI_ALLOC_FID);    CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);    return 0;}/************************************************************//*  wi_write_ssid                                           *//************************************************************/static int wi_write_ssid(struct wi_softc *sc, int rid, u_int8_t * buf, int buflen){    struct wi_ssid ssid;    if (buflen > IEEE80211_NWID_LEN) {        return ENOBUFS;    }    memset(&ssid, 0, sizeof(ssid));    ssid.wi_len = htole16(buflen);    memcpy(ssid.wi_ssid, buf, buflen);    return wi_write_rid(sc, rid, &ssid, sizeof(ssid));

⌨️ 快捷键说明

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