Skip to content

Instantly share code, notes, and snippets.

@kyuumeitai
Created December 30, 2018 15:28
Show Gist options
  • Save kyuumeitai/bf10cdc32a43e72b68bc9c7acc98fb89 to your computer and use it in GitHub Desktop.
Save kyuumeitai/bf10cdc32a43e72b68bc9c7acc98fb89 to your computer and use it in GitHub Desktop.
idchanger
/*
* 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
*
* Modified by Garlaschini Davide to allow changing ids
*/
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#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))
#define ATHEROS_PCI_MEM_SIZE 0x10000
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(){
(void) fprintf( stderr, "Usage: idchanger {-r|-w} physical_address_base [new_VendorID new_DevID new_Subs1 new_Subs2]\nphysical_address_base is a 32 bit hex value: 0xXXXXXXXX\nids are 16 bit hex values: 0xXXXX\n") ;
return ;
}
int
main( int argc, char **argv )
{
unsigned long int base_addr ;
int fd ;
void *membase ;
unsigned short int sdata;
unsigned short int new_id[4];
if ( argc <2 ) {
Usage() ;
return -1 ;
}
if(strcmp(argv[1],"-r")==0){
if ( argc <3 ) {
printf( "Using read command you have to specify adapter's physical_address_base\n") ;
Usage() ;
return -1 ;
}
base_addr = strtoul( argv[2], NULL, 0 ) ;
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 ;
}
printf("Accessing adapter at 0x%08X\n", base_addr);
//Print HEX Dump
int i;
for(i=0x00; i<=0xFF; i++){
printf("Reading %x ",i);
if ( vt_ar5211_eeprom_read( (unsigned char *) membase, i, &sdata ) )
fprintf( stderr, "EEPROM read failed\n" ) ;
printf( "current value 0x%04X\n", sdata) ;
}
}else if(strcmp(argv[1],"-w")==0){
if ( argc <7 ) {
printf( "Using write command you have to specify the 4 new ids\n") ;
Usage() ;
return -1 ;
}
int v;
for(v=3; v<=6; v++){
if ( strtoul( argv[v], NULL, 0 ) > 0xFFFF ) {
(void) fputs(
"Error: New ID must be 16 bit or less\n", stderr ) ;
Usage( argv[0] ) ;
return -2 ;
}else{
new_id[v-3] = (unsigned short int) strtoul( argv[v], NULL, 0 ) ;
}
}
base_addr = strtoul( argv[2], NULL, 0 ) ;
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 ;
}
printf("Accessing adapter at 0x%08X\n", base_addr);
#if 0
(void) vt_ar5211_eeprom_write( (unsigned char *) membase, AR5K_EEPROM_PROTECT_OFFSET, 0 ) ;
#endif /* #if 0 */
//Modify DEVID
if ( vt_ar5211_eeprom_read( (unsigned char *) membase, 0x00, &sdata ) ) fprintf( stderr, "EEPROM read failed\n" ) ;
printf( "Current value 0x%04X will change to 0x%04X\n", sdata, new_id[0] ) ;
if ( vt_ar5211_eeprom_write( (unsigned char *) membase, 0x00, new_id[0] ) ) fprintf( stderr, "EEPROM write failed\n" ) ;
//Modify VENDOR_ID
if ( vt_ar5211_eeprom_read( (unsigned char *) membase, 0x01, &sdata ) ) fprintf( stderr, "EEPROM read failed\n" ) ;
printf( "Current value 0x%04X will change to 0x%04X\n", sdata, new_id[1] ) ;
if ( vt_ar5211_eeprom_write( (unsigned char *) membase, 0x01, new_id[1] ) ) fprintf( stderr, "EEPROM write failed\n" ) ;
//Modify SubsystemID 0x07
if ( vt_ar5211_eeprom_read( (unsigned char *) membase, 0x07, &sdata ) ) fprintf( stderr, "EEPROM read failed\n" ) ;
printf( "Current value 0x%04X will change to 0x%04X\n", sdata, new_id[2] ) ;
if ( vt_ar5211_eeprom_write( (unsigned char *) membase, 0x07, new_id[2] ) ) fprintf( stderr, "EEPROM write failed\n" ) ;
//Modify SubsystemID 0x08
if ( vt_ar5211_eeprom_read( (unsigned char *) membase, 0x08, &sdata ) ) fprintf( stderr, "EEPROM read failed\n" ) ;
printf( "Current value 0x%04X will change to 0x%04X\n", sdata, new_id[3] ) ;
if ( vt_ar5211_eeprom_write( (unsigned char *) membase, 0x08, new_id[3] ) ) fprintf( stderr, "EEPROM write failed\n" ) ;
}else{
Usage( argv[0] ) ;
return -1 ;
}
return 0 ;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment