Here are dmesg lines for Atheros wireless in my Acer Aspire One:
ath0 at pci3 dev 0 function 0 "Atheros AR5424" rev 0x01: apic 4 int 18 (irq 11)
ath0: AR5424 14.2 phy 7.0 rf 0.0, WOR5_ETSIC, address 00:22:69:4c:f5:20

Its EEPROM reports only 802.11g mode supported which is disabled in current 
kernel and this leaves hal->ah_capabilities.cap_mode zeroed, which in turn 
makes it unable to enumerate supported channels, also its hal->ah_radio 
detected as AR2425.
This patch fixes "unable to reset hardware" errors for me but I still can't 
make it associate with AP, although "tcpdump -eni ath0 -y ieee802_11_radio" 
shows wireless frames.

Index: sys/dev/ic/ar5212.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/ar5212.c,v
retrieving revision 1.51
diff -u -p -u -p -r1.51 ar5212.c
--- sys/dev/ic/ar5212.c 2 Jun 2009 12:39:02 -0000       1.51
+++ sys/dev/ic/ar5212.c 24 Apr 2010 15:13:06 -0000
@@ -2860,10 +2860,8 @@ ar5k_ar5212_get_capabilities(struct ath_
 
                if (b)
                        hal->ah_capabilities.cap_mode |= HAL_MODE_11B;
-#if 0
                if (g)
                        hal->ah_capabilities.cap_mode |= HAL_MODE_11G;
-#endif
        }
 
        /* GPIO */
Index: sys/dev/ic/ar5xxx.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/ar5xxx.c,v
retrieving revision 1.55
diff -u -p -u -p -r1.55 ar5xxx.c
--- sys/dev/ic/ar5xxx.c 23 Sep 2009 18:03:30 -0000      1.55
+++ sys/dev/ic/ar5xxx.c 24 Apr 2010 15:13:07 -0000
@@ -87,6 +87,7 @@ u_int32_t      ar5k_ar5110_chan2athchan(HAL_
 HAL_BOOL        ar5k_ar5111_channel(struct ath_hal *, HAL_CHANNEL *);
 HAL_BOOL        ar5k_ar5111_chan2athchan(u_int, struct ar5k_athchan_2ghz *);
 HAL_BOOL        ar5k_ar5112_channel(struct ath_hal *, HAL_CHANNEL *);
+HAL_BOOL        ar5k_ar2425_channel(struct ath_hal *, HAL_CHANNEL *);
 HAL_BOOL        ar5k_check_channel(struct ath_hal *, u_int16_t, u_int flags);
 
 HAL_BOOL        ar5k_ar5111_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
@@ -1127,6 +1128,8 @@ ar5k_channel(struct ath_hal *hal, HAL_CH
                ret = ar5k_ar5110_channel(hal, channel);
        else if (hal->ah_radio == AR5K_AR5111)
                ret = ar5k_ar5111_channel(hal, channel);
+       else if (hal->ah_radio == AR5K_AR2425)
+               ret = ar5k_ar5111_channel(hal, channel);
        else
                ret = ar5k_ar5112_channel(hal, channel);
 
@@ -1283,6 +1286,44 @@ ar5k_ar5112_channel(struct ath_hal *hal,
 
        AR5K_PHY_WRITE(0x27, data & 0xff);
        AR5K_PHY_WRITE(0x36, (data >> 8) & 0x7f);
+
+       return (AH_TRUE);
+}
+
+HAL_BOOL
+ar5k_ar2425_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
+{
+       u_int32_t data, data0, data2;
+       u_int16_t c;
+
+       data = data0 = data2 = 0;
+       c = channel->c_channel + hal->ah_chanoff;
+
+       /*
+        * Set the channel on the AR2425
+        */
+       if (c < 4800) {
+               data0 = ar5k_bitswap((c - 2272), 8);
+               data2 = 0;
+       } else if ((c - (c % 5)) != 2 || c > 5435) {
+               if (!(c % 20) && c < 5120)
+                       data0 = ar5k_bitswap(((c - 4800) / 20 << 2), 8);
+               else if (!(c % 10))
+                       data0 = ar5k_bitswap(((c - 4800) / 10 << 1), 8);
+               else if (!(c % 5))
+                       data0 = ar5k_bitswap((c - 4800) / 5, 8);
+               else
+                       return (AH_FALSE);
+               data2 = ar5k_bitswap(1, 2);
+       } else {
+               data0 = ar5k_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
+               data2 = ar5k_bitswap(0, 2);
+       }
+
+       data = (data0 << 4) | (data2 << 2) | 0x1001;
+
+       AR5K_PHY_WRITE(0x27, data & 0xff);
+       AR5K_PHY_WRITE(0x36, (data >> 8) & 0x7f);
 
        return (AH_TRUE);
 }

-- 
Alexander Vladimirov <alexander.idkfa.vladimi...@gmail.com>

Reply via email to