Main Page | Data Structures | Directories | File List | Data Fields | Globals

regdomain.c

Go to the documentation of this file.
00001 /*
00002  * This program is derived from code bearing the following Copyright(s)
00003  */
00004 /*                                                        -*- linux-c -*-
00005  *   _  _ ____ __ _ ___ ____ ____ __ _ _ _ _ |
00006  * .  \/  |--| | \|  |  |--< [__] | \| | _X_ | s e c u r e  s y s t e m s
00007  *
00008  * .vt|ar5k - PCI/CardBus 802.11a WirelessLAN driver for Atheros AR5k chipsets
00009  *
00010  * Copyright (c) 2002, .vantronix | secure systems
00011  *                     and Reyk Floeter <reyk@vantronix.net>
00012  *
00013  * This program is free software ; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation ; either version 2 of the License, or
00016  * (at your option) any later version.
00017  *
00018  * This program is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY ; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program ; if not, write to the Free Software
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026  */
00027 
00028 #include <sys/mman.h>
00029 #include <stdio.h>
00030 #include <unistd.h>
00031 #include <fcntl.h>
00032 
00033 #define AR5K_PCICFG 0x4010 
00034 #define AR5K_PCICFG_EEAE 0x00000001 
00035 #define AR5K_PCICFG_CLKRUNEN 0x00000004 
00036 #define AR5K_PCICFG_LED_PEND 0x00000020 
00037 #define AR5K_PCICFG_LED_ACT 0x00000040 
00038 #define AR5K_PCICFG_SL_INTEN 0x00000800 
00039 #define AR5K_PCICFG_BCTL                 0x00001000 
00040 #define AR5K_PCICFG_SPWR_DN 0x00010000 
00041 
00042 /* EEPROM Registers in the MAC */
00043 #define AR5211_EEPROM_ADDR 0x6000 
00044 #define AR5211_EEPROM_DATA 0x6004
00045 #define AR5211_EEPROM_COMD 0x6008
00046 #define AR5211_EEPROM_COMD_READ 0x0001
00047 #define AR5211_EEPROM_COMD_WRITE 0x0002
00048 #define AR5211_EEPROM_COMD_RESET 0x0003
00049 #define AR5211_EEPROM_STATUS 0x600C
00050 #define AR5211_EEPROM_STAT_RDERR 0x0001
00051 #define AR5211_EEPROM_STAT_RDDONE 0x0002
00052 #define AR5211_EEPROM_STAT_WRERR 0x0003
00053 #define AR5211_EEPROM_STAT_WRDONE 0x0004
00054 #define AR5211_EEPROM_CONF 0x6010
00055 
00056 #define VT_WLAN_IN32(a)  (*((volatile unsigned long int *)(mem + (a))))
00057 #define VT_WLAN_OUT32(v,a) (*((volatile unsigned long int *)(mem + (a))) = (v))
00058 
00059 int
00060 vt_ar5211_eeprom_read( unsigned char *mem,
00061                        unsigned long int offset,
00062                        unsigned short int *data )
00063 {
00064         int timeout = 10000 ;
00065         unsigned long int status ;
00066 
00067         VT_WLAN_OUT32( 0, AR5211_EEPROM_CONF ),
00068         usleep( 5 ) ;
00069 
00071         VT_WLAN_OUT32( VT_WLAN_IN32(AR5211_EEPROM_COMD)
00072                      | AR5211_EEPROM_COMD_RESET, AR5211_EEPROM_COMD) ;
00073         usleep( 5 ) ;
00074 
00076         VT_WLAN_OUT32( (unsigned char) offset, AR5211_EEPROM_ADDR) ;
00077         usleep( 5 ) ;
00078 
00079         VT_WLAN_OUT32( VT_WLAN_IN32(AR5211_EEPROM_COMD)
00080                      | AR5211_EEPROM_COMD_READ, AR5211_EEPROM_COMD) ;
00081 
00082         while (timeout > 0) {
00083                 usleep(1) ;
00084                 status = VT_WLAN_IN32(AR5211_EEPROM_STATUS) ;
00085                 if (status & AR5211_EEPROM_STAT_RDDONE) {
00086                         if (status & AR5211_EEPROM_STAT_RDERR) {
00087                                 (void) fputs( "eeprom read access failed!\n",
00088                                               stderr ) ;
00089                                 return 1 ;
00090                         }
00091                         status = VT_WLAN_IN32(AR5211_EEPROM_DATA) ;
00092                         *data = status & 0x0000ffff ;
00093                         return 0 ;
00094                 }
00095                 timeout-- ;
00096         }
00097 
00098         (void) fputs( "eeprom read timeout!\n", stderr ) ;
00099 
00100         return 1 ;
00101 }
00102 
00103 int
00104 vt_ar5211_eeprom_write( unsigned char *mem,
00105                         unsigned int offset,
00106                         unsigned short int new_data )
00107 {
00108         int timeout = 10000 ;
00109         unsigned long int status ;
00110         unsigned long int pcicfg ;
00111         int i ;
00112         unsigned short int sdata ;
00113 
00115         pcicfg = VT_WLAN_IN32( AR5K_PCICFG ) ;
00116 VT_WLAN_OUT32( ( pcicfg & ~AR5K_PCICFG_SPWR_DN ), AR5K_PCICFG ) ;
00117 usleep( 500 ) ;
00118         VT_WLAN_OUT32( pcicfg | AR5K_PCICFG_EEAE /* | 0x2 */, AR5K_PCICFG) ;
00119         usleep( 50 ) ;
00120 
00121         VT_WLAN_OUT32( 0, AR5211_EEPROM_STATUS );
00122         usleep( 50 ) ;
00123 
00124         /* VT_WLAN_OUT32( 0x1, AR5211_EEPROM_CONF ) ; */
00125         VT_WLAN_OUT32( 0x0, AR5211_EEPROM_CONF ) ;
00126         usleep( 50 ) ;
00127 
00128         i = 100 ;
00129 retry:
00131         VT_WLAN_OUT32( AR5211_EEPROM_COMD_RESET, AR5211_EEPROM_COMD);
00132         usleep( 500 ) ;
00133 
00134         /* Write data */
00135         VT_WLAN_OUT32( new_data, AR5211_EEPROM_DATA );
00136         usleep( 5 ) ;
00137 
00139         VT_WLAN_OUT32( offset, AR5211_EEPROM_ADDR);
00140         usleep( 5 ) ;
00141 
00142         VT_WLAN_OUT32( AR5211_EEPROM_COMD_WRITE, AR5211_EEPROM_COMD);
00143         usleep( 5 ) ;
00144 
00145         for ( timeout = 10000 ; timeout > 0 ; --timeout ) {
00146                 status = VT_WLAN_IN32( AR5211_EEPROM_STATUS );
00147                 if ( status & 0xC ) {
00148                         if ( status & AR5211_EEPROM_STAT_WRERR ) {
00149                                 fprintf( stderr,
00150                                  "eeprom write access failed!\n");
00151                                 return 1 ;
00152                         }
00153                         VT_WLAN_OUT32( 0, AR5211_EEPROM_STATUS );
00154                         usleep( 10 ) ;
00155                         break ;
00156                 }
00157                 usleep( 10 ) ;
00158                 timeout--;
00159         }
00160         (void) vt_ar5211_eeprom_read( mem, offset, &sdata ) ;
00161         if ( ( sdata != new_data ) && i ) {
00162                 --i ;
00163                 fprintf( stderr, "Retrying eeprom write!\n");
00164                 goto retry ;
00165         }
00166 
00167         return !i ;
00168 }
00169 
00170 static void
00171 Usage( char *progname )
00172 {
00173         (void) fprintf( stderr,
00174                         "Usage: %s physical_address_base new_country_code\n",
00175                         progname ) ;
00176         return ;
00177 }
00178 
00179 int
00180 main( int argc, char **argv )
00181 {
00182         unsigned long int base_addr ;
00183         int fd ;
00184         void *membase ;
00185         unsigned short int sdata ;
00186         unsigned short int new_cc ;
00187 
00188         if ( argc < 3 ) {
00189                 Usage( argv[0] ) ;
00190                 return -1 ;
00191         }
00192 
00193         base_addr = strtoul( argv[2], NULL, 0 ) ;
00194         if ( base_addr > 0xFFFF ) {
00195                 (void) fputs(
00196                       "Error: New domain code must be 16 bits or less\n",
00197                               stderr ) ;
00198                 Usage( argv[0] ) ;
00199                 return -2 ;
00200         }
00201         new_cc = (unsigned short int) base_addr ;
00202         base_addr = strtoul( argv[1], NULL, 0 ) ;
00203 #define ATHEROS_PCI_MEM_SIZE 0x10000
00204         fd = open( "/dev/mem", O_RDWR ) ;
00205         if ( fd < 0 ) {
00206                 fprintf( stderr, "Open of /dev/mem failed!\n" ) ;
00207                 return -2 ;
00208         }
00209         membase = mmap( 0, ATHEROS_PCI_MEM_SIZE, PROT_READ|PROT_WRITE,
00210                         MAP_SHARED|MAP_FILE, fd, base_addr ) ;
00211         if ( membase == (void *) -1 ) {
00212                 fprintf( stderr,
00213                          "Mmap of device at 0x%08X for 0x%X bytes failed!\n",
00214                          base_addr, ATHEROS_PCI_MEM_SIZE ) ;
00215                 return -3 ;
00216         }
00217 
00218 #if 0
00219         (void) vt_ar5211_eeprom_write( (unsigned char *) membase,
00220                                        AR5K_EEPROM_PROTECT_OFFSET, 0 ) ;
00221 #endif /* #if 0 */
00222 
00223         if ( vt_ar5211_eeprom_read( (unsigned char *) membase, 0xBF, &sdata ) )
00224                 fprintf( stderr, "EEPROM read failed\n" ) ;
00225 
00226         printf( "Current value 0x%04X will change to 0x%04X\n", sdata,
00227                 new_cc ) ;
00228 
00229         if ( vt_ar5211_eeprom_write( (unsigned char *) membase, 0xBF, new_cc ) )
00230                 fprintf( stderr, "EEPROM write failed\n" ) ;
00231 
00232         if ( vt_ar5211_eeprom_read( (unsigned char *) membase, 0xBF, &sdata ) )
00233                 fprintf( stderr, "EEPROM read failed\n" ) ;
00234 
00235         if ( sdata != new_cc )
00236                 fprintf( stderr, "Write & read don't match 0x%04X != 0x%04X\n",
00237                          new_cc, sdata ) ;
00238 
00239         return 0 ;
00240 }
00241 

Generated on Mon Nov 21 15:58:11 2005 for openwifi by  doxygen 1.4.1