hi i recently found messages about problems with the if_wi driver in 5.1 (it worked in 5.0-release).
i have a patch for this. it brings back missing features (wep, authmode etc). i could not test it for every possible case but it works fine for my network. regards bruno --- if_wi.c.orig Sun Jun 8 02:32:57 2003 +++ if_wi.c Sun Jun 8 02:33:20 2003 @@ -48,7 +48,7 @@ * without an NDA (if at all). What they do release is an API library * called the HCF (Hardware Control Functions) which is supposed to * do the device-specific operations of a device driver for you. The - * publically available version of the HCF library (the 'HCF Light') is + * publically available version of the HCF library (the 'HCF Light') is * a) extremely gross, b) lacks certain features, particularly support * for 802.11 frames, and c) is contaminated by the GNU Public License. * @@ -848,7 +848,7 @@ } IFQ_DEQUEUE(&ifp->if_snd, m0); ifp->if_opackets++; - m_copydata(m0, 0, ETHER_HDR_LEN, + m_copydata(m0, 0, ETHER_HDR_LEN, (caddr_t)&frmhdr.wi_ehdr); #if NBPFILTER > 0 BPF_MTAP(ifp, m0); @@ -858,7 +858,7 @@ ifp->if_oerrors++; continue; } - wh = mtod(m0, struct ieee80211_frame *); + wh = mtod(m0, struct ieee80211_frame *); if (ic->ic_opmode == IEEE80211_M_HOSTAP && !IEEE80211_IS_MULTICAST(wh->i_addr1) && (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == @@ -942,7 +942,7 @@ int i; int error = 0; int tries; - + /* Symbol firmware cannot be initialized more than once */ if (sc->sc_firmware_type == WI_SYMBOL && sc->sc_reset) return (0); @@ -1024,7 +1024,7 @@ struct ieee80211com *ic = &sc->sc_ic; struct ifreq *ifr = (struct ifreq *)data; struct ieee80211req *ireq; - u_int8_t nodename[IEEE80211_NWID_LEN]; + /* u_int8_t nodename[IEEE80211_NWID_LEN]; */ int error = 0; #if __FreeBSD_version >= 500000 struct thread *td = curthread; @@ -1032,6 +1032,10 @@ struct proc *td = curproc; /* Little white lie */ #endif struct wi_req wreq; + + char tmpkey[IEEE80211_KEYBUF_SIZE]; + int len; + WI_LOCK_DECL(); WI_LOCK(sc); @@ -1112,11 +1116,80 @@ case SIOCG80211: ireq = (struct ieee80211req *) data; switch (ireq->i_type) { + case IEEE80211_IOC_SSID: + if ((ireq->i_val == -1) || (ireq->i_val == 0)) { + error = copyout(sc->sc_net_name, + ireq->i_data, + IEEE80211_NWID_LEN); + ireq->i_len = IEEE80211_NWID_LEN; + } else + error = EINVAL; + break; + case IEEE80211_IOC_NUMSSIDS: + ireq->i_val = 1; + break; + case IEEE80211_IOC_WEP: + if (!(sc->sc_ic.ic_flags & IEEE80211_F_HASWEP)) { + ireq->i_val = IEEE80211_WEP_NOSUP; + } else { + if (sc->sc_ic.ic_flags & IEEE80211_F_WEPON) { + ireq->i_val = + IEEE80211_WEP_MIXED; + } else { + ireq->i_val = + IEEE80211_WEP_OFF; + } + } + break; + case IEEE80211_IOC_WEPKEY: + if (!(sc->sc_ic.ic_flags & IEEE80211_F_HASWEP) || + ireq->i_val < 0 || ireq->i_val > 3) { + error = EINVAL; + break; + } + len = sc->sc_ic.ic_nw_keys[ireq->i_val].wk_len; + if (suser(td)) + bcopy(sc->sc_ic.ic_nw_keys[ireq->i_val].wk_key, + &tmpkey, len); + else + bzero(&tmpkey, len); + + ireq->i_len = len; + error = copyout(&tmpkey, ireq->i_data, len); + + break; + case IEEE80211_IOC_NUMWEPKEYS: + if (!(sc->sc_ic.ic_flags & IEEE80211_F_HASWEP)) + error = EINVAL; + else + ireq->i_val = 4; + break; + case IEEE80211_IOC_WEPTXKEY: + if (!(sc->sc_ic.ic_flags & IEEE80211_F_HASWEP)) + error = EINVAL; + else + ireq->i_val = sc->sc_ic.ic_wep_txkey; + break; + case IEEE80211_IOC_AUTHMODE: + ireq->i_val = sc->sc_cnfauthmode; + break; case IEEE80211_IOC_STATIONNAME: ireq->i_len = sc->sc_nodelen + 1; error = copyout(sc->sc_nodename, ireq->i_data, ireq->i_len); break; + case IEEE80211_IOC_CHANNEL: + ireq->i_val = sc->sc_ic.ic_ibss_chan; + break; + case IEEE80211_IOC_POWERSAVE: + if (sc->sc_ic.ic_flags & IEEE80211_F_PMGTON) + ireq->i_val = IEEE80211_POWERSAVE_ON; + else + ireq->i_val = IEEE80211_POWERSAVE_OFF; + break; + case IEEE80211_IOC_POWERSAVESLEEP: + ireq->i_val = sc->sc_ic.ic_lintval; + break; default: error = ieee80211_ioctl(ifp, cmd, data); break; @@ -1128,30 +1201,106 @@ break; ireq = (struct ieee80211req *) data; switch (ireq->i_type) { - case IEEE80211_IOC_STATIONNAME: + case IEEE80211_IOC_SSID: if (ireq->i_val != 0 || ireq->i_len > IEEE80211_NWID_LEN) { error = EINVAL; break; } - memset(nodename, 0, IEEE80211_NWID_LEN); - error = copyin(ireq->i_data, nodename, ireq->i_len); - if (error) + // We set both of them + bzero(sc->sc_net_name, IEEE80211_NWID_LEN); + error = copyin(ireq->i_data, + sc->sc_net_name, ireq->i_len); + bcopy(sc->sc_net_name, sc->sc_ic.ic_bss.ni_essid, IEEE80211_NWID_LEN); + break; + case IEEE80211_IOC_WEP: + /* + * These cards only support one mode so + * we just turn wep on what ever is + * passed in if it's not OFF. + */ + if (ireq->i_val == IEEE80211_WEP_OFF) { + sc->sc_ic.ic_flags = (sc->sc_ic.ic_flags | IEEE80211_F_WEPON) ^ IEEE80211_F_WEPON; + } else { + sc->sc_ic.ic_flags |= IEEE80211_F_WEPON; + } + break; + case IEEE80211_IOC_WEPKEY: + if (ireq->i_val < 0 || ireq->i_val > 3 || + ireq->i_len > 13) { + error = EINVAL; + break; + } + bzero(sc->sc_ic.ic_nw_keys[ireq->i_val].wk_key, 13); + error = copyin(ireq->i_data, + sc->sc_ic.ic_nw_keys[ireq->i_val].wk_key, + ireq->i_len); + if(error) { + break; + } + sc->sc_ic.ic_nw_keys[ireq->i_val].wk_len = + ireq->i_len; + break; + case IEEE80211_IOC_WEPTXKEY: + if (ireq->i_val < 0 || ireq->i_val > 3) { + error = EINVAL; + break; + } + sc->sc_ic.ic_wep_txkey = ireq->i_val; + break; + case IEEE80211_IOC_AUTHMODE: + sc->sc_cnfauthmode = ireq->i_val; + break; + case IEEE80211_IOC_STATIONNAME: + if (ireq->i_len > 32) { + error = EINVAL; + break; + } + bzero(sc->sc_nodename, 32); + error = copyin(ireq->i_data, + sc->sc_nodename, ireq->i_len); + break; + case IEEE80211_IOC_CHANNEL: + /* + * The actual range is 1-14, but if you + * set it to 0 you get the default. So + * we let that work too. + */ + if (ireq->i_val < 0 || ireq->i_val > 14) { + error = EINVAL; + break; + } + sc->sc_ic.ic_ibss_chan = ireq->i_val; + break; + case IEEE80211_IOC_POWERSAVE: + switch (ireq->i_val) { + case IEEE80211_POWERSAVE_OFF: + sc->sc_ic.ic_flags = (sc->sc_ic.ic_flags | IEEE80211_F_PMGTON) ^ IEEE80211_F_PMGTON; + break; + case IEEE80211_POWERSAVE_ON: + sc->sc_ic.ic_flags |= IEEE80211_F_PMGTON; + break; + default: + error = EINVAL; break; - if (sc->sc_enabled) { - error = wi_write_ssid(sc, WI_RID_NODENAME, - nodename, ireq->i_len); - if (error) - break; } - memcpy(sc->sc_nodename, nodename, IEEE80211_NWID_LEN); - sc->sc_nodelen = ireq->i_len; + break; + case IEEE80211_IOC_POWERSAVESLEEP: + if (ireq->i_val < 0) { + error = EINVAL; + break; + } + sc->sc_ic.ic_lintval= ireq->i_val; break; default: error = ieee80211_ioctl(ifp, cmd, data); break; } + + /* Reinitialize WaveLAN. */ + //wi_init(sc); break; + default: error = ieee80211_ioctl(ifp, cmd, data); break; @@ -2146,7 +2295,7 @@ { int i, s = 0; static volatile int count = 0; - + if (count > 0) panic("Hey partner, hold on there!"); count++; @@ -2904,7 +3053,7 @@ (const uint16_t *)p, len / 2); p += len; } - + /* * PDR: id[4], address[4], length[4]; */ _______________________________________________ [EMAIL PROTECTED] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"