summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2002-04-03 19:44:17 +0000
committerimp <imp@FreeBSD.org>2002-04-03 19:44:17 +0000
commit0b5706252342e9b036051474c986538db78fbecb (patch)
tree70c57ab48bc1d19b6631b2f6c406aa28abc38dd3 /sys
parent9fa365d7d67c21097e519ca5c812844138eb8557 (diff)
downloadFreeBSD-src-0b5706252342e9b036051474c986538db78fbecb.zip
FreeBSD-src-0b5706252342e9b036051474c986538db78fbecb.tar.gz
Four fixes from NetBSD:
1) Properly detect the Symbol based cards (The 3Com Airconnect and their ilk) and only reset them *ONCE* ever. This appears to make them work, but more testing is needed. The tests that would wedge up my machine completely now appear to work, but I have not real access points handy. 2) Report both the Station firmware and the Primary firmware on Prism based cards. On Lucent based cards, only report the station firmware since that's all it supports. On symbol cards, report the symbol specific firmware name as its station firmware. 3) Better Prism 2.5 and 3 family names. We really need to go table driven for this. 4) Workaround for bugs in Intersil's firmware is only needed for at most 0.8.2 and earlier, since 0.8.3 and later appear to work. Obtained from: NetBSD
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/wi/if_wi.c158
-rw-r--r--sys/dev/wi/if_wi_pci.c1
-rw-r--r--sys/dev/wi/if_wireg.h38
-rw-r--r--sys/dev/wi/if_wivar.h11
4 files changed, 146 insertions, 62 deletions
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index aa6a787..765d1fb 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -335,60 +335,85 @@ wi_get_id(sc, dev)
ver.wi_type = WI_RID_CARD_ID;
ver.wi_len = 5;
wi_read_record(sc, (struct wi_ltv_gen *)&ver);
- device_printf(dev, "using ");
- sc->wi_prism2 = 1;
- sc->wi_nic_type = le16toh(ver.wi_ver[0]);
- switch (sc->wi_nic_type) {
+ device_printf(sc->dev, "using ");
+ switch (le16toh(ver.wi_ver[0])) {
case WI_NIC_EVB2:
- printf("RF:PRISM I MAC:HFA3841");
+ printf("RF:PRISM2 MAC:HFA3841");
break;
case WI_NIC_HWB3763:
- printf("RF:PRISM II MAC:HFA3841 CARD:HWB3763 rev.B");
+ printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3763 rev.B");
break;
case WI_NIC_HWB3163:
- printf("RF:PRISM II MAC:HFA3841 CARD:HWB3163 rev.A");
+ printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.A");
break;
case WI_NIC_HWB3163B:
- printf("RF:PRISM II MAC:HFA3841 CARD:HWB3163 rev.B");
+ printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163 rev.B");
break;
case WI_NIC_EVB3:
- case WI_NIC_3842:
- printf("RF:PRISM II MAC:HFA3842");
+ case WI_NIC_3842_EVA:
+ printf("RF:PRISM2 MAC:HFA3842 CARD:HFA3842 EVAL");
break;
case WI_NIC_HWB1153:
- printf("RF:PRISM I MAC:HFA3841 CARD:HWB1153");
+ printf("RF:PRISM1 MAC:HFA3841 CARD:HWB1153");
break;
case WI_NIC_P2_SST:
case WI_NIC_EVB2_SST:
- printf("RF:PRISM II MAC:HFA3841 CARD:HWB3163-SST-flash");
+ printf("RF:PRISM2 MAC:HFA3841 CARD:HWB3163-SST-flash");
break;
- case WI_NIC_PRISM2_5:
+ case WI_NIC_3842_PCMCIA_AMD:
+ case WI_NIC_3842_PCMCIA_SST:
+ case WI_NIC_3842_PCMCIA_ATM:
printf("RF:PRISM2.5 MAC:ISL3873");
break;
- case WI_NIC_3874A:
- printf("RF:PRISM2.5 MAC:ISL3874A(PCI)");
+ case WI_NIC_3842_MINI_AMD:
+ case WI_NIC_3842_MINI_SST:
+ case WI_NIC_3842_MINI_ATM:
+ printf("RF:PRISM2.5 MAC:ISL3874A(Mini-PCI)");
break;
- case WI_NIC_37300P:
- printf("RF:PRISM2.5 MAC:ISL37300P");
+ case WI_NIC_3842_PCI_AMD:
+ case WI_NIC_3842_PCI_SST:
+ case WI_NIC_3842_PCI_ATM:
+ printf("RF:PRISM2.5 MAC:ISL3874A(PCI-bridge)");
break;
- case WI_NIC_P3_SST:
- printf("RF:PRISM3");
+ case WI_NIC_P3_PCMCIA_AMD:
+ case WI_NIC_P3_PCMCIA_SST:
+ printf("RF:PRISM3(PCMCIA)");
break;
- case WI_NIC_P3_PCI:
- printf("RF:PRISM3");
+ case WI_NIC_P3_MINI_AMD:
+ case WI_NIC_P3_MINI_SST:
+ printf("RF:PRISM3(Mini-PCI)");
break;
case WI_NIC_LUCENT:
case WI_NIC_LUCENT_ALT:
- printf("WaveLan/Lucent/Orinoco chip");
- sc->wi_prism2 = 0;
+ printf("Lucent Technologies, WaveLAN/IEEE");
break;
default:
- printf("Lucent chip or unknown chip %04x", ver.wi_ver[0]);
- sc->wi_prism2 = 0;
+ if (le16toh(ver.wi_ver[0]) & 0x8000)
+ printf("Unknown PRISM2 chip");
+ else
+ printf("Unknown Lucent chip");
+ printf(" 0x%x", le16toh(ver.wi_ver[0]));
break;
}
-
- /* get firmware version */
+ if (le16toh(ver.wi_ver[0]) & 0x8000)
+ sc->sc_firmware_type = WI_INTERSIL;
+ else
+ sc->sc_firmware_type = WI_LUCENT;
+
+ if (sc->sc_firmware_type != WI_LUCENT) {
+ /* get primary firmware version */
+ memset(&ver, 0, sizeof(ver));
+ ver.wi_type = WI_RID_PRI_IDENTITY;
+ ver.wi_len = 5;
+ wi_read_record(sc, (struct wi_ltv_gen *)&ver);
+ ver.wi_ver[1] = le16toh(ver.wi_ver[1]);
+ ver.wi_ver[2] = le16toh(ver.wi_ver[2]);
+ ver.wi_ver[3] = le16toh(ver.wi_ver[3]);
+ sc->sc_pri_firmware_ver = ver.wi_ver[2] * 10000 +
+ ver.wi_ver[3] * 100 + ver.wi_ver[1];
+ }
+
+ /* get station firmware version */
memset(&ver, 0, sizeof(ver));
ver.wi_type = WI_RID_STA_IDENTITY;
ver.wi_len = 5;
@@ -396,11 +421,43 @@ wi_get_id(sc, dev)
ver.wi_ver[1] = le16toh(ver.wi_ver[1]);
ver.wi_ver[2] = le16toh(ver.wi_ver[2]);
ver.wi_ver[3] = le16toh(ver.wi_ver[3]);
- sc->wi_firmware_ver = ver.wi_ver[2] * 100 + ver.wi_ver[3] * 10 +
- ver.wi_ver[1];
- printf(", Firmware: %d.%02d variant %d\n", ver.wi_ver[2],
- ver.wi_ver[3], ver.wi_ver[1]);
+ sc->sc_sta_firmware_ver = ver.wi_ver[2] * 10000 +
+ ver.wi_ver[3] * 100 + ver.wi_ver[1];
+ if (sc->sc_firmware_type == WI_INTERSIL &&
+ (sc->sc_sta_firmware_ver == 10102 ||
+ sc->sc_sta_firmware_ver == 20102)) {
+ struct wi_ltv_str sver;
+ char *p;
+
+ memset(&sver, 0, sizeof(sver));
+ sver.wi_type = WI_RID_SYMBOL_IDENTITY;
+ sver.wi_len = 7;
+ /* value should be "V2.00-11" */
+ if (wi_read_record(sc, (struct wi_ltv_gen *)&sver) == 0 &&
+ *(p = (char *)sver.wi_str) == 'V' &&
+ p[2] == '.' && p[5] == '-' && p[8] == '\0') {
+ sc->sc_firmware_type = WI_SYMBOL;
+ sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 +
+ (p[3] - '0') * 1000 + (p[4] - '0') * 100 +
+ (p[6] - '0') * 10 + (p[7] - '0');
+ }
+ }
+ printf("\n");
+ device_printf(sc->dev, "%s Firmware: ",
+ sc->sc_firmware_type == WI_LUCENT ? "Lucent" :
+ (sc->sc_firmware_type == WI_SYMBOL ? "Symbol" : "Intersil"));
+ /*
+ * The primary firmware is only valid on Prism based chipsets
+ * (INTERSIL or SYMBOL).
+ */
+ if (sc->sc_firmware_type != WI_LUCENT)
+ printf("Primary %u.%02u.%02u, ", sc->sc_pri_firmware_ver / 10000,
+ (sc->sc_pri_firmware_ver % 10000) / 100,
+ sc->sc_pri_firmware_ver % 100);
+ printf("Station %u.%02u.%02u\n",
+ sc->sc_sta_firmware_ver / 10000, (sc->sc_sta_firmware_ver % 10000) / 100,
+ sc->sc_sta_firmware_ver % 100);
return;
}
@@ -847,8 +904,17 @@ wi_reset(sc)
{
#define WI_INIT_TRIES 5
int i;
+ int tries;
- for (i = 0; i < WI_INIT_TRIES; i++) {
+ /* Symbol firmware cannot be initialized more than once */
+ if (sc->sc_firmware_type == WI_SYMBOL && sc->sc_enabled)
+ return;
+ if (sc->sc_firmware_type == WI_SYMBOL)
+ tries = 1;
+ else
+ tries = WI_INIT_TRIES;
+
+ for (i = 0; i < tries; i++) {
if (wi_cmd(sc, WI_CMD_INI, 0, 0, 0) == 0)
break;
DELAY(WI_DELAY * 1000);
@@ -862,6 +928,8 @@ wi_reset(sc)
/* Calibrate timer. */
WI_SETVAL(WI_RID_TICK_TIME, 8);
+ sc->sc_enabled = 1;
+
return;
}
@@ -878,7 +946,7 @@ wi_read_record(sc, ltv)
struct wi_ltv_gen *oltv, p2ltv;
oltv = ltv;
- if (sc->wi_prism2) {
+ if (sc->sc_firmware_type != WI_LUCENT) {
switch (ltv->wi_type) {
case WI_RID_ENCRYPTION:
p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
@@ -921,7 +989,7 @@ wi_read_record(sc, ltv)
for (i = 0; i < ltv->wi_len - 1; i++)
ptr[i] = CSR_READ_2(sc, WI_DATA1);
- if (sc->wi_prism2) {
+ if (sc->sc_firmware_type != WI_LUCENT) {
switch (oltv->wi_type) {
case WI_RID_TX_RATE:
case WI_RID_CUR_TX_RATE:
@@ -972,7 +1040,7 @@ wi_write_record(sc, ltv)
int i;
struct wi_ltv_gen p2ltv;
- if (sc->wi_prism2) {
+ if (sc->sc_firmware_type != WI_LUCENT) {
switch (ltv->wi_type) {
case WI_RID_TX_RATE:
p2ltv.wi_type = WI_RID_TX_RATE;
@@ -1437,8 +1505,9 @@ wi_ioctl(ifp, command, data)
wreq.wi_val[0] = sc->wi_procframe;
} else if (wreq.wi_type == WI_RID_PRISM2) {
wreq.wi_len = 2;
- wreq.wi_val[0] = sc->wi_prism2;
- } else if (wreq.wi_type == WI_RID_SCAN_RES && !sc->wi_prism2) {
+ wreq.wi_val[0] = sc->sc_firmware_type != WI_LUCENT;
+ } else if (wreq.wi_type == WI_RID_SCAN_RES &&
+ sc->sc_firmware_type == WI_LUCENT) {
memcpy((char *)wreq.wi_val, (char *)sc->wi_scanbuf,
sc->wi_scanbuf_len * 2);
wreq.wi_len = sc->wi_scanbuf_len;
@@ -1471,7 +1540,8 @@ wi_ioctl(ifp, command, data)
* interrupt handler. otherwise the scan request can be
* directly handled by a prism2 card's rid interface.
*/
- } else if (wreq.wi_type == WI_RID_SCAN_REQ && !sc->wi_prism2) {
+ } else if (wreq.wi_type == WI_RID_SCAN_REQ &&
+ sc->sc_firmware_type == WI_LUCENT) {
wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0);
} else {
error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
@@ -1483,7 +1553,8 @@ wi_ioctl(ifp, command, data)
error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
if (error)
break;
- if (!(ifp->if_flags & IFF_RUNNING) || !sc->wi_prism2) {
+ if (!(ifp->if_flags & IFF_RUNNING) ||
+ sc->sc_firmware_type == WI_LUCENT) {
error = EIO;
break;
}
@@ -1780,18 +1851,19 @@ wi_init(xsc)
sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1;
sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS;
wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys);
- if (sc->wi_prism2 && sc->wi_use_wep) {
+ if (sc->sc_firmware_type != WI_LUCENT && sc->wi_use_wep) {
/*
* ONLY HWB3163 EVAL-CARD Firmware version
- * less than 0.8 variant3
+ * less than 0.8 variant2
*
* If promiscuous mode disable, Prism2 chip
* does not work with WEP .
* It is under investigation for details.
* (ichiro@netbsd.org)
*/
- if (sc->wi_firmware_ver < 83 ) {
- /* firm ver < 0.8 variant 3 */
+ if (sc->sc_firmware_type == WI_INTERSIL &&
+ sc->sc_sta_firmware_ver < 802 ) {
+ /* firm ver < 0.8 variant 2 */
WI_SETVAL(WI_RID_PROMISC, 1);
}
WI_SETVAL(WI_RID_AUTH_CNTL, sc->wi_authtype);
diff --git a/sys/dev/wi/if_wi_pci.c b/sys/dev/wi/if_wi_pci.c
index e9c1c9f..9adc8ce 100644
--- a/sys/dev/wi/if_wi_pci.c
+++ b/sys/dev/wi/if_wi_pci.c
@@ -115,7 +115,6 @@ wi_pci_probe(dev)
for(i=0; pci_ids[i].vendor != 0; i++) {
if ((pci_get_vendor(dev) == pci_ids[i].vendor) &&
(pci_get_device(dev) == pci_ids[i].device)) {
- sc->wi_prism2 = 1;
sc->wi_bus_type = pci_ids[i].bus_type;
device_set_desc(dev, pci_ids[i].desc);
return (0);
diff --git a/sys/dev/wi/if_wireg.h b/sys/dev/wi/if_wireg.h
index bf28e64..7ad5cf1 100644
--- a/sys/dev/wi/if_wireg.h
+++ b/sys/dev/wi/if_wireg.h
@@ -370,22 +370,30 @@ struct wi_ltv_ver {
u_int16_t wi_len;
u_int16_t wi_type;
u_int16_t wi_ver[4];
-#define WI_NIC_LUCENT 0x0001 /* Emperically derived */
+#define WI_NIC_LUCENT 0x0001 /* Emperically derived */
#define WI_NIC_LUCENT_ALT 0x0005 /* Emperically derived */
-#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_EVB2_SST 0x8009
-#define WI_NIC_3842 0x800A /* 3482 Evaluation Board */
-#define WI_NIC_PRISM2_5 0x800C
-#define WI_NIC_3874A 0x8013 /* Prism2.5 Mini-PCI */
-#define WI_NIC_37300P 0x801a
-#define WI_NIC_P3_SST 0x801B /* Prism3 PCMCIA */
-#define WI_NIC_P3_PCI 0x8022 /* Prism3 Mini-PCI */
+#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_EVB2_SST 0x8009
+#define WI_NIC_3842_EVA 0x800A /* 3842 Evaluation Board */
+#define WI_NIC_3842_PCMCIA_AMD 0x800B /* Prism2.5 PCMCIA */
+#define WI_NIC_3842_PCMCIA_SST 0x800C
+#define WI_NIC_3842_PCMCIA_ATM 0x800D
+#define WI_NIC_3842_MINI_AMD 0x8012 /* Prism2.5 Mini-PCI */
+#define WI_NIC_3842_MINI_SST 0x8013
+#define WI_NIC_3842_MINI_ATM 0x8014
+#define WI_NIC_3842_PCI_AMD 0x8016 /* Prism2.5 PCI-bridge */
+#define WI_NIC_3842_PCI_SST 0x8017
+#define WI_NIC_3842_PCI_ATM 0x8018
+#define WI_NIC_P3_PCMCIA_AMD 0x801A /* Prism3 PCMCIA */
+#define WI_NIC_P3_PCMCIA_SST 0x801B
+#define WI_NIC_P3_MINI_AMD 0x8021 /* Prism3 Mini-PCI */
+#define WI_NIC_P3_MINI_SST 0x8022
};
/*
diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h
index 655b623..876c613 100644
--- a/sys/dev/wi/if_wivar.h
+++ b/sys/dev/wi/if_wivar.h
@@ -111,7 +111,14 @@ struct wi_softc {
bus_space_handle_t wi_bmemhandle;
bus_space_tag_t wi_bmemtag;
void * wi_intrhand;
- int wi_io_addr;
+ int sc_firmware_type;
+#define WI_LUCENT 0
+#define WI_INTERSIL 1
+#define WI_SYMBOL 2
+ int sc_pri_firmware_ver; /* Primary firmware */
+ int sc_sta_firmware_ver; /* Station firmware */
+ int sc_enabled;
+ int wi_io_addr;
int wi_tx_data_id;
int wi_tx_mgmt_id;
int wi_gone;
@@ -149,8 +156,6 @@ struct wi_softc {
#endif
struct callout_handle wi_stat_ch;
struct mtx wi_mtx;
- int wi_prism2;
- int wi_firmware_ver;
int wi_nic_type;
int wi_bus_type; /* Bus attachment type */
struct {
OpenPOWER on IntegriCloud