--- embedtools/src/athctl.c 2010/11/03 14:34:58 1.1.2.10 +++ embedtools/src/athctl.c 2017/01/22 20:40:10 1.4.14.1 @@ -3,9 +3,46 @@ * by Michael Pounov * * $Author: misho $ - * $Id: athctl.c,v 1.1.2.10 2010/11/03 14:34:58 misho Exp $ + * $Id: athctl.c,v 1.4.14.1 2017/01/22 20:40:10 misho Exp $ * - *************************************************************************/ + ************************************************************************* +The ELWIX and AITNET software is distributed under the following +terms: + +All of the documentation and software included in the ELWIX and AITNET +Releases is copyrighted by ELWIX - Sofia/Bulgaria + +Copyright 2004 - 2017 + by Michael Pounov . All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: +This product includes software developed by Michael Pounov +ELWIX - Embedded LightWeight unIX and its contributors. +4. Neither the name of AITNET nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. +*/ #include "global.h" #include "athctl.h" @@ -26,13 +63,15 @@ Usage() " athctl [-v] -r <0xoffset> <0xMemory_Address>\n" " athctl [-v] -w <0xoffset> <0xMemory_Address> \n" " athctl [-v] -s <0xMemory_Address>\n" - " athctl [-v] -w <0xMemory_Address>\n" + " athctl [-v] -u <0xMemory_Address>\n" + " athctl [-v] -R <0xMemory_Address> [new_regdomain]\n" "\n" "\t-v\t\tVerbose ...\n" "\t-t\t\tGet current Atheros maximum range in meters\n" "\t-i \tApply to this Atheros interface number (like ath0 == 0)\n" "\t-d \tMode distance, meters to target\n" "\t-c \tMode distance, mS timeouts correction\n" + "\t-R\t\tRead or Write EEPROM Regulatory domain\n" "\t-s \tDump EEPROM to file\n" "\t-u \tUpdate EEPROM from file\n" "\t-r \tRead EEPROM word from PCI mapped memory address\n" @@ -64,7 +103,7 @@ calcDistance(int ifid, int dist, int cor) errno, strerror(errno)); return -1; } else - VERB(1) printf("Info:: set slottime(%d) from %d to %d ... OK!\n", len, + VERB(1) printf("Info:: set slottime(%zd) from %d to %d ... OK!\n", len, slottime[1], slottime[0]); memset(szStr, 0, STRSIZ); @@ -80,7 +119,7 @@ calcDistance(int ifid, int dist, int cor) errno, strerror(errno)); return -1; } else - VERB(1) printf("Info:: set acktimeout(%d) from %d to %d ... OK!\n", len, + VERB(1) printf("Info:: set acktimeout(%zd) from %d to %d ... OK!\n", len, timeout[1], timeout[0]); memset(szStr, 0, STRSIZ); @@ -96,7 +135,7 @@ calcDistance(int ifid, int dist, int cor) errno, strerror(errno)); return -1; } else - VERB(1) printf("Info:: set ctstimeout(%d) from %d to %d ... OK!\n", len, + VERB(1) printf("Info:: set ctstimeout(%zd) from %d to %d ... OK!\n", len, timeout[1], timeout[0]); return timeout[0]; @@ -119,7 +158,7 @@ calcTimeout(int ifid, int cor) printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno)); return -1; } else - VERB(1) printf("Info:: get slottime(%d) %d ... OK!\n", len, slottime[1]); + VERB(1) printf("Info:: get slottime(%zd) %d ... OK!\n", len, slottime[1]); memset(szStr, 0, STRSIZ); snprintf(szStr, STRSIZ, SC_ACKTIMEOUT, ifid); @@ -130,7 +169,7 @@ calcTimeout(int ifid, int cor) printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno)); return -1; } else - VERB(1) printf("Info:: get acktimeout(%d) %d ... OK!\n", len, timeout[1]); + VERB(1) printf("Info:: get acktimeout(%zd) %d ... OK!\n", len, timeout[1]); slottime[0] = (timeout[1] - 3 - cor) / 2; VERB(3) printf("Info:: calculated slottime=%d\n", slottime[0]); @@ -176,7 +215,7 @@ readWord(u_char *mem, u_long offset) register int timeout = ATH_ACCESS_TIMEOUT; u_long stat; - VERB(2) printf("Reading EEPROM memory %p+%lx ...\n", mem, offset); + VERB(9) printf("Reading EEPROM memory %p+%lx ...\n", mem, offset); ATH_OUT(mem, AR5211_EEPROM_CONF, 0); usleep(ATH_ACCESS_WAIT); /* enable eeprom access */ @@ -212,9 +251,9 @@ writeWord(u_char *mem, u_long offset, u_short newval) { register int i = ATH_WRITE_RETRY, timeout; u_long pcicfg, stat; - u_short chk; + int chk; - VERB(2) printf("Writing EEPROM memory %p+%lx ...\n", mem, offset); + VERB(9) printf("Writing EEPROM memory %p+%lx ...\n", mem, offset); /* enable pci write access */ pcicfg = ATH_IN(mem, AR5K_PCICFG); ATH_OUT(mem, AR5K_PCICFG, (pcicfg & ~AR5K_PCICFG_SPWR_DN)); @@ -255,10 +294,10 @@ writeWord(u_char *mem, u_long offset, u_short newval) chk = readWord(mem, offset); if (chk == (u_short) -1) return -1; - if (chk == newval) - return chk << 16; + if ((u_short) (chk >> 16) == newval) + return chk; else - VERB(1) printf("Write & Read don`t match 0x%04X != 0x%04X\n", newval, chk); + VERB(1) printf("Write & Read don`t match 0x%04X != 0x%04X\n", newval, (u_short) (chk >> 16)); if (i) printf("Warning:: Retrying EEPROM write ...\n"); } while (--i); @@ -272,7 +311,7 @@ dumpFile(const char *csName, u_char *mem) { register u_long i; u_short d1, d2; - u_short eeprom[ATH_EEPROM_SIZE] = { 0 }; + u_char eeprom[ATH_EEPROM_SIZE] = { 0 }; int f, data; VERB(2) printf("Reading EEPROM memory %p ::\n", mem); @@ -286,8 +325,11 @@ dumpFile(const char *csName, u_char *mem) if ((data = readWord(mem, i)) == -1) return -1; else { - d1 = ((u_short) data >> 16) / 0x100; - d2 = ((u_short) data >> 16) % 0x100; + d1 = ((u_short)(data >> 16)) / 0x100; + d2 = ((u_short)(data >> 16)) % 0x100; + + VERB(5) printf( "Current value 0x%04X on position 0x%04lX will change 0x%02X 0x%02X\n", + (u_short) (data >> 16), i, d1, d2); } eeprom[i * 2] = d2; @@ -321,7 +363,7 @@ flashFile(const char *csName, u_char *mem) { register u_long i; u_short d1; - u_short eeprom[ATH_EEPROM_SIZE] = { 0 }; + u_char eeprom[ATH_EEPROM_SIZE] = { 0 }; int f, data; VERB(2) printf("Reading EEPROM from file %s ... ", csName); @@ -337,7 +379,7 @@ flashFile(const char *csName, u_char *mem) return 0; } close(f); - printf("OK!\n"); + VERB(2) printf("OK!\n"); VERB(2) printf("Writing EEPROM memory %p ::\n", mem); for (i = 0; i < ATH_EEPROM_SIZE / 2; i++) { @@ -351,14 +393,16 @@ flashFile(const char *csName, u_char *mem) return -1; else d1 = eeprom[i * 2 + 1] * 0x100 + eeprom[i * 2]; + VERB(5) printf("eeprom_data=0x%04X read_d1=0x%04X\n", (u_char) (data >> 16), d1); - if ((data >> 16) == d1) + if (((u_short) (data >> 16)) == d1) printf("."); else { - printf("x"); if (writeWord(mem, i, d1) < 1) - return -1; + printf("!"); + else + printf("x"); } usleep(ATH_ACCESS_WAITDOWN); @@ -368,6 +412,28 @@ flashFile(const char *csName, u_char *mem) return 0; } +static int +regDomain(u_char *mem, u_short newval) +{ + int ret, data; + + if ((data = readWord(mem, ATH_OFFSET_REGDOMAIN)) == -1) + return -1; + + printf("Current value 0x%04X ", (u_short) (data >> 16)); + if (newval != (u_short) -1) { + printf("will change to 0x%04X\n", newval); + + if ((ret = writeWord(mem, ATH_OFFSET_REGDOMAIN, newval)) == -1) + return -1; + + printf("Updated regulatory domain is 0x%04X\n", (u_short) (ret >> 16)); + } else + printf("\nCurrent regulatory domain is 0x%04X\n", (u_short) (data >> 16)); + + return 0; +} + // ---------------------------------------------------- int @@ -379,7 +445,7 @@ main(int argc, char **argv) u_short newval = 0; void *basemem = NULL; - while ((ch = getopt(argc, argv, "hvtr:w:i:d:c:u:s:")) != -1) + while ((ch = getopt(argc, argv, "hvRtr:w:i:d:c:u:s:")) != -1) switch (ch) { case 'v': Verbose++; @@ -414,6 +480,9 @@ main(int argc, char **argv) mode = 0x20; strlcpy(szName, optarg, MAXPATHLEN); break; + case 'R': + mode = 0x40; + break; case 'r': mode = 4; offset = strtoul(optarg, NULL, 0); @@ -446,6 +515,12 @@ main(int argc, char **argv) } else newval = (u_short) strtoul(argv[1], NULL, 0); } + if (mode & 0x40) { + if (argv[1]) + newval = (u_short) strtoul(argv[1], NULL, 0); + else + newval = (u_short) -1; + } if (mode & 1) if ((ret = calcDistance(ino, dist, cor)) < 1) @@ -468,7 +543,7 @@ main(int argc, char **argv) devClose(basemem); return 3; } else - printf("EEPROM readed value 0x%04X\n", (u_short) ret >> 16); + printf("EEPROM readed value 0x%04X\n", (u_short) (ret >> 16)); devClose(basemem); } if (mode & 8) { @@ -478,7 +553,7 @@ main(int argc, char **argv) devClose(basemem); return 3; } else - printf("EEPROM writed value 0x%04X\n", (u_short) ret); + printf("EEPROM writed value 0x%04X\n", (u_short) (ret >> 16)); devClose(basemem); } @@ -495,6 +570,16 @@ main(int argc, char **argv) if (!(basemem = devOpen(baseaddr))) return 2; if ((ret = flashFile(szName, basemem)) < 1) { + devClose(basemem); + return 3; + } + devClose(basemem); + } + + if (mode & 0x40) { + if (!(basemem = devOpen(baseaddr))) + return 2; + if ((ret = regDomain(basemem, newval)) < 1) { devClose(basemem); return 3; }