On Fri, Oct 12, 2007 at 05:55:21PM +0200, Reyk Floeter wrote:
> People who had problems with unsupported Atheros devices (single chip
> variants found in recent laptops, macbooks, etc.) should get the
> latest code from CVS and test it... I was able to make 11b mode work
> on at least two different new-age chipsets:
> 
> ath0 at pci2 dev 0 function 0 "Atheros AR5212 (IBM MiniPCI)" rev 0x01: apic 1 
> int 17 (irq 11)
> ath0: ARxxxx 10.3 phy 6.1 rf 10.2, WOR2W, address 00:16:cf:ab:4c:97
> ath1 at cardbus0 dev 0 function 0 "Atheros Communications, Inc., 
> AR5001-0000-0000, Wireless LAN Reference Card": irq 10
> ath1: AR5413 10.5 phy 6.1 rf 6.3, WOR0W, address 00:12:bf:0e:7d:36
> 
> Thanks again to Dave Del Debbio and David Menzel for donating me PCI
> Express MiniCards for testing and development.
> 
> But there are still some known problems:
> 
> - The ath0 device sometimes runs into a hardware-locking RX overrun
> bug. The only way to recover the device is to _cold_ start the
> computer.  Use "ifconfig ath0 debug" and look for "rx FIFO overrun;
> resetting".
> 
> - The devices sometimes need a long time to calibrate, just associate
> and wait some seconds before trying your first ping.
> 
> - The offset is not alway right, I'm trying to find a better way to
> set the channels correctly. See the attached commit message for more info.
> 
> - more...?
> 
> Hacked and tested in the Melbourne Museum during the AUUG 2007...
> 

ok, it appears that the offset varies in some cases and there needs to
be some sort of calibration. you can use the attached diff to adjust
the offset to make it work - this is really only for testing and not
for the tree.

for example, here in the melbourne museum i have to adjust the offset
by 5MHz to be able to join the public wireless network:

# ifconfig ath1 chanoff 5 down up                                               
                      
# ifconfig ath1           
ath1: flags=8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:12:bf:0e:7d:36
        groups: wlan egress
        media: IEEE802.11 autoselect (DS2 mode 11b)
        status: active
        ieee80211: nwid museumpublic chan 1 (offset 5) bssid 00:12:a9:4f:2a:82 
82%
        inet6 fe80::212:bfff:fe0e:7d36%ath1 prefixlen 64 scopeid 0x5
        inet 136.154.47.89 netmask 0xffffff00 broadcast 136.154.47.255

if you experience any problems, try to set the chanoff to positive or
negative numbers and send me some feedback.

reyk

Index: sbin/ifconfig/ifconfig.c
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.188
diff -u -p -r1.188 ifconfig.c
--- sbin/ifconfig/ifconfig.c    9 Oct 2007 21:41:54 -0000       1.188
+++ sbin/ifconfig/ifconfig.c    13 Oct 2007 01:41:55 -0000
@@ -154,6 +154,7 @@ void        setifnwid(const char *, int);
 void   setifbssid(const char *, int);
 void   setifnwkey(const char *, int);
 void   setifchan(const char *, int);
+void   setifchanoff(const char *, int);
 void   setiftxpower(const char *, int);
 void   setifpowersave(const char *, int);
 void   setifpowersavesleep(const char *, int);
@@ -283,6 +284,8 @@ const struct        cmd {
        { "-nwkey",     -1,             0,              setifnwkey },
        { "chan",       NEXTARG,        0,              setifchan },
        { "-chan",      -1,             0,              setifchan },
+       { "chanoff",    NEXTARG,        0,              setifchanoff },
+       { "-chanoff",   -1,             0,              setifchanoff },
        { "powersave",  1,              0,              setifpowersave },
        { "-powersave", 0,              0,              setifpowersave },
        { "powersavesleep", NEXTARG,    0,              setifpowersavesleep },
@@ -1417,6 +1420,27 @@ setifchan(const char *val, int d)
                warn("SIOCS80211CHANNEL");
 }
 
