mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-19 07:16:16 +02:00
[package] iwinfo: implement proper hardware detection for ar23xx SoC devices like the NanoStation 2
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@30605 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
c2da468a0c
commit
e01799a285
@ -7,7 +7,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=libiwinfo
|
PKG_NAME:=libiwinfo
|
||||||
PKG_RELEASE:=25
|
PKG_RELEASE:=26
|
||||||
|
|
||||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||||
PKG_CONFIG_DEPENDS := \
|
PKG_CONFIG_DEPENDS := \
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
@ -39,4 +39,6 @@ void iwinfo_close(void);
|
|||||||
|
|
||||||
struct iwinfo_hardware_entry * iwinfo_hardware(struct iwinfo_hardware_id *id);
|
struct iwinfo_hardware_entry * iwinfo_hardware(struct iwinfo_hardware_id *id);
|
||||||
|
|
||||||
|
int iwinfo_hardware_id_from_mtd(struct iwinfo_hardware_id *id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -988,40 +988,6 @@ int madwifi_get_mbssid_support(const char *ifname, int *buf)
|
|||||||
return -1;
|
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)
|
int madwifi_get_hardware_id(const char *ifname, char *buf)
|
||||||
{
|
{
|
||||||
char vendor[64];
|
char vendor[64];
|
||||||
@ -1030,32 +996,7 @@ int madwifi_get_hardware_id(const char *ifname, char *buf)
|
|||||||
struct iwinfo_hardware_entry *e;
|
struct iwinfo_hardware_entry *e;
|
||||||
|
|
||||||
if (wext_get_hardware_id(ifname, buf))
|
if (wext_get_hardware_id(ifname, buf))
|
||||||
{
|
return iwinfo_hardware_id_from_mtd((struct iwinfo_hardware_id *)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 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1073,24 +1014,12 @@ madwifi_get_hardware_entry(const char *ifname)
|
|||||||
|
|
||||||
int madwifi_get_hardware_name(const char *ifname, char *buf)
|
int madwifi_get_hardware_name(const char *ifname, char *buf)
|
||||||
{
|
{
|
||||||
char vendor[64];
|
|
||||||
char device[64];
|
|
||||||
const struct iwinfo_hardware_entry *hw;
|
const struct iwinfo_hardware_entry *hw;
|
||||||
|
|
||||||
if (!(hw = madwifi_get_hardware_entry(ifname)))
|
if (!(hw = madwifi_get_hardware_entry(ifname)))
|
||||||
{
|
sprintf(buf, "Generic Atheros");
|
||||||
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");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
sprintf(buf, "%s %s", hw->vendor_name, hw->device_name);
|
sprintf(buf, "%s %s", hw->vendor_name, hw->device_name);
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1646,7 +1646,7 @@ int nl80211_get_hardware_id(const char *ifname, char *buf)
|
|||||||
/* Reuse existing interface */
|
/* Reuse existing interface */
|
||||||
if ((res = nl80211_phy2ifname(ifname)) != NULL)
|
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 */
|
/* 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);
|
rv = wext_get_hardware_id(res, buf);
|
||||||
nl80211_ifdel(res);
|
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 *
|
static const struct iwinfo_hardware_entry *
|
||||||
|
@ -150,3 +150,63 @@ struct iwinfo_hardware_entry * iwinfo_hardware(struct iwinfo_hardware_id *id)
|
|||||||
|
|
||||||
return NULL;
|
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;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user