|
Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com |
[patch] - wi(4) ioctl(SIOC[G,S]80211CHANNEL) support
From: Jesper Louis Andersen (jlouis
mongers.org)
Date: Tue Oct 04 2005 - 11:10:08 CDT
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
The following patch is an attempt to begin streamlining the wi(4)
driver. Historically, I think we have awicontrol(8), wicontrol(8),
foocontrol(8) and the like, each controlling its own wifi-card via its
own, crufty ioctl(2) interface. This is god damn ugly, so it is very
nice to see ifconfig(8) being able to set values based on the ioctl
interface for ieee80211.
However, some (old) cards lacks this interface and we have to use
wicontrol and friends still. What a shame.
As far as I can see, the best plan is to build a layer, inside the
kernel, using the crufty ioctl-interface for retrieving information and
placing it in the new ieee80211 interface for ioctls. Then, when this
has happened, we can begin destroying the old, crufty interface (small
steps in the right direction rather than a giant errornous leap).
The patch enables the SIOCG80211CHANNEL and SIOCS80211CHANNEL ioctls to
be used with the wi(4) driver. It is a small change, but I would like
peoples comments on wether this is the correct way to proceed.
caveats:
We retrieve and set what is known as the IBSS channel. Not the
``current'' channel. I hope this is intended behaviour. What it means is
that the NIC can select some channel other than the IBSS (own) channel
and work on this other channel. Thus the ifconfig line:
ieee80211: nwid Andersen chan 3 -4dBm (auto)
Is a bit counter-intuitive since the real channel is 11 for the Andersen
nwid. Maybe it should be changed.
Further we can, with the wicontrol(8) -f parameter or via the following
patch, choose any 16-bit unsigned integer as the channel number. What
happens when you choose a channel, say, 32 is not known to me. But it is
possible. We could attempt a boundary check, but this differs from the
European region to the Northern America region due to differing channels
being allowed. So ultimately, we need to have this information somewhere.
Patch attached, comments welcome.
Index: if_wi.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/if_wi.c,v
retrieving revision 1.120
diff -u -r1.120 if_wi.c
--- if_wi.c 18 Sep 2005 09:24:03 -0000 1.120
+++ if_wi.c 4 Oct 2005 15:26:44 -0000

-162,6 +162,8 
STATIC void wi_media_status(struct ifnet *, struct ifmediareq *);
STATIC int wi_set_ssid(struct ieee80211_nwid *, u_int8_t *, int);
+STATIC int wi_set_chan(struct wi_softc *, struct ieee80211chanreq *);
+STATIC int wi_get_chan(struct wi_softc *, struct ieee80211chanreq *);
STATIC int wi_set_nwkey(struct wi_softc *, struct ieee80211_nwkey *);
STATIC int wi_get_nwkey(struct wi_softc *, struct ieee80211_nwkey *);
STATIC int wi_sync_media(struct wi_softc *, int, int);

-1800,6 +1802,14 
/* Reinitialize WaveLAN. */
wi_init(sc);
break;
+ case SIOCS80211CHANNEL:
+ if ((error = suser(curproc, 0)) != 0)
+ break;
+ error = wi_set_chan(sc, (struct ieee80211chanreq *)data);
+ break;
+ case SIOCG80211CHANNEL:
+ error = wi_get_chan(sc, (struct ieee80211chanreq *)data);
+ break;
case SIOCS80211NWKEY:
if ((error = suser(curproc, 0)) != 0)
break;

-2712,6 +2722,44 
letoh16(wreq.wi_val[0]) != 0)
imr->ifm_status |= IFM_ACTIVE;
}
+}
+
+STATIC int
+wi_get_chan(struct wi_softc *sc, struct ieee80211chanreq *chanreq)
+{
+ struct wi_req wreq;
+
+ bzero(&wreq, sizeof(wreq));
+ wreq.wi_len = WI_MAX_DATALEN;
+ wreq.wi_type = WI_RID_OWN_CHNL;
+
+ if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) {
+ return (EINVAL);
+ }
+
+ chanreq->i_channel = letoh16(wreq.wi_val[0]);
+ return (0);
+}
+
+STATIC int
+wi_set_chan(struct wi_softc *sc, struct ieee80211chanreq *chanreq)
+{
+ struct wi_req wreq;
+ int error;
+
+ bzero(&wreq, sizeof(wreq));
+ wreq.wi_type = WI_RID_OWN_CHNL;
+ wreq.wi_len = sizeof(u_int16_t);
+ wreq.wi_val[0] = htole16(chanreq->i_channel);
+
+ error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
+ if (!error)
+ error = wi_setdef(sc, &wreq);
+
+ if (!error && (sc->sc_arpcom.ac_if.if_flags & IFF_UP))
+ wi_init(sc);
+
+ return (error);
}
STATIC int
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]