From: Jo-Philipp Wich Date: Fri, 17 Feb 2012 00:36:25 +0000 (+0000) Subject: iwinfo: implement proper hardware detection for ar23xx SoC devices like the NanoStation 2 X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=018d69c3b3421ff86be0004a25943068cd54aace;p=openwrt%2Fstaging%2Flinusw.git iwinfo: implement proper hardware detection for ar23xx SoC devices like the NanoStation 2 SVN-Revision: 30605 --- 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 #include +#include #include #include 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; +}