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>