diff options
Diffstat (limited to 'package/broadcom-wl/src/wlc')
| -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 f5db9a763..aa9a559f7 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))  | 
