AWMN @ oZoNet

You are here: Home > Mirrors > MadWifi regdomain

MadWifi regdomain


From: Igor Muncie nitric.com>
Subject: Re: Re: D-Link Dwl-Ag530 - unable to collect channel list from hal
Newsgroups: gmane.linux.drivers.madwifi.user
Date: 2004-11-01 22:54:19 GMT (34 weeks, 6 days, 19 hours and 55 minutes ago)
r/mattfoster  clara.co.uk/2004.11.01/20:32:10
>Quoting Nathan Kirk (nkirk linuxmail.org):
>>
>> Hi Igor,
>>
>> You will find the answer to this question in the archives starting at:
>> "2004-07-19 16:29"
>> Re: RE: Problem with loading the ath_pci for AR5212 based NIC
>> I was able to get my D-Link DWL-AG530 working.
>> D-Link's regdomain setting in this particular card is the problem.
>>
>> Cheers,
>> Nathan.
>>
>
>I've added this into the FAQ (entry 6.4) [1].
>
>If anyone has any changes/corrections, then please mail me.
>
>Cheers,
>
>Matt

Following Nathan's directions (thanks!) I got the card working just
fine. In case it is useful, I have documented the steps I went through
below. Of course, maybe changing the regdomain is not something you wish
to advocate in the FAQ..

# Steps to patch the regdomain from unknown (18) to FCC (16) for a D-Link
# DWL-AG530 so it works with current madwifi drivers.

1. Download the ar5k source, per Paul Shupak:
http://sourceforge.net/mailarchive/message.php?msg_id=8966525

The program code below will change the regulatory domain/country code
for any 521[123] based product. You"ll have to be root (of course) and know
the physical address in the card"s BAR0 ("lspci" will give this). The arguments
are "programname physical_address new_domain". I"m not sure what madWiFi is
looking for, but useful values include: 0 (wildcarded), 0x10 (FCC), 0x20 (DOC),
0x30 (ETSI), 0x31 (Spain), 0x32 (France), 0x40 (MKK-Japan), and 0xFF (debug).
Most "universal/worldwide" cards use zero as the value, some 0xFF.

NOTE: The included copyright is not mine.

Does this count as overwrite^H^H^H^H^Hriding it?

Paul Shupak

P.S. This came about because of my aggravation with a D-Link DWL-AG530.

P.P.S. D-Link intends for 0x12 to mean FCC minus 5.15-5.25 (i.e. no channels
less than 52 for 802.11a): I don"t know if this is "standard" or not; Most
of the values I"ve gotten from the SNMP mib for 802.11. I doubt the card
violates ERP for that range, but the rules are different for each of the
three 802.11 ranges (i.e. 5.15-5.25GHz, 5.25-5.35GHz & 5.725-5.85GHz).

>Message: 3
>From: Sam Leffler <sam@er...>
>Organization: Errno Consulting
>To: "Neilson Henriques" <neilson@pr...>
>Subject: Re: [Madwifi-users] RE: Problem with loading the ath_pci for AR5212 bas
>ed NIC
>Date: Wed, 14 Jul 2004 17:27:19 -0700
>Cc: <madwifi-users@li...>
>
>On Wednesday 14 July 2004 05:13 pm, Neilson Henriques wrote:
>> ath%d: unable to collect channel list from hal
>> ath%d: possible regdomain 18 countrycode 0
>>
>> Thats what I got ...
>>
>> My DWL-AG530 was purchased in USA if this
>> information can be relevant ... :-)
>
>Hmm, 18 is a new regulatory domain and not in the tables. I"ll try to fix
>this quickly. Sure would be easier if you could just override it... :)
>
> Sam

--------------------------------------------------------------------------------
/*
* This program is derived from code bearing the following Copyright(s)
*/
/* -*- linux-c -*-
* _ _ ____ __ _ ___ ____ ____ __ _ _ _ _ |
* . \/ |--| | \| | |--< [__] | \| | _X_ | s e c u r e s y s t e m s
*
* .vt|ar5k - PCI/CardBus 802.11a WirelessLAN driver for Atheros AR5k chipsets
*
* Copyright (c) 2002, .vantronix | secure systems
* and Reyk Floeter <reyk@va...>
*
* This program is free software ; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <sys/mman.h>
#include
#include
#include

#define AR5K_PCICFG 0x4010
#define AR5K_PCICFG_EEAE 0x00000001
#define AR5K_PCICFG_CLKRUNEN 0x00000004
#define AR5K_PCICFG_LED_PEND 0x00000020
#define AR5K_PCICFG_LED_ACT 0x00000040
#define AR5K_PCICFG_SL_INTEN 0x00000800
#define AR5K_PCICFG_BCTL 0x00001000
#define AR5K_PCICFG_SPWR_DN 0x00010000

/* EEPROM Registers in the MAC */
#define AR5211_EEPROM_ADDR 0x6000
#define AR5211_EEPROM_DATA 0x6004
#define AR5211_EEPROM_COMD 0x6008
#define AR5211_EEPROM_COMD_READ 0x0001
#define AR5211_EEPROM_COMD_WRITE 0x0002
#define AR5211_EEPROM_COMD_RESET 0x0003
#define AR5211_EEPROM_STATUS 0x600C
#define AR5211_EEPROM_STAT_RDERR 0x0001
#define AR5211_EEPROM_STAT_RDDONE 0x0002
#define AR5211_EEPROM_STAT_WRERR 0x0003
#define AR5211_EEPROM_STAT_WRDONE 0x0004
#define AR5211_EEPROM_CONF 0x6010

