Date: Thu, 07 Dec 2006 21:23:08 +0900 (JST) From: YAMAMOTO Shigeru <shigeru@iij.ad.jp> To: freebsd-current@freebsd.org Subject: Re: how to get supported channels from iwi firmware Message-ID: <20061207.212308.32463430.shigeru@iij.ad.jp> In-Reply-To: <456271B3.4060701@errno.com> References: <20061121.100736.48665070.shigeru@iij.ad.jp> <456271B3.4060701@errno.com>
next in thread | previous in thread | raw e-mail | index | archive | help
----Next_Part(Thu_Dec__7_21_23_08_2006_784)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit >>>>> "Sam" == Sam Leffler <sam@errno.com> writes: >> I'm using iwi(Intel(R) PRO/Wireless 2915ABG). iwi driver does not >> support 802.11j channels (34, 38, 42, 46) which channles are used in >> Japan. # a channel set, 34, 38, 42, 46 is called 'J52' in Japan. >> >> So, I fix iwi to support 802.11j channels. But it is no good fix. >> >> I think it is better to get supported channels list from iwi firmware. >> Does anybody know how to get supported channels list from iwi firmware? Sam> It's in the EEPROM. I don't recall if the linux driver even does that Sam> but maybe a recent version does so check there. I check Linux driver code at http://ipw2200.sourceforge.net/ I create new patch to get channel information from EEPROM. I test it at on my NotePC. Currently, I hove no trouble. But I don't to know my patch is right or not. Because, Linux driver does not use channel information. ;-( Linux driver only uses country code in EEPROM. So default setting in my patch is using only country code. If set 'USE_IWI_EEPROM_CHANNELS', my patch uses channel information in EEPROM. Please try my patch if you have interest my patch. Thanks, ------- YAMAMOTO Shigeru <shigeru@iij.ad.jp> ----Next_Part(Thu_Dec__7_21_23_08_2006_784)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="iwi.eeprom.diff" Index: sys/dev/iwi/if_iwi.c =================================================================== RCS file: /share/cvsup/FreeBSD/current/usr/src/sys/dev/iwi/if_iwi.c,v retrieving revision 1.43 diff -u -r1.43 if_iwi.c --- sys/dev/iwi/if_iwi.c 6 Dec 2006 21:23:51 -0000 1.43 +++ sys/dev/iwi/if_iwi.c 7 Dec 2006 02:27:34 -0000 @@ -395,6 +395,32 @@ IEEE80211_C_WPA | /* 802.11i */ IEEE80211_C_WME; /* 802.11e */ + /* read EEPROM */ + for (i = 0; i < IWI_EEPROM_SIZE/2; i ++) { + sc->sc_eeprom.eeprom16[i] = iwi_read_prom_word(sc, i); + } + device_printf(dev, "IWI_EEPROM:\n"); + for (i = 0; i < IWI_EEPROM_SIZE/2; i ++) { + if (i % 16 == 0) { + printf("\n"); + } + printf(" %04x", sc->sc_eeprom.eeprom16[i]); + } + printf("\n"); + device_printf(dev, "IWI_EEPROM_VERSION: %d\n", sc->sc_eeprom.eeprom8[IWI_EEPROM_VERSION*2 + 1]); + device_printf(dev, "IWI_EEPROM_HW_VERSION: 0x%04x\n", sc->sc_eeprom.eeprom16[IWI_EEPROM_HW_VERSION]); + device_printf(dev, "IWI_EEPROM_COUNTRY_CODE: %c%c%c\n", sc->sc_eeprom.eeprom8[IWI_EEPROM_COUNTRY_CODE*2], sc->sc_eeprom.eeprom8[IWI_EEPROM_COUNTRY_CODE*2 + 1] , sc->sc_eeprom.eeprom8[IWI_EEPROM_COUNTRY_CODE*2 + 2]); + device_printf(dev, "IWI_EEPROM_BSS_CHANNELS_BG:"); + for (i = 0; i < 2; i ++) { + printf(" %02x", sc->sc_eeprom.eeprom8[IWI_EEPROM_BSS_CHANNELS_BG*2 + i]); + } + printf("\n"); + device_printf(dev, "IWI_EEPROM_BSS_CHANNELS_A:"); + for (i = 0; i < 5; i ++) { + printf(" %02x", sc->sc_eeprom.eeprom8[IWI_EEPROM_BSS_CHANNELS_A*2 + i]); + } + printf("\n"); + /* read MAC address from EEPROM */ val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0); ic->ic_myaddr[0] = val & 0xff; @@ -410,12 +436,40 @@ /* set supported .11a rates (2915ABG only) */ ic->ic_sup_rates[IEEE80211_MODE_11A] = iwi_rateset_11a; +#if defined(USE_IWI_EEPROM_CHANNELS) + for (i = 0; i < 5*8; i ++) { + if ((sc->sc_eeprom.eeprom8[IWI_EEPROM_IBSS_CHANNELS_A*2 + i/8] >> (i % 8)) & 0x01) { + int ch = (i+1)*2; + + ic->ic_channels[ch].ic_freq = + ieee80211_ieee2mhz(ch, IEEE80211_CHAN_5GHZ); + ic->ic_channels[ch].ic_flags = IEEE80211_CHAN_A; + } + if ((sc->sc_eeprom.eeprom8[IWI_EEPROM_BSS_CHANNELS_A*2 + i/8] >> (i % 8)) & 0x01) { + int ch = (i+1)*2; + + ic->ic_channels[ch].ic_freq = + ieee80211_ieee2mhz(ch, IEEE80211_CHAN_5GHZ); + ic->ic_channels[ch].ic_flags = IEEE80211_CHAN_A; + } + } +#else + if (memcmp(&(sc->sc_eeprom.eeprom8[IWI_EEPROM_COUNTRY_CODE*2]), "ZZJ", 3) == 0) { + /* set supported .11a(802.11j) channels, which is used in Japan */ + for (i = 34; i <= 46; i += 4) { + ic->ic_channels[i].ic_freq = + ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); + ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A; + } + } + /* set supported .11a channels */ for (i = 36; i <= 64; i += 4) { ic->ic_channels[i].ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A; } +#endif for (i = 149; i <= 165; i += 4) { ic->ic_channels[i].ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); @@ -428,6 +482,28 @@ ic->ic_sup_rates[IEEE80211_MODE_11G] = iwi_rateset_11g; /* set supported .11b and .11g channels (1 through 14) */ +#if defined(USE_IWI_EEPROM_CHANNELS) + for (i = 0; i < 2*8 - 1; i ++) { + if ((sc->sc_eeprom.eeprom8[IWI_EEPROM_IBSS_CHANNELS_BG*2 + i/8] >> (i % 8)) & 0x01) { + int ch = (i+1); + + ic->ic_channels[ch].ic_freq = + ieee80211_ieee2mhz(ch, IEEE80211_CHAN_2GHZ); + ic->ic_channels[ch].ic_flags = + IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | + IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; + } + if ((sc->sc_eeprom.eeprom8[IWI_EEPROM_BSS_CHANNELS_BG*2 + i/8] >> (i % 8)) & 0x01) { + int ch = (i+1); + + ic->ic_channels[ch].ic_freq = + ieee80211_ieee2mhz(ch, IEEE80211_CHAN_2GHZ); + ic->ic_channels[ch].ic_flags = + IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | + IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; + } + } +#else for (i = 1; i <= 14; i++) { ic->ic_channels[i].ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); @@ -435,6 +511,7 @@ IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; } +#endif ieee80211_ifattach(ic); ic->ic_bmissthreshold = 10; /* override default */ Index: sys/dev/iwi/if_iwireg.h =================================================================== RCS file: /share/cvsup/FreeBSD/current/usr/src/sys/dev/iwi/if_iwireg.h,v retrieving revision 1.13 diff -u -r1.13 if_iwireg.h --- sys/dev/iwi/if_iwireg.h 23 Oct 2006 00:34:07 -0000 1.13 +++ sys/dev/iwi/if_iwireg.h 21 Nov 2006 08:31:51 -0000 @@ -476,9 +476,19 @@ #define IWI_MEM_EEPROM_EVENT 0x00300004 #define IWI_MEM_EEPROM_CTL 0x00300040 +#define IWI_EEPROM_SIZE (256) + +#define IWI_EEPROM_PME_CAPABILITY 0x09 /* 1 octet (msb) */ #define IWI_EEPROM_MAC 0x21 +#define IWI_EEPROM_VERSION 0x24 /* 1 octet (msb) */ #define IWI_EEPROM_NIC 0x25 /* nic type (lsb) */ #define IWI_EEPROM_SKU 0x25 /* nic type (msb) */ +#define IWI_EEPROM_COUNTRY_CODE 0x26 /* 3 octets (lsb) */ +#define IWI_EEPROM_IBSS_CHANNELS_BG 0x28 /* 2 octets (lsb) */ +#define IWI_EEPROM_IBSS_CHANNELS_A 0x29 /* 5 octets (msb) */ +#define IWI_EEPROM_BSS_CHANNELS_BG 0x2c /* 2 octets (lsb) */ +#define IWI_EEPROM_BSS_CHANNELS_A 0x2d /* 5 octets (msb) */ +#define IWI_EEPROM_HW_VERSION 0x72 /* 2 octets (lsb) */ #define IWI_EEPROM_DELAY 1 /* minimum hold time (microsecond) */ Index: sys/dev/iwi/if_iwivar.h =================================================================== RCS file: /share/cvsup/FreeBSD/current/usr/src/sys/dev/iwi/if_iwivar.h,v retrieving revision 1.11 diff -u -r1.11 if_iwivar.h --- sys/dev/iwi/if_iwivar.h 27 Apr 2006 21:43:37 -0000 1.11 +++ sys/dev/iwi/if_iwivar.h 21 Nov 2006 08:54:48 -0000 @@ -209,6 +209,11 @@ } sc_txtapu; #define sc_txtap sc_txtapu.th int sc_txtap_len; + + union { + uint8_t eeprom8[IWI_EEPROM_SIZE]; + uint16_t eeprom16[IWI_EEPROM_SIZE/2]; + } sc_eeprom; }; /* ----Next_Part(Thu_Dec__7_21_23_08_2006_784)----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20061207.212308.32463430.shigeru>