diff options
-rw-r--r-- | sys/dev/wi/if_wi.c | 158 | ||||
-rw-r--r-- | sys/dev/wi/if_wi_pci.c | 1 | ||||
-rw-r--r-- | sys/dev/wi/if_wireg.h | 38 | ||||
-rw-r--r-- | sys/dev/wi/if_wivar.h | 11 |
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 { |