Annotation of embedtools/src/athctl.c, revision 1.1.2.11
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.11! misho 6: * $Id: athctl.c,v 1.1.2.10 2010/11/03 14:34:58 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"
1.1.2.11! misho 29: " athctl [-v] -u <file> <0xMemory_Address>\n"
! 30: " athctl [-v] -R <0xMemory_Address> [new_regdomain]\n"
1.1.2.3 misho 31: "\n"
1.1.2.2 misho 32: "\t-v\t\tVerbose ...\n"
33: "\t-t\t\tGet current Atheros maximum range in meters\n"
34: "\t-i <iface_no>\tApply to this Atheros interface number (like ath0 == 0)\n"
35: "\t-d <distance>\tMode distance, meters to target\n"
36: "\t-c <timeout>\tMode distance, mS timeouts correction\n"
1.1.2.11! misho 37: "\t-R\t\tRead or Write EEPROM Regulatory domain\n"
1.1.2.3 misho 38: "\t-s <file>\tDump EEPROM to file\n"
39: "\t-u <file>\tUpdate EEPROM from file\n"
40: "\t-r <offset>\tRead EEPROM word from PCI mapped memory address\n"
41: "\t-w <offset>\tWrite EEPROM word to PCI mapped memory address\n"
1.1.2.2 misho 42: "\n", compiled, compiledby, compilehost);
43: }
44:
45: static int
46: calcDistance(int ifid, int dist, int cor)
47: {
48: int slottime[2], timeout[2];
49: size_t len;
50: char szStr[STRSIZ];
51:
52: slottime[0] = 9 + (dist / 300) + (dist % 300 ? 1 : 0);
53: timeout[0] = slottime[0] * 2 + 3 + cor;
54: VERB(3) printf("Info:: slottime=%d timeout=%d\n", slottime[0], timeout[0]);
55:
56: memset(szStr, 0, STRSIZ);
57: snprintf(szStr, STRSIZ, SC_SLOTTIME, ifid);
58: if (sysctlbyname(szStr, NULL, &len, NULL, 0) == -1) {
59: printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
60: return -1;
61: } else if (sysctlbyname(szStr, &slottime[1], &len, NULL, 0) == -1) {
62: printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
63: return -1;
64: } else if (sysctlbyname(szStr, NULL, NULL, &slottime[0], sizeof slottime[0]) == -1) {
65: printf("Error:: set sysctl %s from %d #%d - %s\n", szStr, slottime[1],
66: errno, strerror(errno));
67: return -1;
68: } else
69: VERB(1) printf("Info:: set slottime(%d) from %d to %d ... OK!\n", len,
70: slottime[1], slottime[0]);
71:
72: memset(szStr, 0, STRSIZ);
73: snprintf(szStr, STRSIZ, SC_ACKTIMEOUT, ifid);
74: if (sysctlbyname(szStr, NULL, &len, NULL, 0) == -1) {
75: printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
76: return -1;
77: } else if (sysctlbyname(szStr, &timeout[1], &len, NULL, 0) == -1) {
78: printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
79: return -1;
80: } else if (sysctlbyname(szStr, NULL, NULL, &timeout[0], sizeof timeout[0]) == -1) {
81: printf("Error:: set sysctl %s from %d #%d - %s\n", szStr, timeout[1],
82: errno, strerror(errno));
83: return -1;
84: } else
85: VERB(1) printf("Info:: set acktimeout(%d) from %d to %d ... OK!\n", len,
86: timeout[1], timeout[0]);
87:
88: memset(szStr, 0, STRSIZ);
89: snprintf(szStr, STRSIZ, SC_CTSTIMEOUT, ifid);
90: if (sysctlbyname(szStr, NULL, &len, NULL, 0) == -1) {
91: printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
92: return -1;
93: } else if (sysctlbyname(szStr, &timeout[1], &len, NULL, 0) == -1) {
94: printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
95: return -1;
96: } else if (sysctlbyname(szStr, NULL, NULL, &timeout[0], sizeof timeout[0]) == -1) {
97: printf("Error:: set sysctl %s from %d #%d - %s\n", szStr, timeout[1],
98: errno, strerror(errno));
99: return -1;
100: } else
101: VERB(1) printf("Info:: set ctstimeout(%d) from %d to %d ... OK!\n", len,
102: timeout[1], timeout[0]);
103:
104: return timeout[0];
105: }
106:
107:
108: static int
109: calcTimeout(int ifid, int cor)
110: {
111: int slottime[2], timeout[2];
112: size_t len;
113: char szStr[STRSIZ];
114:
115: memset(szStr, 0, STRSIZ);
116: snprintf(szStr, STRSIZ, SC_SLOTTIME, ifid);
117: if (sysctlbyname(szStr, NULL, &len, NULL, 0) == -1) {
118: printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
119: return -1;
120: } else if (sysctlbyname(szStr, &slottime[1], &len, NULL, 0) == -1) {
121: printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
122: return -1;
123: } else
124: VERB(1) printf("Info:: get slottime(%d) %d ... OK!\n", len, slottime[1]);
125:
126: memset(szStr, 0, STRSIZ);
127: snprintf(szStr, STRSIZ, SC_ACKTIMEOUT, ifid);
128: if (sysctlbyname(szStr, NULL, &len, NULL, 0) == -1) {
129: printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
130: return -1;
131: } else if (sysctlbyname(szStr, &timeout[1], &len, NULL, 0) == -1) {
132: printf("Error:: get sysctl %s #%d - %s\n", szStr, errno, strerror(errno));
133: return -1;
134: } else
135: VERB(1) printf("Info:: get acktimeout(%d) %d ... OK!\n", len, timeout[1]);
136:
137: slottime[0] = (timeout[1] - 3 - cor) / 2;
138: VERB(3) printf("Info:: calculated slottime=%d\n", slottime[0]);
139: timeout[0] = (slottime[0] - 10) * 300;
140: VERB(3) printf("Info:: calculated timeout=%d\n", timeout[0]);
141:
142: return timeout[0];
143: }
1.1.2.3 misho 144:
145:
146: static inline void *
147: devOpen(u_long baseaddr)
148: {
149: int fd;
150: void *basemem;
151:
152: fd = open("/dev/mem", O_RDWR);
153: if (fd == -1) {
154: printf("Error:: open device #%d - %s\n", errno, strerror(errno));
155: return NULL;
156: }
157: basemem = mmap(NULL, ATH_PCI_MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, baseaddr);
158: if (basemem == MAP_FAILED) {
159: printf("Error:: map device #%d - %s\n", errno, strerror(errno));
160: close(fd);
161: return NULL;
162: } else
163: close(fd);
164:
165: return basemem;
166: }
167:
168: static inline void
169: devClose(void *basemem)
170: {
171: if (basemem)
172: munmap(basemem, ATH_PCI_MEM_SIZE);
173: }
174:
1.1.2.8 misho 175: static inline int
1.1.2.4 misho 176: readWord(u_char *mem, u_long offset)
177: {
178: register int timeout = ATH_ACCESS_TIMEOUT;
179: u_long stat;
180:
1.1.2.11! misho 181: VERB(9) printf("Reading EEPROM memory %p+%lx ...\n", mem, offset);
1.1.2.4 misho 182: ATH_OUT(mem, AR5211_EEPROM_CONF, 0);
183: usleep(ATH_ACCESS_WAIT);
184: /* enable eeprom access */
185: ATH_OUT(mem, AR5211_EEPROM_COMD, ATH_IN(mem, AR5211_EEPROM_COMD) | AR5211_EEPROM_COMD_RESET);
186: usleep(ATH_ACCESS_WAIT);
187: /* set address */
188: ATH_OUT(mem, AR5211_EEPROM_ADDR, offset);
189: usleep(ATH_ACCESS_WAIT);
190: /* enable eeprom read access */
191: ATH_OUT(mem, AR5211_EEPROM_COMD, ATH_IN(mem, AR5211_EEPROM_COMD) | AR5211_EEPROM_COMD_READ);
192: usleep(ATH_ACCESS_WAIT);
193:
194: while (timeout--) {
195: usleep(1);
196: stat = ATH_IN(mem, AR5211_EEPROM_STATUS);
197: if (stat & AR5211_EEPROM_STAT_RDDONE) {
198: if (stat & AR5211_EEPROM_STAT_RDERR) {
199: printf("Error:: EEPROM read failed!\n");
200: return -1;
201: }
202:
203: stat = ATH_IN(mem, AR5211_EEPROM_DATA);
1.1.2.8 misho 204: return (stat & 0x0000ffff) << 16;
1.1.2.4 misho 205: }
206: }
207:
208: printf("Error:: EEPROM read timeout!\n");
1.1.2.7 misho 209: return -1;
1.1.2.4 misho 210: }
211:
1.1.2.8 misho 212: static inline int
1.1.2.4 misho 213: writeWord(u_char *mem, u_long offset, u_short newval)
214: {
215: register int i = ATH_WRITE_RETRY, timeout;
216: u_long pcicfg, stat;
1.1.2.11! misho 217: int chk;
1.1.2.4 misho 218:
1.1.2.11! misho 219: VERB(9) printf("Writing EEPROM memory %p+%lx ...\n", mem, offset);
1.1.2.4 misho 220: /* enable pci write access */
221: pcicfg = ATH_IN(mem, AR5K_PCICFG);
222: ATH_OUT(mem, AR5K_PCICFG, (pcicfg & ~AR5K_PCICFG_SPWR_DN));
223: usleep(ATH_ACCESS_WAITDOWN);
224: ATH_OUT(mem, AR5K_PCICFG, pcicfg | AR5K_PCICFG_EEAE /* | 0x2 */);
225: usleep(ATH_ACCESS_WAITPCI);
226: ATH_OUT(mem, AR5211_EEPROM_STATUS, 0);
227: usleep(ATH_ACCESS_WAITPCI);
228: /* ATH_OUT(mem, AR5211_EEPROM_CONF, 1); */
229: ATH_OUT(mem, AR5211_EEPROM_CONF, 0);
230:
231: do {
232: /* enable eeprom write access */
233: ATH_OUT(mem, AR5211_EEPROM_COMD, AR5211_EEPROM_COMD_RESET);
234: usleep(ATH_ACCESS_WAITDOWN);
235: ATH_OUT(mem, AR5211_EEPROM_DATA, newval);
236: usleep(ATH_ACCESS_WAIT);
237: ATH_OUT(mem, AR5211_EEPROM_ADDR, offset);
238: usleep(ATH_ACCESS_WAIT);
239: ATH_OUT(mem, AR5211_EEPROM_COMD, AR5211_EEPROM_COMD_WRITE);
240: usleep(ATH_ACCESS_WAIT);
241:
242: for (timeout = ATH_ACCESS_TIMEOUT; timeout; timeout--) {
243: stat = ATH_IN(mem, AR5211_EEPROM_STATUS);
244: if (stat & 0xc) {
245: if (stat & AR5211_EEPROM_STAT_WRERR) {
246: printf("Error:: EEPROM write failed!\n");
247: return -1;
248: }
249:
250: ATH_OUT(mem, AR5211_EEPROM_STATUS, 0);
251: usleep(ATH_ACCESS_WAIT * 2);
252: break;
253: }
254: usleep(ATH_ACCESS_WAIT * 2);
255: }
256:
257: chk = readWord(mem, offset);
258: if (chk == (u_short) -1)
259: return -1;
1.1.2.11! misho 260: if ((u_short) (chk >> 16) == newval)
! 261: return chk;
1.1.2.5 misho 262: else
1.1.2.11! misho 263: VERB(1) printf("Write & Read don`t match 0x%04X != 0x%04X\n", newval, (u_short) (chk >> 16));
1.1.2.4 misho 264: if (i)
265: printf("Warning:: Retrying EEPROM write ...\n");
266: } while (--i);
267:
268: printf("Error:: EEPROM write timeout!\n");
1.1.2.7 misho 269: return -1;
1.1.2.4 misho 270: }
271:
1.1.2.3 misho 272: static int
1.1.2.5 misho 273: dumpFile(const char *csName, u_char *mem)
1.1.2.3 misho 274: {
275: register u_long i;
1.1.2.8 misho 276: u_short d1, d2;
1.1.2.11! misho 277: u_char eeprom[ATH_EEPROM_SIZE] = { 0 };
1.1.2.8 misho 278: int f, data;
1.1.2.3 misho 279:
1.1.2.8 misho 280: VERB(2) printf("Reading EEPROM memory %p ::\n", mem);
1.1.2.3 misho 281: for (i = 0; i < ATH_EEPROM_SIZE / 2; i++) {
1.1.2.5 misho 282: if (!(i % 0x40)) {
283: if (i)
284: printf("]\n");
1.1.2.9 misho 285: printf("0x%04lX [", i * 2);
1.1.2.5 misho 286: }
287:
1.1.2.8 misho 288: if ((data = readWord(mem, i)) == -1)
1.1.2.5 misho 289: return -1;
290: else {
1.1.2.11! misho 291: d1 = ((u_short)(data >> 16)) / 0x100;
! 292: d2 = ((u_short)(data >> 16)) % 0x100;
! 293:
! 294: VERB(5) printf( "Current value 0x%04X on position 0x%04lX will change 0x%02X 0x%02X\n",
! 295: (u_short) (data >> 16), i, d1, d2);
1.1.2.5 misho 296: }
297:
298: eeprom[i * 2] = d2;
299: eeprom[i * 2 + 1] = d1;
300:
301: printf(".");
302: usleep(ATH_ACCESS_WAITDOWN);
303: }
304: printf("]\n");
305:
1.1.2.8 misho 306: VERB(2) printf("Saving EEPROM to file %s ... ", csName);
1.1.2.5 misho 307: f = open(csName, O_WRONLY | O_CREAT | O_TRUNC, 0644);
308: if (f == -1) {
309: printf("Failed!\nError:: in create file %s #%d - %s\n", csName,
310: errno, strerror(errno));
311: return 0;
312: }
313: if (write(f, eeprom, ATH_EEPROM_SIZE) == -1) {
314: printf("Failed!\nError:: in write to file %s #%d - %s\n", csName,
315: errno, strerror(errno));
316: close(f);
317: return 0;
1.1.2.3 misho 318: }
1.1.2.5 misho 319: close(f);
320: printf("OK!\n");
321: return 1;
322: }
323:
324: static int
325: flashFile(const char *csName, u_char *mem)
326: {
327: register u_long i;
1.1.2.8 misho 328: u_short d1;
1.1.2.11! misho 329: u_char eeprom[ATH_EEPROM_SIZE] = { 0 };
1.1.2.8 misho 330: int f, data;
1.1.2.5 misho 331:
1.1.2.8 misho 332: VERB(2) printf("Reading EEPROM from file %s ... ", csName);
1.1.2.5 misho 333: f = open(csName, O_RDONLY);
334: if (f == -1) {
335: printf("Failed!\nError:: in open file %s #%d - %s\n", csName,
336: errno, strerror(errno));
337: return 0;
338: }
339: if (read(f, eeprom, ATH_EEPROM_SIZE) != ATH_EEPROM_SIZE) {
340: printf("Failed!\nError:: failed load image from file %s\n", csName);
341: close(f);
342: return 0;
343: }
344: close(f);
1.1.2.11! misho 345: VERB(2) printf("OK!\n");
1.1.2.5 misho 346:
1.1.2.8 misho 347: VERB(2) printf("Writing EEPROM memory %p ::\n", mem);
1.1.2.5 misho 348: for (i = 0; i < ATH_EEPROM_SIZE / 2; i++) {
349: if (!(i % 0x40)) {
350: if (i)
351: printf("]\n");
1.1.2.9 misho 352: printf("0x%04lX [", i * 2);
1.1.2.5 misho 353: }
354:
1.1.2.8 misho 355: if ((data = readWord(mem, i)) == -1)
1.1.2.5 misho 356: return -1;
357: else
358: d1 = eeprom[i * 2 + 1] * 0x100 + eeprom[i * 2];
1.1.2.11! misho 359: VERB(5) printf("eeprom_data=0x%04X read_d1=0x%04X\n", (u_char) (data >> 16), d1);
1.1.2.5 misho 360:
1.1.2.11! misho 361: if (((u_short) (data >> 16)) == d1)
1.1.2.5 misho 362: printf(".");
363: else {
364:
365: if (writeWord(mem, i, d1) < 1)
1.1.2.11! misho 366: printf("!");
! 367: else
! 368: printf("x");
1.1.2.5 misho 369: }
370:
371: usleep(ATH_ACCESS_WAITDOWN);
372: }
373: printf("]\n");
374:
375: return 0;
1.1.2.3 misho 376: }
377:
1.1.2.2 misho 378: // ----------------------------------------------------
379:
1.1.2.1 misho 380: int
381: main(int argc, char **argv)
382: {
1.1.2.3 misho 383: char ch, szName[MAXPATHLEN] = { 0 }, mode = 0;
1.1.2.2 misho 384: int ret = 0, dist = 0, cor = 0, ino = 0;
1.1.2.4 misho 385: u_long offset = 0, baseaddr = (u_long) -1;
386: u_short newval = 0;
1.1.2.3 misho 387: void *basemem = NULL;
1.1.2.2 misho 388:
1.1.2.11! misho 389: while ((ch = getopt(argc, argv, "hvRtr:w:i:d:c:u:s:")) != -1)
1.1.2.2 misho 390: switch (ch) {
391: case 'v':
392: Verbose++;
393: break;
394: case 't':
395: mode |= 2;
396: break;
397: case 'i':
398: ino = strtol(optarg, NULL, 0);
399: if (ino < 0) {
400: printf("Error:: in interface number %d\n", ino);
401: return 1;
402: }
403: break;
404: case 'd':
405: mode |= 1;
406: dist = strtol(optarg, NULL, 0);
407: if (dist < 1) {
408: printf("Error:: in distance meters %d\n", dist);
409: return 1;
410: }
411: break;
412: case 'c':
413: mode |= 1;
414: cor = strtol(optarg, NULL, 0);
415: break;
1.1.2.3 misho 416: case 's':
417: mode = 0x10;
418: strlcpy(szName, optarg, MAXPATHLEN);
419: break;
420: case 'u':
421: mode = 0x20;
422: strlcpy(szName, optarg, MAXPATHLEN);
423: break;
1.1.2.11! misho 424: case 'R':
! 425: mode = 0x40;
! 426: break;
1.1.2.3 misho 427: case 'r':
428: mode = 4;
429: offset = strtoul(optarg, NULL, 0);
430: break;
431: case 'w':
432: mode = 8;
433: offset = strtoul(optarg, NULL, 0);
434: break;
1.1.2.2 misho 435: case 'h':
436: default:
437: Usage();
438: return 1;
439: }
440: argc -= optind;
441: argv += optind;
1.1.2.3 misho 442: if (argc && *argv)
443: baseaddr = strtoul(*argv, NULL, 0);
1.1.2.2 misho 444: if (!mode) {
445: printf("Error:: not selected mode for operation ...\n");
446: return 1;
447: }
1.1.2.3 misho 448: if (mode > 3 && baseaddr == (u_long) -1) {
449: printf("Error:: in this mode for operation, must give memory mapped address ...\n");
450: return 1;
451: }
1.1.2.4 misho 452: if (mode & 8) {
453: if (!argv[1]) {
454: printf("Error:: in write word mode, must give memory mapped address and new value ...\n");
455: return 1;
456: } else
457: newval = (u_short) strtoul(argv[1], NULL, 0);
458: }
1.1.2.11! misho 459: if (mode & 0x40 && argv[1])
! 460: newval = (u_short) strtoul(argv[1], NULL, 0);
1.1.2.2 misho 461:
462: if (mode & 1)
463: if ((ret = calcDistance(ino, dist, cor)) < 1)
464: return 2;
465: if (mode & 2) {
466: if ((ret = calcTimeout(ino, cor)) < 1)
467: return 2;
468: else {
469: VERB(1)
470: printf("Maximum approximate distance ~%d meters\n", ret);
471: else
472: printf("~%d\n", ret);
473: }
474: }
475:
1.1.2.3 misho 476: if (mode & 4) {
477: if (!(basemem = devOpen(baseaddr)))
478: return 2;
1.1.2.7 misho 479: if ((ret = readWord(basemem, offset)) == -1) {
1.1.2.4 misho 480: devClose(basemem);
481: return 3;
1.1.2.6 misho 482: } else
1.1.2.11! misho 483: printf("EEPROM readed value 0x%04X\n", (u_short) (ret >> 16));
1.1.2.4 misho 484: devClose(basemem);
485: }
486: if (mode & 8) {
487: if (!(basemem = devOpen(baseaddr)))
488: return 2;
1.1.2.7 misho 489: if ((ret = writeWord(basemem, offset, newval)) == -1) {
1.1.2.4 misho 490: devClose(basemem);
491: return 3;
1.1.2.7 misho 492: } else
1.1.2.11! misho 493: printf("EEPROM writed value 0x%04X\n", (u_short) (ret >> 16));
1.1.2.3 misho 494: devClose(basemem);
495: }
496:
1.1.2.5 misho 497: if (mode & 0x10) {
1.1.2.10 misho 498: if (!(basemem = devOpen(baseaddr)))
499: return 2;
1.1.2.5 misho 500: if ((ret = dumpFile(szName, basemem)) < 1) {
1.1.2.10 misho 501: devClose(basemem);
1.1.2.5 misho 502: return 3;
503: }
1.1.2.10 misho 504: devClose(basemem);
1.1.2.5 misho 505: }
506: if (mode & 0x20) {
507: if (!(basemem = devOpen(baseaddr)))
508: return 2;
509: if ((ret = flashFile(szName, basemem)) < 1) {
510: devClose(basemem);
511: return 3;
512: }
513: devClose(basemem);
514: }
515:
1.1.2.11! misho 516: if (mode & 0x40) {
! 517: if (!(basemem = devOpen(baseaddr)))
! 518: return 2;
! 519: /*
! 520: if ((ret = regDomain(basemem, newval)) < 1) {
! 521: devClose(basemem);
! 522: return 3;
! 523: }
! 524: */
! 525: devClose(basemem);
! 526: }
! 527:
1.1.2.1 misho 528: return 0;
529: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>