aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2001-12-05 08:57:36 +0000
committerWarner Losh <imp@FreeBSD.org>2001-12-05 08:57:36 +0000
commit3b289629dbaa8eb98cc6500ba490e0fae96ae0d2 (patch)
treeb6172e5cb5a461f66cfc5575633b4b50b055a69f
parent023fe503025d3927be8694bb464379eee7e17f2e (diff)
downloadsrc-3b289629dbaa8eb98cc6500ba490e0fae96ae0d2.tar.gz
src-3b289629dbaa8eb98cc6500ba490e0fae96ae0d2.zip
Implement prism2 detection from NetBSD. This mostly obsoletes the
prism2 flag in pccard.conf, but I'm leaving it place for the moment in case the small sample of PrismII cards that I've tried is not representative. MFC After: 30 days Obtained from: NetBSD
Notes
Notes: svn path=/head/; revision=87383
-rw-r--r--sys/dev/wi/if_wi.c111
-rw-r--r--sys/dev/wi/if_wireg.h23
2 files changed, 107 insertions, 27 deletions
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index a0a241449451..1573f856f39d 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -124,6 +124,13 @@ static const char rcsid[] =
static u_int8_t wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 };
#endif
+/*
+ * The following is for compatibility with NetBSD, but should really be
+ * brought in from NetBSD en toto.
+ */
+#define le16toh(a) (a)
+#define LE16TOH(a)
+
static void wi_intr __P((void *));
static void wi_reset __P((struct wi_softc *));
static int wi_ioctl __P((struct ifnet *, u_long, caddr_t));
@@ -170,6 +177,7 @@ static int wi_alloc __P((device_t, int));
static void wi_free __P((device_t));
static int wi_get_cur_ssid __P((struct wi_softc *, char *, int *));
+static void wi_get_id __P((struct wi_softc *, device_t));
static int wi_media_change __P((struct ifnet *));
static void wi_media_status __P((struct ifnet *, struct ifmediareq *));
@@ -350,33 +358,9 @@ static int wi_pccard_attach(device_t dev)
{
struct wi_softc *sc;
int error;
- u_int32_t flags;
sc = device_get_softc(dev);
- /*
- * XXX: quick hack to support Prism II chip.
- * Currently, we need to set a flags in pccard.conf to specify
- * which type chip is used.
- *
- * We need to replace this code in a future.
- * It is better to use CIS than using a flag.
- */
- flags = device_get_flags(dev);
-#define WI_FLAGS_PRISM2 0x10000
- if (flags & WI_FLAGS_PRISM2) {
- sc->wi_prism2 = 1;
- if (bootverbose) {
- device_printf(dev, "found PrismII chip\n");
- }
- }
- else {
- sc->wi_prism2 = 0;
- if (bootverbose) {
- device_printf(dev, "found Lucent chip\n");
- }
- }
-
error = wi_alloc(dev, 0);
if (error) {
device_printf(dev, "wi_alloc() failed! (%d)\n", error);
@@ -510,8 +494,9 @@ wi_generic_attach(device_t dev)
bcopy((char *)&mac.wi_mac_addr,
(char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
- device_printf(dev, "Ethernet address: %6D\n",
- sc->arpcom.ac_enaddr, ":");
+ device_printf(dev, "802.11 address: %6D\n", sc->arpcom.ac_enaddr, ":");
+
+ wi_get_id(sc, dev);
ifp->if_softc = sc;
ifp->if_unit = sc->wi_unit;
@@ -611,6 +596,80 @@ wi_generic_attach(device_t dev)
return(0);
}
+static void
+wi_get_id(sc, dev)
+ struct wi_softc *sc;
+ device_t dev;
+{
+ struct wi_ltv_ver ver;
+
+ /* getting chip identity */
+ memset(&ver, 0, sizeof(ver));
+ ver.wi_type = WI_RID_CARDID;
+ ver.wi_len = 5;
+ wi_read_record(sc, (struct wi_ltv_gen *)&ver);
+ device_printf(dev, "using ");
+ switch (le16toh(ver.wi_ver[0])) {
+ case WI_NIC_EVB2:
+ printf("RF:PRISM2 MAC:HFA3841");
+ sc->wi_prism2 = 1;
+ break;
+ case WI_NIC_HWB3763:
+ printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3763 rev.B");
+ sc->wi_prism2 = 1;
+ break;
+ case WI_NIC_HWB3163:
+ printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.A");
+ sc->wi_prism2 = 1;
+ break;
+ case WI_NIC_HWB3163B:
+ printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.B");
+ sc->wi_prism2 = 1;
+ break;
+ case WI_NIC_EVB3:
+ printf("RF:PRISM2 MAC:HFA3842");
+ sc->wi_prism2 = 1;
+ break;
+ case WI_NIC_HWB1153:
+ printf("RF:PRISM1 MAC:HFA3841 CARD:HWB1153");
+ sc->wi_prism2 = 1;
+ break;
+ case WI_NIC_P2_SST:
+ printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163-SST-flash");
+ sc->wi_prism2 = 1;
+ break;
+ case WI_NIC_PRISM2_5:
+ printf("RF:PRISM2.5 MAC:ISL3873");
+ sc->wi_prism2 = 1;
+ break;
+ case WI_NIC_3874A:
+ printf("RF:PRISM2.5 MAC:ISL3874A(PCI)");
+ sc->wi_prism2 = 1;
+ break;
+ default:
+ printf("Lucent chip or unknown chip\n");
+ sc->wi_prism2 = 0;
+ break;
+ }
+
+ if (sc->wi_prism2) {
+ /* try to get prism2 firm version */
+ memset(&ver, 0, sizeof(ver));
+ ver.wi_type = WI_RID_IDENT;
+ ver.wi_len = 5;
+ wi_read_record(sc, (struct wi_ltv_gen *)&ver);
+ LE16TOH(ver.wi_ver[1]);
+ LE16TOH(ver.wi_ver[2]);
+ LE16TOH(ver.wi_ver[3]);
+ printf(", Firmware: %i.%i variant %i\n", ver.wi_ver[2],
+ ver.wi_ver[3], ver.wi_ver[1]);
+ sc->wi_prism2_ver = ver.wi_ver[2] * 100 +
+ ver.wi_ver[3] * 10 + ver.wi_ver[1];
+ }
+
+ return;
+}
+
static void wi_rxeof(sc)
struct wi_softc *sc;
{
diff --git a/sys/dev/wi/if_wireg.h b/sys/dev/wi/if_wireg.h
index 7602f69e89d2..bcb7368bed76 100644
--- a/sys/dev/wi/if_wireg.h
+++ b/sys/dev/wi/if_wireg.h
@@ -135,7 +135,8 @@ struct wi_softc {
#endif
struct callout_handle wi_stat_ch;
struct mtx wi_mtx;
- int wi_prism2; /* set to 1 if it uses a Prism II chip */
+ int wi_prism2;
+ int wi_prism2_ver;
};
#define WI_LOCK(_sc)
@@ -444,6 +445,26 @@ struct wi_ltv_memsz {
};
/*
+ * NIC Identification (0xFD0B)
+ */
+#define WI_RID_CARDID 0xFD0B
+#define WI_RID_IDENT 0xFD20
+struct wi_ltv_ver {
+ u_int16_t wi_len;
+ u_int16_t wi_type;
+ u_int16_t wi_ver[4];
+#define WI_NIC_EVB2 0x8000
+#define WI_NIC_HWB3763 0x8001
+#define WI_NIC_HWB3163 0x8002
+#define WI_NIC_HWB3163B 0x8003
+#define WI_NIC_EVB3 0x8004
+#define WI_NIC_HWB1153 0x8007
+#define WI_NIC_P2_SST 0x8008 /* Prism2 with SST flush */
+#define WI_NIC_PRISM2_5 0x800C
+#define WI_NIC_3874A 0x8013 /* Prism2.5 Mini-PCI */
+};
+
+/*
* List of intended regulatory domains (0xFD11).
*/
#define WI_RID_DOMAINS 0xFD11