#define VT_WLAN_IN32(a) (*((volatile unsigned long int *)(mem + (a))))
#define VT_WLAN_OUT32(v,a) (*((volatile unsigned long int *)(mem + (a))) = (v))

int
vt_ar5211_eeprom_read( unsigned char *mem,
unsigned long int offset,
unsigned short int *data )
{
int timeout = 10000 ;
unsigned long int status ;

VT_WLAN_OUT32( 0, AR5211_EEPROM_CONF ),
usleep( 5 ) ;

/** enable eeprom read access */
VT_WLAN_OUT32( VT_WLAN_IN32(AR5211_EEPROM_COMD)
| AR5211_EEPROM_COMD_RESET, AR5211_EEPROM_COMD) ;
usleep( 5 ) ;

/** set address */
VT_WLAN_OUT32( (unsigned char) offset, AR5211_EEPROM_ADDR) ;
usleep( 5 ) ;

VT_WLAN_OUT32( VT_WLAN_IN32(AR5211_EEPROM_COMD)
| AR5211_EEPROM_COMD_READ, AR5211_EEPROM_COMD) ;

while (timeout > 0) {
usleep(1) ;
status = VT_WLAN_IN32(AR5211_EEPROM_STATUS) ;
if (status & AR5211_EEPROM_STAT_RDDONE) {
if (status & AR5211_EEPROM_STAT_RDERR) {
(void) fputs( "eeprom read access failed!\n",
stderr ) ;
return 1 ;
}
status = VT_WLAN_IN32(AR5211_EEPROM_DATA) ;
*data = status & 0x0000ffff ;
return 0 ;
}
timeout-- ;
}

(void) fputs( "eeprom read timeout!\n", stderr ) ;

return 1 ;
}

int
vt_ar5211_eeprom_write( unsigned char *mem,
unsigned int offset,
unsigned short int new_data )
{
int timeout = 10000 ;
unsigned long int status ;
unsigned long int pcicfg ;
int i ;
unsigned short int sdata ;

/** enable eeprom access */
pcicfg = VT_WLAN_IN32( AR5K_PCICFG ) ;
VT_WLAN_OUT32( ( pcicfg & ~AR5K_PCICFG_SPWR_DN ), AR5K_PCICFG ) ;
usleep( 500 ) ;
VT_WLAN_OUT32( pcicfg | AR5K_PCICFG_EEAE /* | 0x2 */, AR5K_PCICFG) ;
usleep( 50 ) ;

VT_WLAN_OUT32( 0, AR5211_EEPROM_STATUS );
usleep( 50 ) ;

/* VT_WLAN_OUT32( 0x1, AR5211_EEPROM_CONF ) ; */
VT_WLAN_OUT32( 0x0, AR5211_EEPROM_CONF ) ;
usleep( 50 ) ;

i = 100 ;
retry:
/** enable eeprom write access */
VT_WLAN_OUT32( AR5211_EEPROM_COMD_RESET, AR5211_EEPROM_COMD);
usleep( 500 ) ;

/* Write data */
VT_WLAN_OUT32( new_data, AR5211_EEPROM_DATA );
usleep( 5 ) ;

/** set address */
VT_WLAN_OUT32( offset, AR5211_EEPROM_ADDR);
usleep( 5 ) ;

VT_WLAN_OUT32( AR5211_EEPROM_COMD_WRITE, AR5211_EEPROM_COMD);
usleep( 5 ) ;

for ( timeout = 10000 ; timeout > 0 ; --timeout ) {
status = VT_WLAN_IN32( AR5211_EEPROM_STATUS );
if ( status & 0xC ) {
if ( status & AR5211_EEPROM_STAT_WRERR ) {
fprintf( stderr,
"eeprom write access failed!\n");
return 1 ;
}
VT_WLAN_OUT32( 0, AR5211_EEPROM_STATUS );
usleep( 10 ) ;
break ;
}
usleep( 10 ) ;
timeout--;
}
(void) vt_ar5211_eeprom_read( mem, offset, &sdata ) ;
if ( ( sdata != new_data ) && i ) {
--i ;
fprintf( stderr, "Retrying eeprom write!\n");
goto retry ;
}

return !i ;
}

static void
Usage( char *progname )
{
(void) fprintf( stderr,
"Usage: %s physical_address_base new_country_code\n",
progname ) ;
return ;
}