+void
+setifchanoff(const char *val, int d)
+{
+       const char *errstr;
+       int off;
+
+       if (d != 0)
+               off = 0;
+       else {
+               off = strtonum(val, -5000, 5000, &errstr);
+               if (errstr) {
+                       warnx("wrong channel offset %s: %s", errstr, val);
+                       return;
+               }
+       }
+
+       ifr.ifr_metric = off;
+       if (ioctl(s, SIOCSIFGENERIC, (caddr_t)&ifr) == -1)
+               warn("SIOCSIFGENERIC(chanoff)");
+}
+
 #ifndef SMALL
 void
 setiftxpower(const char *val, int d)
@@ -1516,7 +1540,7 @@ setifpowersavesleep(const char *val, int
 void
 ieee80211_status(void)
 {
-       int len, i, nwkey_verbose, inwid, inwkey, ichan, ipwr, ibssid, itxpower;
+       int len, i, nwkey_verbose, inwid, inwkey, ichan, ipwr, ibssid, 
itxpower, ichanoff, chanoff;
        struct ieee80211_nwid nwid;
        struct ieee80211_nwkey nwkey;
        struct ieee80211_power power;
@@ -1546,6 +1570,12 @@ ieee80211_status(void)
        strlcpy(channel.i_name, name, sizeof(channel.i_name));
        ichan = ioctl(s, SIOCG80211CHANNEL, (caddr_t)&channel);
 
+       memset(&ifr, 0, sizeof(ifr));
+       strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+       ichanoff = ioctl(s, SIOCGIFGENERIC, (caddr_t)&ifr);
+       if (ichanoff == 0)
+               chanoff = ifr.ifr_metric;
+
        memset(&bssid, 0, sizeof(bssid));
        strlcpy(bssid.i_name, name, sizeof(bssid.i_name));
        ibssid = ioctl(s, SIOCG80211BSSID, &bssid);
@@ -1573,6 +1603,8 @@ ieee80211_status(void)
        if (ichan == 0 && channel.i_channel != 0 &&
            channel.i_channel != (u_int16_t)-1)
                printf(" chan %u", channel.i_channel);
+       if (ichanoff == 0)
+               printf(" (offset %d)", chanoff);
 
        memset(&zero_bssid, 0, sizeof(zero_bssid));
        if (ibssid == 0 &&
Index: sys/dev/ic/ath.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/ath.c,v
retrieving revision 1.68
diff -u -p -r1.68 ath.c
--- sys/dev/ic/ath.c    1 Oct 2007 04:03:51 -0000       1.68
+++ sys/dev/ic/ath.c    13 Oct 2007 01:42:06 -0000
@@ -1050,6 +1050,7 @@ int
 ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 {
        struct ath_softc *sc = ifp->if_softc;
+       struct ath_hal *ah = sc->sc_ah;
        struct ieee80211com *ic = &sc->sc_ic;
        struct ifreq *ifr = (struct ifreq *)data;
        struct ifaddr *ifa = (struct ifaddr *)data;
@@ -1113,6 +1114,18 @@ ath_ioctl(struct ifnet *ifp, u_long cmd,
        case SIOCGATHSTATS:
                error = copyout(&sc->sc_stats,
                    ifr->ifr_data, sizeof (sc->sc_stats));
+               break;
+       case SIOCSIFGENERIC:
+               if (ifp->if_flags & IFF_DEBUG)
+                       printf("%s: setting channel offset: %d -> %d\n",
+                           ifp->if_xname, ah->ah_chanoff, ifr->ifr_metric);
+               ah->ah_chanoff = ifr->ifr_metric;
+               break;
+       case SIOCGIFGENERIC:
+               if (ifp->if_flags & IFF_DEBUG)
+                       printf("%s: returning channel offset: %d\n",
+                           ifp->if_xname, ah->ah_chanoff);
+               ifr->ifr_metric = ah->ah_chanoff;
                break;
        default:
                error = ieee80211_ioctl(ifp, cmd, data);

Reply via email to