diff options
Diffstat (limited to 'package/broadcom-wl/src/wlc/wlc.c')
-rw-r--r-- | package/broadcom-wl/src/wlc/wlc.c | 225 |
1 files changed, 7 insertions, 218 deletions
diff --git a/package/broadcom-wl/src/wlc/wlc.c b/package/broadcom-wl/src/wlc/wlc.c index f5db9a7..aa9a559 100644 --- a/package/broadcom-wl/src/wlc/wlc.c +++ b/package/broadcom-wl/src/wlc/wlc.c @@ -56,7 +56,6 @@ static char wlbuf[8192]; static char interface[16] = "wl0"; -static unsigned long ptable[128]; static unsigned long kmem_offset = 0; static int vif = 0, debug = 1, fromstdin = 0; @@ -98,205 +97,6 @@ static inline int my_ether_ntoa(unsigned char *ea, char *buf) ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]); } -/* - * find the starting point of wl.o in memory - * by reading /proc/ksyms - */ -static inline void wlc_get_mem_offset(void) -{ - FILE *f; - char s[64]; - - /* yes, i'm lazy ;) */ - f = popen("grep '\\[wl]' /proc/ksyms | sort", "r"); - if (fgets(s, 64, f) == 0) - return; - - pclose(f); - - s[8] = 0; - kmem_offset = strtoul(s, NULL, 16); - - /* sanity check */ - if (kmem_offset < 0xc0000000) - kmem_offset = 0; -} - - -static int ptable_init(void) -{ - glob_t globbuf; - struct stat statbuf; - int fd; - - if (ptable[0] == PTABLE_MAGIC) - return 0; - - glob("/lib/modules/2.4.*/wl.o.patch", 0, NULL, &globbuf); - - if (globbuf.gl_pathv[0] == NULL) - return -1; - - if ((fd = open(globbuf.gl_pathv[0], O_RDONLY)) < 0) - return -1; - - if (fstat(fd, &statbuf) < 0) - goto failed; - - if (statbuf.st_size < 512) - goto failed; - - if (read(fd, ptable, 512) < 512) - goto failed; - - if (ptable[0] != PTABLE_MAGIC) - goto failed; - - close(fd); - - wlc_get_mem_offset(); - if (kmem_offset == 0) - return -1; - - return 0; - -failed: - close(fd); - - return -1; -} - -static inline unsigned long wlc_kmem_read(unsigned long offset) -{ - int fd; - unsigned long ret; - - if ((fd = open("/dev/kmem", O_RDONLY )) < 0) - return -1; - - lseek(fd, 0x70000000, SEEK_SET); - lseek(fd, (kmem_offset - 0x70000000) + offset, SEEK_CUR); - read(fd, &ret, 4); - close(fd); - - return ret; -} - -static inline void wlc_kmem_write(unsigned long offset, unsigned long value) -{ - int fd; - - if ((fd = open("/dev/kmem", O_WRONLY )) < 0) - return; - - lseek(fd, 0x70000000, SEEK_SET); - lseek(fd, (kmem_offset - 0x70000000) + offset, SEEK_CUR); - write(fd, &value, 4); - close(fd); -} - -static int wlc_patcher_getval(unsigned long key, unsigned long *val) -{ - unsigned long *pt = &ptable[1]; - unsigned long tmp; - - if (ptable_init() < 0) { - fprintf(stderr, "Could not load the ptable\n"); - return -1; - } - - while (*pt != PTABLE_END) { - if (*pt == key) { - tmp = wlc_kmem_read(pt[1]); - - if (tmp == pt[2]) - *val = 0xffffffff; - else - *val = tmp; - - return 0; - } - pt += 3; - } - - return -1; -} - -static int wlc_patcher_setval(unsigned long key, unsigned long val) -{ - unsigned long *pt = &ptable[1]; - - if (ptable_init() < 0) { - fprintf(stderr, "Could not load the ptable\n"); - return -1; - } - - if (val != 0xffffffff) - val = (pt[2] & ~(0xffff)) | (val & 0xffff); - - while (*pt != PTABLE_END) { - if (*pt == key) { - if (val == 0xffffffff) /* default */ - val = pt[2]; - - wlc_kmem_write(pt[1], val); - } - pt += 3; - } - - return 0; -} - -static int wlc_slottime(wlc_param param, void *data, void *value) -{ - int *val = (int *) value; - int ret = 0; - - if ((param & PARAM_MODE) == SET) { - wlc_patcher_setval(PTABLE_SLT1, *val); - wlc_patcher_setval(PTABLE_SLT2, ((*val == -1) ? *val : *val + 510)); - } else if ((param & PARAM_MODE) == GET) { - ret = wlc_patcher_getval(PTABLE_SLT1, (unsigned long *) val); - if (*val != 0xffffffff) - *val &= 0xffff; - } - - return ret; -} - -static int wlc_noack(wlc_param param, void *data, void *value) -{ - int *val = (int *) value; - int ret = 0; - - if ((param & PARAM_MODE) == SET) { - wlc_patcher_setval(PTABLE_ACKW, ((*val) ? 1 : 0)); - } else if ((param & PARAM_MODE) == GET) { - ret = wlc_patcher_getval(PTABLE_ACKW, (unsigned long *) val); - *val &= 0xffff; - *val = (*val ? 1 : 0); - } - - return ret; -} - -static int wlc_ibss_merge(wlc_param param, void *data, void *value) -{ - int *val = (int *) value; - int ret = 0; - - if ((param & PARAM_MODE) == SET) { - /* overwrite the instruction with 'lui v0,0x0' - fake a return - * status of 0 for wlc_bcn_tsf_later */ - wlc_patcher_setval(PTABLE_ACKW, ((*val) ? -1 : 0x3c020000)); - } else if ((param & PARAM_MODE) == GET) { - ret = wlc_patcher_getval(PTABLE_ACKW, (unsigned long *) val); - *val = ((*val == -1) ? 1 : 0); - } - - return ret; -} - static int wlc_ioctl(wlc_param param, void *data, void *value) { unsigned int *var = ((unsigned int *) data); @@ -957,6 +757,13 @@ static const struct wlc_call wlc_calls[] = { .desc = "RTS threshold" }, { + .name = "slottime", + .param = INT, + .handler = wlc_iovar, + .data.str = "acktiming", + .desc = "Slot time" + }, + { .name = "rxant", .param = INT, .handler = wlc_ioctl, @@ -1052,24 +859,6 @@ static const struct wlc_call wlc_calls[] = { .handler = wlc_afterburner, .desc = "Broadcom Afterburner" }, - { - .name = "slottime", - .param = INT, - .handler = wlc_slottime, - .desc = "Slot time (-1 = auto)" - }, - { - .name = "txack", - .param = INT, - .handler = wlc_noack, - .desc = "Tx ACK enabled flag" - }, - { - .name = "ibss_merge", - .param = INT, - .handler = wlc_ibss_merge, - .desc = "Allow IBSS merge in Ad-Hoc mode" - } }; #define wlc_calls_size (sizeof(wlc_calls) / sizeof(struct wlc_call)) |