aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2012-02-17 00:36:25 +0000
committerJo-Philipp Wich <jow@openwrt.org>2012-02-17 00:36:25 +0000
commit018d69c3b3421ff86be0004a25943068cd54aace (patch)
tree25f3ffdfbd017853efe69fecf8793dca16212075
parente17a3ffbbde8622189a4514f864f8241fb1ed485 (diff)
downloadupstream-018d69c3b3421ff86be0004a25943068cd54aace.tar.gz
upstream-018d69c3b3421ff86be0004a25943068cd54aace.tar.bz2
upstream-018d69c3b3421ff86be0004a25943068cd54aace.zip
iwinfo: implement proper hardware detection for ar23xx SoC devices like the NanoStation 2
SVN-Revision: 30605
-rw-r--r--package/iwinfo/Makefile2
-rw-r--r--package/iwinfo/src/include/iwinfo.h1
-rw-r--r--package/iwinfo/src/include/iwinfo/utils.h2
-rw-r--r--package/iwinfo/src/iwinfo_madwifi.c75
-rw-r--r--package/iwinfo/src/iwinfo_nl80211.c15
-rw-r--r--package/iwinfo/src/iwinfo_utils.c60
6 files changed, 78 insertions, 77 deletions
diff --git a/package/iwinfo/Makefile b/package/iwinfo/Makefile
index 27caf9fcba..35ba0cc180 100644
--- a/package/iwinfo/Makefile
+++ b/package/iwinfo/Makefile
@@ -7,7 +7,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libiwinfo
-PKG_RELEASE:=25
+PKG_RELEASE:=26
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
PKG_CONFIG_DEPENDS := \
diff --git a/package/iwinfo/src/include/iwinfo.h b/package/iwinfo/src/include/iwinfo.h
index 198d57c9d2..40b85a0492 100644
--- a/package/iwinfo/src/include/iwinfo.h
+++ b/package/iwinfo/src/include/iwinfo.h
@@ -15,6 +15,7 @@
#include <stdint.h>
#include <sys/ioctl.h>
+#include <sys/mman.h>
#include <net/if.h>
#include <errno.h>
diff --git a/package/iwinfo/src/include/iwinfo/utils.h b/package/iwinfo/src/include/iwinfo/utils.h
index e897b2718a..10246a8e3c 100644
--- a/package/iwinfo/src/include/iwinfo/utils.h
+++ b/package/iwinfo/src/include/iwinfo/utils.h
@@ -39,4 +39,6 @@ void iwinfo_close(void);
struct iwinfo_hardware_entry * iwinfo_hardware(struct iwinfo_hardware_id *id);
+int iwinfo_hardware_id_from_mtd(struct iwinfo_hardware_id *id);
+
#endif
diff --git a/package/iwinfo/src/iwinfo_madwifi.c b/package/iwinfo/src/iwinfo_madwifi.c
index 732cfe56fe..fcd6c8c987 100644
--- a/package/iwinfo/src/iwinfo_madwifi.c
+++ b/package/iwinfo/src/iwinfo_madwifi.c
@@ -988,40 +988,6 @@ int madwifi_get_mbssid_support(const char *ifname, int *buf)
return -1;
}
-static void madwifi_proc_file(const char *ifname, const char *file,
- char *buf, int blen)
-{
- int fd;
- const char *wifi = madwifi_isvap(ifname, NULL);
-
- if (!wifi && madwifi_iswifi(ifname))
- wifi = ifname;
-
- snprintf(buf, blen, "/proc/sys/dev/%s/%s", wifi, file);
-
- if ((fd = open(buf, O_RDONLY)) > 0)
- {
- if (read(fd, buf, blen) > 1)
- buf[strlen(buf)-1] = 0;
- else
- buf[0] = 0;
-
- close(fd);
- }
- else
- {
- buf[0] = 0;
- }
-}
-
-static int madwifi_startswith(const char *a, const char *b)
-{
- int l1 = strlen(a);
- int l2 = strlen(b);
- int ln = (l1 < l2) ? l1 : l2;
- return !strncmp(a, b, ln);
-}
-
int madwifi_get_hardware_id(const char *ifname, char *buf)
{
char vendor[64];
@@ -1030,32 +996,7 @@ int madwifi_get_hardware_id(const char *ifname, char *buf)
struct iwinfo_hardware_entry *e;
if (wext_get_hardware_id(ifname, buf))
- {
- ids = (struct iwinfo_hardware_id *)buf;
- madwifi_proc_file(ifname, "dev_vendor", vendor, sizeof(vendor));
- madwifi_proc_file(ifname, "dev_name", device, sizeof(device));
-
- if (vendor[0] && device[0])
- {
- for (e = IWINFO_HARDWARE_ENTRIES; e->vendor_name; e++)
- {
- if (!madwifi_startswith(vendor, e->vendor_name))
- continue;
-
- if (!madwifi_startswith(device, e->device_name))
- continue;
-
- ids->vendor_id = e->vendor_id;
- ids->device_id = e->device_id;
- ids->subsystem_vendor_id = e->subsystem_vendor_id;
- ids->subsystem_device_id = e->subsystem_device_id;
-
- return 0;
- }
- }
-
- return -1;
- }
+ return iwinfo_hardware_id_from_mtd((struct iwinfo_hardware_id *)buf);
return 0;
}
@@ -1073,24 +1014,12 @@ madwifi_get_hardware_entry(const char *ifname)
int madwifi_get_hardware_name(const char *ifname, char *buf)
{
- char vendor[64];
- char device[64];
const struct iwinfo_hardware_entry *hw;
if (!(hw = madwifi_get_hardware_entry(ifname)))
- {
- madwifi_proc_file(ifname, "dev_vendor", vendor, sizeof(vendor));
- madwifi_proc_file(ifname, "dev_name", device, sizeof(device));
-
- if (vendor[0] && device[0])
- sprintf(buf, "%s %s", vendor, device);
- else
- sprintf(buf, "Generic Atheros");
- }
+ sprintf(buf, "Generic Atheros");
else
- {
sprintf(buf, "%s %s", hw->vendor_name, hw->device_name);
- }
return 0;
}
diff --git a/package/iwinfo/src/iwinfo_nl80211.c b/package/iwinfo/src/iwinfo_nl80211.c
index e8cfb902f0..5c6f7a8ef8 100644
--- a/package/iwinfo/src/iwinfo_nl80211.c
+++ b/package/iwinfo/src/iwinfo_nl80211.c
@@ -1646,7 +1646,7 @@ int nl80211_get_hardware_id(const char *ifname, char *buf)
/* Reuse existing interface */
if ((res = nl80211_phy2ifname(ifname)) != NULL)
{
- return wext_get_hardware_id(res, buf);
+ rv = wext_get_hardware_id(res, buf);
}
/* Need to spawn a temporary iface for finding IDs */
@@ -1654,11 +1654,20 @@ int nl80211_get_hardware_id(const char *ifname, char *buf)
{
rv = wext_get_hardware_id(res, buf);
nl80211_ifdel(res);
- return rv;
}
}
+ else
+ {
+ rv = wext_get_hardware_id(ifname, buf);
+ }
- return wext_get_hardware_id(ifname, buf);
+ /* Failed to obtain hardware IDs, search board config */
+ if (rv)
+ {
+ rv = iwinfo_hardware_id_from_mtd(buf);
+ }
+
+ return rv;
}
static const struct iwinfo_hardware_entry *
diff --git a/package/iwinfo/src/iwinfo_utils.c b/package/iwinfo/src/iwinfo_utils.c
index b49447b072..ec6aa2233f 100644
--- a/package/iwinfo/src/iwinfo_utils.c
+++ b/package/iwinfo/src/iwinfo_utils.c
@@ -150,3 +150,63 @@ struct iwinfo_hardware_entry * iwinfo_hardware(struct iwinfo_hardware_id *id)
return NULL;
}
+
+int iwinfo_hardware_id_from_mtd(struct iwinfo_hardware_id *id)
+{
+ FILE *mtd;
+ uint16_t *bc;
+
+ int fd, len, off;
+ char buf[128];
+
+ if (!(mtd = fopen("/proc/mtd", "r")))
+ return -1;
+
+ while (fgets(buf, sizeof(buf), mtd) > 0)
+ {
+ if (fscanf(mtd, "mtd%d: %*x %x %127s", &off, &len, buf) < 3 ||
+ strcmp(buf, "\"boardconfig\""))
+ {
+ off = -1;
+ continue;
+ }
+
+ break;
+ }
+
+ fclose(mtd);
+
+ if (off < 0)
+ return -1;
+
+ snprintf(buf, sizeof(buf), "/dev/mtdblock%d", off);
+
+ if ((fd = open(buf, O_RDONLY)) < 0)
+ return -1;
+
+ bc = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_LOCKED, fd, 0);
+
+ if ((void *)bc != MAP_FAILED)
+ {
+ id->vendor_id = 0;
+ id->device_id = 0;
+
+ for (off = len / 2 - 0x800; off >= 0; off -= 0x800)
+ {
+ if ((bc[off] == 0x3533) && (bc[off + 1] == 0x3131))
+ {
+ id->vendor_id = bc[off + 0x7d];
+ id->device_id = bc[off + 0x7c];
+ id->subsystem_vendor_id = bc[off + 0x84];
+ id->subsystem_device_id = bc[off + 0x83];
+ break;
+ }
+ }
+
+ munmap(bc, len);
+ }
+
+ close(fd);
+
+ return (id->vendor_id && id->device_id) ? 0 : -1;
+}