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]"

Reply via email to