📄 wlandrv.c
字号:
break;#endif /* (WLAN_SUPPORT_SYMBOL >= 1) */ } /* * Find out if we support WEP on this card. */ buflen = sizeof(val); if (wi_read_rid(sc, WI_RID_WEP_AVAIL, &val, &buflen) == 0 && val != htole16(0)) { ic->ic_caps |= IEEE80211_C_WEP; } /* * Find supported rates. */ buflen = sizeof(ratebuf); rs = &ic->ic_sup_rates[IEEE80211_MODE_11B]; if (wi_read_rid(sc, WI_RID_DATA_RATES, ratebuf, &buflen) == 0) { nrates = le16toh(*(u_int16_t *) ratebuf); if (nrates > IEEE80211_RATE_MAXSIZE) { nrates = IEEE80211_RATE_MAXSIZE; } rs->rs_nrates = 0; for (i = 0; i < nrates; i++) { if (ratebuf[2 + i]) { rs->rs_rates[rs->rs_nrates++] = ratebuf[2 + i]; } } } else { /* * XXX fallback on error? */ rs->rs_nrates = 0; } buflen = sizeof(val); if ((sc->sc_flags & WI_FLAGS_HAS_DBMADJUST) && wi_read_rid(sc, WI_RID_DBM_ADJUST, &val, &buflen) == 0) { sc->sc_dbm_offset = le16toh(val); } sc->sc_max_datalen = 2304; sc->sc_system_scale = 1; sc->sc_cnfauthmode = IEEE80211_AUTH_OPEN; sc->sc_roaming_mode = WI_DEFAULT_ROAMING; sc->sc_portnum = WI_DEFAULT_PORT; sc->sc_authtype = WI_DEFAULT_AUTHTYPE; /* * Init DeviceSemaphore */ NutEventPost(&hDeviceSemaphore); return (0);}/************************************************************//* wlandrv_Init *//************************************************************/void wlandrv_Init(device_t dev){ struct wi_softc *sc = device_get_softc(dev); struct ieee80211com *ic = &sc->sc_ic; int i; int error = 0, wasenabled; WI_LOCK(sc); if (sc->wi_gone) { WI_UNLOCK(sc); return; } if ((wasenabled = sc->sc_enabled)) { wi_stop(sc, 1); } wi_reset(sc); /* * common 802.11 configuration */ ic->ic_flags &= ~IEEE80211_F_IBSSON; sc->sc_flags &= ~WI_FLAGS_OUTRANGE; switch (ic->ic_opmode) { case IEEE80211_M_STA: wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_BSS); break; case IEEE80211_M_IBSS: wi_write_val(sc, WI_RID_PORTTYPE, sc->sc_ibss_port); ic->ic_flags |= IEEE80211_F_IBSSON; break; case IEEE80211_M_AHDEMO: wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC); break; case IEEE80211_M_HOSTAP: /* * For PRISM cards, override the empty SSID, because in * HostAP mode the controller will lock up otherwise. */ if (sc->sc_firmware_type == WI_INTERSIL && ic->ic_des_esslen == 0) { ic->ic_des_essid[0] = ' '; ic->ic_des_esslen = 1; } wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_HOSTAP); break; case IEEE80211_M_MONITOR: /* Harald: Should be handled. */#if 0 // @@MF this mode is not working with my card if (sc->sc_firmware_type == WI_LUCENT) { wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC); } error = wi_cmd(sc, WI_CMD_DEBUG | (WI_TEST_MONITOR << 8), 0, 0, 0);#endif break; } /* * Intersil interprets this RID as joining ESS even in IBSS mode */ if (sc->sc_firmware_type == WI_LUCENT && (ic->ic_flags & IEEE80211_F_IBSSON) && ic->ic_des_esslen > 0) { wi_write_val(sc, WI_RID_CREATE_IBSS, 1); } else { wi_write_val(sc, WI_RID_CREATE_IBSS, 0); }#if 0 //@@MF later wi_write_val(sc, WI_RID_MAX_SLEEP, ic->ic_lintval);#endif /* later */ wi_write_ssid(sc, WI_RID_DESIRED_SSID, ic->ic_des_essid, ic->ic_des_esslen); wi_write_val(sc, WI_RID_OWN_CHNL, ic->ic_ibss_chan); wi_write_ssid(sc, WI_RID_OWN_SSID, ic->ic_des_essid, ic->ic_des_esslen); wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, IEEE80211_ADDR_LEN); wi_write_val(sc, WI_RID_PM_ENABLED, (ic->ic_flags & IEEE80211_F_PMGTON) ? 1 : 0); /* * not yet common 802.11 configuration */ wi_write_val(sc, WI_RID_MAX_DATALEN, sc->sc_max_datalen);#if 0 //@@MF later wi_write_val(sc, WI_RID_RTS_THRESH, ic->ic_rtsthreshold); if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) { wi_write_val(sc, WI_RID_FRAG_THRESH, ic->ic_fragthreshold); }#endif /* later */ /* * driver specific 802.11 configuration */ if (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE) { wi_write_val(sc, WI_RID_SYSTEM_SCALE, sc->sc_system_scale); } if (sc->sc_flags & WI_FLAGS_HAS_ROAMING) { wi_write_val(sc, WI_RID_ROAMING_MODE, sc->sc_roaming_mode); } if (sc->sc_flags & WI_FLAGS_HAS_MOR) { wi_write_val(sc, WI_RID_MICROWAVE_OVEN, sc->sc_microwave_oven); } wi_write_txrate(sc);#if 0 //@@MF later /* * What is a nodename ??? :-( */ wi_write_ssid(sc, WI_RID_NODENAME, sc->sc_nodename, sc->sc_nodelen);#endif /* later */#if 0 //@@MF later /* * Does we realy need HOSTAP on Ethernut?? */ if (ic->ic_opmode == IEEE80211_M_HOSTAP && sc->sc_firmware_type == WI_INTERSIL) { wi_write_val(sc, WI_RID_OWN_BEACON_INT, ic->ic_lintval); wi_write_val(sc, WI_RID_BASIC_RATE, 0x03); /* 1, 2 */ wi_write_val(sc, WI_RID_SUPPORT_RATE, 0x0f); /* 1, 2, 5.5, 11 */ wi_write_val(sc, WI_RID_DTIM_PERIOD, 1); }#endif /* later */ /* * Initialize promisc mode. * Being in the Host-AP mode causes a great * deal of pain if primisc mode is set. * Therefore we avoid confusing the firmware * and always reset promisc mode in Host-AP * mode. Host-AP sees all the packets anyway. */ if ((ic->ic_opmode != IEEE80211_M_HOSTAP) && (sc->PromiscuousMode != 0)) { wi_write_val(sc, WI_RID_PROMISC, 1); } else { wi_write_val(sc, WI_RID_PROMISC, 0); } /* * Configure WEP. */ if (ic->ic_caps & IEEE80211_C_WEP) { wi_write_wep(sc); }#if 0 //@@MF later /* * Set multicast filter. */ wi_write_multi(sc);#endif /* later */ /* * Allocate fids for the card */ if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled) { sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame); if (sc->sc_firmware_type == WI_SYMBOL) { sc->sc_buflen = 1585; /* XXX */ } for (i = 0; i < sc->sc_ntxbuf; i++) { error = wi_alloc_fid(sc, sc->sc_buflen, &sc->sc_txd[i].d_fid); if (error) { Debug(("tx buffer allocation failed (error %u)\n", error)); goto out; } sc->sc_txd[i].d_len = 0; } } sc->sc_txcur = sc->sc_txnext = 0; /* * Enable desired port */ wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0); sc->sc_enabled = 1; if (ic->ic_opmode == IEEE80211_M_AHDEMO || ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_opmode == IEEE80211_M_HOSTAP) { ieee80211_new_state(ic, IEEE80211_S_RUN, -1); } /*************************************************************************/ /* Set interrupt and start RxThread */ /*************************************************************************/ if (sc->InterruptInitDone == 0) { sc->InterruptInitDone = 1; /* * Install WLAN interrupt */ PORTE |= 0x80; /* Enable PullUp */ error = NutRegisterIrqHandler(&sig_INTERRUPT7, WLANInterrupt, dev); if (error == FALSE) { EICR |= 0x80; // falling edge sbi(EIMSK, INT7); /* * Start the receiver thread. */ NutThreadCreate("rxi7", RxThread, dev, 640); } } /*************************************************************************/ /* * Enable interrupts */ CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); if (!wasenabled && ic->ic_opmode == IEEE80211_M_HOSTAP && sc->sc_firmware_type == WI_INTERSIL) { /* * XXX: some card need to be re-enabled for hostap */ wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0); wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0); }#if 0 //@@MF later /* * This is only for IEEE80211_M_STA */ if (ic->ic_opmode == IEEE80211_M_STA && ((ic->ic_flags & IEEE80211_F_DESBSSID) || ic->ic_des_chan != IEEE80211_CHAN_ANYC)) { memset(&join, 0, sizeof(join)); if (ic->ic_flags & IEEE80211_F_DESBSSID) IEEE80211_ADDR_COPY(&join.wi_bssid, ic->ic_des_bssid); if (ic->ic_des_chan != IEEE80211_CHAN_ANYC) join.wi_chan = htole16(ieee80211_chan2ieee(ic, ic->ic_des_chan)); /* * Lucent firmware does not support the JOIN RID. */ if (sc->sc_firmware_type != WI_LUCENT) wi_write_rid(sc, WI_RID_JOIN_REQ, &join, sizeof(join)); }#endif /* later */ WI_UNLOCK(sc); return; out: if (error) { Debug(("interface not running\n")); wi_stop(sc, 1); } WI_UNLOCK(sc); Debug(("wi_init: return %d\n", error)); return;}/************************************************************//* wlandrv_PutPacket *//************************************************************/int wlandrv_PutPacket(NUTDEVICE * dev, NETBUF * nb){ int error = -1; struct wi_softc *sc = (struct wi_softc *) dev->dev_dcb; struct wi_frame frmhdr; LLCS_SNAP_HEADER LLCSSNAPHeader; ETHERHDR *pMAC8023Header; int cur, fid, off, len; if (sc->wi_gone) { Debug(("wlandrv_PutPacket gone\r\n")); return (-1); } /* * Calculate the number of bytes to be send. Do not * send packets larger than 1518 bytes. */ len = nb->nb_dl.sz + nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz; if (len > 1518) { return (-1); } else { WI_LOCK(sc); /* * This is a RFC894 Frame from Ethernut */#if (WLAN_ENABLE_TX_FRAME_DUMP >= 1) Debug(("TxFrame: %d\n", len)); DumpWlanData(nb->nb_dl.vp, len);#endif /* * But we must send a RFC1024 Frame. * ETHERHDR is not part of an RFC1024 Frame */ len = len - sizeof(ETHERHDR); /* * Add RFC1024 Header */ len += sizeof(LLCS_SNAP_HEADER); /* * I do not know what I do here, therefore clear the header * and to hope for, the card will do the rest? */ memset(&frmhdr, 0, sizeof(frmhdr)); /* * Copy the Ethernut MAC 802.3 Dest/Source Address into the WLANHeader */ pMAC8023Header = (ETHERHDR *) nb->nb_dl.vp; frmhdr.wi_dat_len = len; memcpy(frmhdr.wi_ehdr.ether_dhost, pMAC8023Header->ether_dhost, IEEE80211_ADDR_LEN); memcpy(frmhdr.wi_ehdr.ether_shost, pMAC8023Header->ether_shost, IEEE80211_ADDR_LEN); frmhdr.wi_ehdr.ether_type = SWAP(len); /* * Prepare the RFC1024 Header */ LLCSSNAPHeader.DSAPSSAP = 0xAAAA; LLCSSNAPHeader.Control = 0x0003; LLCSSNAPHeader.MustZero = 0x0000; LLCSSNAPHeader.Type = pMAC8023Header->ether_type; /* * Get the TX-BUffer-ID */ cur = sc->sc_txcur; fid = sc->sc_txd[cur].d_fid; /* * And Copy the WLANHeader */ error = wi_write_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)); if (error == 0) { off = sizeof(frmhdr); /* * Now copy the RFC1024 Header */ error = wi_write_bap(sc, fid, off, &LLCSSNAPHeader, sizeof(LLCSSNAPHeader)); if (error == 0) { off += sizeof(LLCSSNAPHeader); /* * Copy the rest of the Ethernut Data */ if ((error == 0) && (nb->nb_nw.sz !
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -