Annotation of embedtools/src/athctl.c, revision 1.1.2.4

1.1.2.2   misho       1: /*************************************************************************
                      2:  * (C) 2010 AITNET - Sofia/Bulgaria - <office@aitbg.com>
                      3:  *  by Michael Pounov <misho@aitbg.com>
                      4:  *
                      5:  * $Author: misho $
1.1.2.4 ! misho       6:  * $Id: athctl.c,v 1.1.2.3 2010/10/25 12:56:27 misho Exp $
1.1.2.2   misho       7:  *
                      8:  *************************************************************************/
1.1.2.1   misho       9: #include "global.h"
1.1.2.2   misho      10: #include "athctl.h"
1.1.2.1   misho      11: 
                     12: 
1.1.2.2   misho      13: int Verbose;
                     14: extern char compiled[], compiledby[], compilehost[];
                     15: 
                     16: 
                     17: static void
                     18: Usage()
                     19: {
                     20:        printf( "athCtl is tool for Atheros WiFi cards managment \n"
                     21:                "=== %s === %s@%s ===\n\n"
1.1.2.4 ! misho      22:                "  Syntax: athctl [options] [[0xMemory_Address] new_value]\n"
1.1.2.3   misho      23:                "          athctl [-v] -t [-i <iface_no>]\n"
                     24:                "          athctl [-v] -c <timeout> [-i <iface_no>]\n"
                     25:                "          athctl [-v] -d <distance> [-i <iface_no>]\n"
                     26:                "          athctl [-v] -r <0xoffset> <0xMemory_Address>\n"
1.1.2.4 ! misho      27:                "          athctl [-v] -w <0xoffset> <0xMemory_Address> <uint16_value>\n"
1.1.2.3   misho      28:                "          athctl [-v] -s <file> <0xMemory_Address>\n"
                     29:                "          athctl [-v] -w <file> <0xMemory_Address>\n"
                     30:                "\n"
1.1.2.2   misho      31:                "\t-v\t\tVerbose ...\n"
                     32:                "\t-t\t\tGet current Atheros maximum range in meters\n"
                     33:                "\t-i <iface_no>\tApply to this Atheros interface number (like ath0 == 0)\n"
                     34:                "\t-d <distance>\tMode distance, meters to target\n"
                     35:                "\t-c <timeout>\tMode distance, mS timeouts correction\n"
1.1.2.3   misho      36:                "\t-s <file>\tDump EEPROM to file\n"
                     37:                "\t-u <file>\tUpdate EEPROM from file\n"
                     38:                "\t-r <offset>\tRead EEPROM word from PCI mapped memory address\n"
                     39:                "\t-w <offset>\tWrite EEPROM word to PCI mapped memory address\n"
1.1.2.2   misho      40:                "\n", compiled, compiledby, compilehost);
                     41: }
                     42: 
                     43: static int
                     44: calcDistance(int ifid, int dist, int cor)
                     45: {
                     46:        int slottime[2], timeout[2];
                     47:        size_t len;
                     48:        char szStr[STRSIZ];
                     49: 
                     50:        slottime[0] = 9 + (dist / 300) + (dist % 300 ? 1 : 0);
                     51:        timeout[0] = slottime[0] * 2 + 3 + cor;
                     52:        VERB(3) printf("Info:: slottime=%d timeout=%d\n", slottime[0], timeout[0]);
                     53: 
                     54:        memset(szStr, 0, STRSIZ);
                     55:        snprintf(szStr, STRSIZ, SC_SLOTTIME, ifid);
                     56:        if (sysctlbyname(szStr, NULL, &len, NULL, 0) == -1) {
                     57:                printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
                     58:                return -1;
                     59:        } else if (sysctlbyname(szStr, &slottime[1], &len, NULL, 0) == -1) {
                     60:                printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
                     61:                return -1;
                     62:        } else if (sysctlbyname(szStr, NULL, NULL, &slottime[0], sizeof slottime[0]) == -1) {
                     63:                printf("Error:: set sysctl %s from %d #%d - %s\n", szStr, slottime[1], 
                     64:                                errno, strerror(errno));
                     65:                return -1;
                     66:        } else
                     67:                VERB(1) printf("Info:: set slottime(%d) from %d to %d ... OK!\n", len, 
                     68:                                slottime[1], slottime[0]);
                     69: 
                     70:        memset(szStr, 0, STRSIZ);
                     71:        snprintf(szStr, STRSIZ, SC_ACKTIMEOUT, ifid);
                     72:        if (sysctlbyname(szStr, NULL, &len, NULL, 0) == -1) {
                     73:                printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
                     74:                return -1;
                     75:        } else if (sysctlbyname(szStr, &timeout[1], &len, NULL, 0) == -1) {
                     76:                printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
                     77:                return -1;
                     78:        } else if (sysctlbyname(szStr, NULL, NULL, &timeout[0], sizeof timeout[0]) == -1) {
                     79:                printf("Error:: set sysctl %s from %d #%d - %s\n", szStr, timeout[1], 
                     80:                                errno, strerror(errno));
                     81:                return -1;
                     82:        } else
                     83:                VERB(1) printf("Info:: set acktimeout(%d) from %d to %d ... OK!\n", len, 
                     84:                                timeout[1], timeout[0]);
                     85: 
                     86:        memset(szStr, 0, STRSIZ);
                     87:        snprintf(szStr, STRSIZ, SC_CTSTIMEOUT, ifid);
                     88:        if (sysctlbyname(szStr, NULL, &len, NULL, 0) == -1) {
                     89:                printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
                     90:                return -1;
                     91:        } else if (sysctlbyname(szStr, &timeout[1], &len, NULL, 0) == -1) {
                     92:                printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
                     93:                return -1;
                     94:        } else if (sysctlbyname(szStr, NULL, NULL, &timeout[0], sizeof timeout[0]) == -1) {
                     95:                printf("Error:: set sysctl %s from %d #%d - %s\n", szStr, timeout[1], 
                     96:                                errno, strerror(errno));
                     97:                return -1;
                     98:        } else
                     99:                VERB(1) printf("Info:: set ctstimeout(%d) from %d to %d ... OK!\n", len, 
                    100:                                timeout[1], timeout[0]);
                    101: 
                    102:        return timeout[0];
                    103: }
                    104: 
                    105: 
                    106: static int
                    107: calcTimeout(int ifid, int cor)
                    108: {
                    109:        int slottime[2], timeout[2];
                    110:        size_t len;
                    111:        char szStr[STRSIZ];
                    112: 
                    113:        memset(szStr, 0, STRSIZ);
                    114:        snprintf(szStr, STRSIZ, SC_SLOTTIME, ifid);
                    115:        if (sysctlbyname(szStr, NULL, &len, NULL, 0) == -1) {
                    116:                printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
                    117:                return -1;
                    118:        } else if (sysctlbyname(szStr, &slottime[1], &len, NULL, 0) == -1) {
                    119:                printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
                    120:                return -1;
                    121:        } else
                    122:                VERB(1) printf("Info:: get slottime(%d) %d ... OK!\n", len, slottime[1]);
                    123: 
                    124:        memset(szStr, 0, STRSIZ);
                    125:        snprintf(szStr, STRSIZ, SC_ACKTIMEOUT, ifid);
                    126:        if (sysctlbyname(szStr, NULL, &len, NULL, 0) == -1) {
                    127:                printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
                    128:                return -1;
                    129:        } else if (sysctlbyname(szStr, &timeout[1], &len, NULL, 0) == -1) {
                    130:                printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
                    131:                return -1;
                    132:        } else
                    133:                VERB(1) printf("Info:: get acktimeout(%d) %d ... OK!\n", len, timeout[1]);
                    134: 
                    135:        slottime[0] = (timeout[1] - 3 - cor) / 2;
                    136:        VERB(3) printf("Info:: calculated slottime=%d\n", slottime[0]);
                    137:        timeout[0] = (slottime[0] - 10) * 300;
                    138:        VERB(3) printf("Info:: calculated timeout=%d\n", timeout[0]);
                    139: 
                    140:        return timeout[0];
                    141: }
1.1.2.3   misho     142: 
                    143: 
                    144: static inline void *
                    145: devOpen(u_long baseaddr)
                    146: {
                    147:        int fd;
                    148:        void *basemem;
                    149: 
                    150:        fd = open("/dev/mem", O_RDWR);
                    151:        if (fd == -1) {
                    152:                printf("Error:: open device #%d - %s\n", errno, strerror(errno));
                    153:                return NULL;
                    154:        }
                    155:        basemem = mmap(NULL, ATH_PCI_MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, baseaddr);
                    156:        if (basemem == MAP_FAILED) {
                    157:                printf("Error:: map device #%d - %s\n", errno, strerror(errno));
                    158:                close(fd);
                    159:                return NULL;
                    160:        } else
                    161:                close(fd);
                    162: 
                    163:        return basemem;
                    164: }
                    165: 
                    166: static inline void
                    167: devClose(void *basemem)
                    168: {
                    169:        if (basemem)
                    170:                munmap(basemem, ATH_PCI_MEM_SIZE);
                    171: }
                    172: 
1.1.2.4 ! misho     173: static inline short
        !           174: readWord(u_char *mem, u_long offset)
        !           175: {
        !           176:        register int timeout = ATH_ACCESS_TIMEOUT;
        !           177:        u_long stat;
        !           178: 
        !           179:        ATH_OUT(mem, AR5211_EEPROM_CONF, 0);
        !           180:        usleep(ATH_ACCESS_WAIT);
        !           181:        /* enable eeprom access */
        !           182:        ATH_OUT(mem, AR5211_EEPROM_COMD, ATH_IN(mem, AR5211_EEPROM_COMD) | AR5211_EEPROM_COMD_RESET);
        !           183:        usleep(ATH_ACCESS_WAIT);
        !           184:        /* set address */
        !           185:        ATH_OUT(mem, AR5211_EEPROM_ADDR, offset);
        !           186:        usleep(ATH_ACCESS_WAIT);
        !           187:        /* enable eeprom read access */
        !           188:        ATH_OUT(mem, AR5211_EEPROM_COMD, ATH_IN(mem, AR5211_EEPROM_COMD) | AR5211_EEPROM_COMD_READ);
        !           189:        usleep(ATH_ACCESS_WAIT);
        !           190: 
        !           191:        while (timeout--) {
        !           192:                usleep(1);
        !           193:                stat = ATH_IN(mem, AR5211_EEPROM_STATUS);
        !           194:                if (stat & AR5211_EEPROM_STAT_RDDONE) {
        !           195:                        if (stat & AR5211_EEPROM_STAT_RDERR) {
        !           196:                                printf("Error:: EEPROM read failed!\n");
        !           197:                                return -1;
        !           198:                        }
        !           199: 
        !           200:                        stat = ATH_IN(mem, AR5211_EEPROM_DATA);
        !           201:                        return stat & 0x0000ffff;
        !           202:                }
        !           203:        }
        !           204: 
        !           205:        printf("Error:: EEPROM read timeout!\n");
        !           206:        return 0;
        !           207: }
        !           208: 
        !           209: static inline short
        !           210: writeWord(u_char *mem, u_long offset, u_short newval)
        !           211: {
        !           212:        register int i = ATH_WRITE_RETRY, timeout;
        !           213:        u_long pcicfg, stat;
        !           214:        u_short chk;
        !           215: 
        !           216:        /* enable pci write access */
        !           217:        pcicfg = ATH_IN(mem, AR5K_PCICFG);
        !           218:        ATH_OUT(mem, AR5K_PCICFG, (pcicfg & ~AR5K_PCICFG_SPWR_DN));
        !           219:        usleep(ATH_ACCESS_WAITDOWN);
        !           220:        ATH_OUT(mem, AR5K_PCICFG, pcicfg | AR5K_PCICFG_EEAE /* | 0x2 */);
        !           221:        usleep(ATH_ACCESS_WAITPCI);
        !           222:        ATH_OUT(mem, AR5211_EEPROM_STATUS, 0);
        !           223:        usleep(ATH_ACCESS_WAITPCI);
        !           224:        /* ATH_OUT(mem, AR5211_EEPROM_CONF, 1); */
        !           225:        ATH_OUT(mem, AR5211_EEPROM_CONF, 0);
        !           226: 
        !           227:        do {
        !           228:                /* enable eeprom write access */
        !           229:                ATH_OUT(mem, AR5211_EEPROM_COMD, AR5211_EEPROM_COMD_RESET);
        !           230:                usleep(ATH_ACCESS_WAITDOWN);
        !           231:                ATH_OUT(mem, AR5211_EEPROM_DATA, newval);
        !           232:                usleep(ATH_ACCESS_WAIT);
        !           233:                ATH_OUT(mem, AR5211_EEPROM_ADDR, offset);
        !           234:                usleep(ATH_ACCESS_WAIT);
        !           235:                ATH_OUT(mem, AR5211_EEPROM_COMD, AR5211_EEPROM_COMD_WRITE);
        !           236:                usleep(ATH_ACCESS_WAIT);
        !           237: 
        !           238:                for (timeout = ATH_ACCESS_TIMEOUT; timeout; timeout--) {
        !           239:                        stat = ATH_IN(mem, AR5211_EEPROM_STATUS);
        !           240:                        if (stat & 0xc) {
        !           241:                                if (stat & AR5211_EEPROM_STAT_WRERR) {
        !           242:                                        printf("Error:: EEPROM write failed!\n");
        !           243:                                        return -1;
        !           244:                                }
        !           245: 
        !           246:                                ATH_OUT(mem, AR5211_EEPROM_STATUS, 0);
        !           247:                                usleep(ATH_ACCESS_WAIT * 2);
        !           248:                                break;
        !           249:                        }
        !           250:                        usleep(ATH_ACCESS_WAIT * 2);
        !           251:                }
        !           252: 
        !           253:                chk = readWord(mem, offset);
        !           254:                if (chk == (u_short) -1)
        !           255:                        return -1;
        !           256:                if (chk == newval)
        !           257:                        return 1;
        !           258:                if (i)
        !           259:                        printf("Warning:: Retrying EEPROM write ...\n");
        !           260:        } while (--i);
        !           261: 
        !           262:        printf("Error:: EEPROM write timeout!\n");
        !           263:        return 0;
        !           264: }
        !           265: 
1.1.2.3   misho     266: /*
                    267: static int
                    268: readEEPROM()
                    269: {
                    270:        register u_long i;
                    271: 
                    272:        printf("Reading EEPROM ...\n");
                    273:        for (i = 0; i < ATH_EEPROM_SIZE / 2; i++) {
                    274:        }
                    275: }
                    276: */
                    277: 
1.1.2.2   misho     278: // ----------------------------------------------------
                    279: 
1.1.2.1   misho     280: int
                    281: main(int argc, char **argv)
                    282: {
1.1.2.3   misho     283:        char ch, szName[MAXPATHLEN] = { 0 }, mode = 0;
1.1.2.2   misho     284:        int ret = 0, dist = 0, cor = 0, ino = 0;
1.1.2.4 ! misho     285:        u_long offset = 0, baseaddr = (u_long) -1;
        !           286:        u_short newval = 0;
1.1.2.3   misho     287:        void *basemem = NULL;
1.1.2.2   misho     288: 
1.1.2.3   misho     289:        while ((ch = getopt(argc, argv, "hvtr:w:i:d:c:u:s:")) != -1)
1.1.2.2   misho     290:                switch (ch) {
                    291:                        case 'v':
                    292:                                Verbose++;
                    293:                                break;
                    294:                        case 't':
                    295:                                mode |= 2;
                    296:                                break;
                    297:                        case 'i':
                    298:                                ino = strtol(optarg, NULL, 0);
                    299:                                if (ino < 0) {
                    300:                                        printf("Error:: in interface number %d\n", ino);
                    301:                                        return 1;
                    302:                                }
                    303:                                break;
                    304:                        case 'd':
                    305:                                mode |= 1;
                    306:                                dist = strtol(optarg, NULL, 0);
                    307:                                if (dist < 1) {
                    308:                                        printf("Error:: in distance meters %d\n", dist);
                    309:                                        return 1;
                    310:                                }
                    311:                                break;
                    312:                        case 'c':
                    313:                                mode |= 1;
                    314:                                cor = strtol(optarg, NULL, 0);
                    315:                                break;
1.1.2.3   misho     316:                        case 's':
                    317:                                mode = 0x10;
                    318:                                strlcpy(szName, optarg, MAXPATHLEN);
                    319:                                break;
                    320:                        case 'u':
                    321:                                mode = 0x20;
                    322:                                strlcpy(szName, optarg, MAXPATHLEN);
                    323:                                break;
                    324:                        case 'r':
                    325:                                mode = 4;
                    326:                                offset = strtoul(optarg, NULL, 0);
                    327:                                break;
                    328:                        case 'w':
                    329:                                mode = 8;
                    330:                                offset = strtoul(optarg, NULL, 0);
                    331:                                break;
1.1.2.2   misho     332:                        case 'h':
                    333:                        default:
                    334:                                Usage();
                    335:                                return 1;
                    336:                }
                    337:        argc -= optind;
                    338:        argv += optind;
1.1.2.3   misho     339:        if (argc && *argv)
                    340:                baseaddr = strtoul(*argv, NULL, 0);
1.1.2.2   misho     341:        if (!mode) {
                    342:                printf("Error:: not selected mode for operation ...\n");
                    343:                return 1;
                    344:        }
1.1.2.3   misho     345:        if (mode > 3 && baseaddr == (u_long) -1) {
                    346:                printf("Error:: in this mode for operation, must give memory mapped address ...\n");
                    347:                return 1;
                    348:        }
1.1.2.4 ! misho     349:        if (mode & 8) {
        !           350:                if (!argv[1]) {
        !           351:                        printf("Error:: in write word mode, must give memory mapped address and new value ...\n");
        !           352:                        return 1;
        !           353:                } else
        !           354:                        newval = (u_short) strtoul(argv[1], NULL, 0);
        !           355:        }
1.1.2.2   misho     356: 
                    357:        if (mode & 1)
                    358:                if ((ret = calcDistance(ino, dist, cor)) < 1)
                    359:                        return 2;
                    360:        if (mode & 2) {
                    361:                if ((ret = calcTimeout(ino, cor)) < 1)
                    362:                        return 2;
                    363:                else {
                    364:                        VERB(1)
                    365:                                printf("Maximum approximate distance ~%d meters\n", ret);
                    366:                        else
                    367:                                printf("~%d\n", ret);
                    368:                }
                    369:        }
                    370: 
1.1.2.3   misho     371:        if (mode & 4) {
                    372:                if (!(basemem = devOpen(baseaddr)))
                    373:                        return 2;
1.1.2.4 ! misho     374:                if ((ret = readWord(basemem, offset)) < 1) {
        !           375:                        devClose(basemem);
        !           376:                        return 3;
        !           377:                }
        !           378:                devClose(basemem);
        !           379:        }
        !           380:        if (mode & 8) {
        !           381:                if (!(basemem = devOpen(baseaddr)))
        !           382:                        return 2;
        !           383:                if ((ret = writeWord(basemem, offset, newval)) < 1) {
        !           384:                        devClose(basemem);
        !           385:                        return 3;
        !           386:                }
1.1.2.3   misho     387:                devClose(basemem);
                    388:        }
                    389: 
1.1.2.1   misho     390:        return 0;
                    391: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>