if_wi patch
Ritz, Bruno
bruno_ritz at gmx.ch
Mon Jun 23 12:15:52 PDT 2003
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];
*/
More information about the freebsd-hackers
mailing list