int
main( int argc, char **argv )
{
unsigned long int base_addr ;
int fd ;
void *membase ;
unsigned short int sdata ;
unsigned short int new_cc ;

if ( argc < 3 ) {
Usage( argv[0] ) ;
return -1 ;
}

base_addr = strtoul( argv[2], NULL, 0 ) ;
if ( base_addr > 0xFFFF ) {
(void) fputs(
"Error: New domain code must be 16 bits or less\n",
stderr ) ;
Usage( argv[0] ) ;
return -2 ;
}
new_cc = (unsigned short int) base_addr ;
base_addr = strtoul( argv[1], NULL, 0 ) ;
#define ATHEROS_PCI_MEM_SIZE 0x10000
fd = open( "/dev/mem", O_RDWR ) ;
if ( fd < 0 ) {
fprintf( stderr, "Open of /dev/mem failed!\n" ) ;
return -2 ;
}
membase = mmap( 0, ATHEROS_PCI_MEM_SIZE, PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_FILE, fd, base_addr ) ;
if ( membase == (void *) -1 ) {
fprintf( stderr,
"Mmap of device at 0x%08X for 0x%X bytes failed!\n",
base_addr, ATHEROS_PCI_MEM_SIZE ) ;
return -3 ;
}

#if 0
(void) vt_ar5211_eeprom_write( (unsigned char *) membase,
AR5K_EEPROM_PROTECT_OFFSET, 0 ) ;
#endif /* #if 0 */

if ( vt_ar5211_eeprom_read( (unsigned char *) membase, 0xBF, &sdata ) )
fprintf( stderr, "EEPROM read failed\n" ) ;

printf( "Current value 0x%04X will change to 0x%04X\n", sdata,
new_cc ) ;

if ( vt_ar5211_eeprom_write( (unsigned char *) membase, 0xBF, new_cc ) )
fprintf( stderr, "EEPROM write failed\n" ) ;

if ( vt_ar5211_eeprom_read( (unsigned char *) membase, 0xBF, &sdata ) )
fprintf( stderr, "EEPROM read failed\n" ) ;

if ( sdata != new_cc )
fprintf( stderr, "Write & read don"t match 0x%04X != 0x%04X\n",
new_cc, sdata ) ;

return 0 ;
}


Cut and paste the source into a file ar5k.c and then compile it:
gcc ar5k.c -o ar5k

NB: When I cut and paste, I get a typo near the end of the
program; it reads ...don"t match..., should read ...don't match...
Fix and recompile.

2. Patch ath/if_ath.c, per Michael Gernoth:
http://sourceforge.net/mailarchive/message.php?msg_id=9000820

On Mon, Jul 19, 2004 at 06:29:31PM -0500, Nathan Kirk wrote:
> Even with Paul"s utility program, I am still unable to get my DWL-AG530 working.
> The eeprom read fails and the program exits without changing the regulatory domain.

The driver needs to be loaded for the program to work.
After "killing" my card with a wrong region I modified the driver to
load despite of the unknown region and after that I was able to fix
the setting again.

Diff attached.

Regards,
Michael


--- ath/if_ath.c.orig 2004-07-20 16:30:40.000000000 +0200
+++ ath/if_ath.c 2004-07-20 16:32:13.000000000 +0200
@@ -3663,7 +3663,7 @@
"regdomain likely %u country code %u\n",
dev->name, rd, cc);
kfree(chans);
- return EINVAL;
+ return 0;
}

/*

Rebuild the atheros modules, reinstall and reboot.

NB: I had to reboot to single-user mode (i.e., LILO: linux single)
because with an unknown regdomain, the patched atheros module rendered
networking unusable (all networking, such as ifconfig, nfsd, samba,
apache, would hang)

3. Make sure ath_pci is loaded:
modprobe ath_pci

Find its memory address:
lspci -v > /tmp/lspci
less /tmp/lspci

Look for:
0000:00:0a.0 Ethernet controller: Atheros Communications, Inc. AR5212 802.11abg NIC (rev 01)
Subsystem: D-Link System Inc: Unknown device 3a14
Flags: bus master, medium devsel, latency 168, IRQ 169
Memory at ec100000 (32-bit, non-prefetchable) [size=64K]
Capabilities: [44] Power Management version 2

The memory address is on the second-last line of that section.

Find the regdomain for your use; see Paul Shupak's mail; 0x10
(16) is FCC.

Run the ar5k utility:
./ar5k 0xec100000 0x10
^ ^
| +- The appropriate regdomain value
+------------ From lspci

It should print out that it has changed from 18 to 16, or whatever.

4. Reboot and everything magically works fine. You don't need to
unpatch the atheros modules, but equally you don't need to repatch
it in the future.

5. If you ever want to undo this change, just run ar5k 0xec100000 0x12
(or whatever the original value was (0x12 == 18)).

-- Igor

nach oben