iwinfo: implement proper hardware detection for ar23xx SoC devices like the NanoStation 2
authorJo-Philipp Wich <jow@openwrt.org>
Fri, 17 Feb 2012 00:36:25 +0000 (00:36 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Fri, 17 Feb 2012 00:36:25 +0000 (00:36 +0000)
SVN-Revision: 30605

package/iwinfo/Makefile
package/iwinfo/src/include/iwinfo.h
package/iwinfo/src/include/iwinfo/utils.h
package/iwinfo/src/iwinfo_madwifi.c
package/iwinfo/src/iwinfo_nl80211.c
package/iwinfo/src/iwinfo_utils.c

index 27caf9fcba15baeb429e0c6c20998277084fa467..35ba0cc1808fbd6524d7822661c80cd034ab8014 100644 (file)
@@ -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 := \
index 198d57c9d2a4644cca2b8b75845365bfafa0a44f..40b85a049218ea8acae33a0dbd9ee084d1b20190 100644 (file)
@@ -15,6 +15,7 @@
 #include <stdint.h>
 
 #include <sys/ioctl.h>
+#include <sys/mman.h>
 #include <net/if.h>
 #include <errno.h>
 
index e897b2718a332b6924d0bac860a805c3a74f56df..10246a8e3cea2bf5ae853e03fd519b2856d12674 100644 (file)
@@ -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
index 732cfe56fe8f02121ab855e11729f9c8d5ae5f31..fcd6c8c9871741f2645e5e7cabfaf538e78d5def 100644 (file)
@@ -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;
 }
index e8cfb902f04c5ad20166bbe8b3037b8b2c1f8d01..5c6f7a8ef8dcffe1d4ef7123098d8b696043a2dd 100644 (file)
@@ -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 *
index b49447b072aa277d150ff3bdf61d8de659fe7a8d..ec6aa2233f38ac38cc6e1ea752785fde964cad44 100644 (file)
@@ -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;
+}