summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2003-10-26 15:34:17 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2003-10-26 15:34:17 +0000
commit43782ab58acc9f9d055d1fc33d7069fe85857d90 (patch)
tree75ff040ecf49a4340cd89b95a47ff537576652da /sys/dev/ic
parentb62dde670d7c7927ce0448b2c885cb9fdd70e437 (diff)
Driver for PRISM 2.5/3 based (wifi) USB adapters. This is a work in progress,
it does not yet handle bulk data copies or hostap mode. Only one model currently supported, however driver may support other PRISM based adapters. ok millert@ fgsch@
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/if_wi.c128
-rw-r--r--sys/dev/ic/if_wi_ieee.h8
-rw-r--r--sys/dev/ic/if_wivar.h43
3 files changed, 136 insertions, 43 deletions
diff --git a/sys/dev/ic/if_wi.c b/sys/dev/ic/if_wi.c
index f1ece1d0899..260c8d9e8a6 100644
--- a/sys/dev/ic/if_wi.c
+++ b/sys/dev/ic/if_wi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wi.c,v 1.100 2003/10/21 18:58:49 jmc Exp $ */
+/* $OpenBSD: if_wi.c,v 1.101 2003/10/26 15:34:15 drahn Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -126,7 +126,7 @@ u_int32_t widebug = WIDEBUG;
#if !defined(lint) && !defined(__OpenBSD__)
static const char rcsid[] =
- "$OpenBSD: if_wi.c,v 1.100 2003/10/21 18:58:49 jmc Exp $";
+ "$OpenBSD: if_wi.c,v 1.101 2003/10/26 15:34:15 drahn Exp $";
#endif /* lint */
#ifdef foo
@@ -135,6 +135,7 @@ static u_int8_t wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 };
STATIC void wi_reset(struct wi_softc *);
STATIC int wi_ioctl(struct ifnet *, u_long, caddr_t);
+STATIC void wi_init_io(struct wi_softc *);
STATIC void wi_start(struct ifnet *);
STATIC void wi_watchdog(struct ifnet *);
STATIC void wi_shutdown(void *);
@@ -143,15 +144,15 @@ STATIC void wi_txeof(struct wi_softc *, int);
STATIC void wi_update_stats(struct wi_softc *);
STATIC void wi_setmulti(struct wi_softc *);
-STATIC int wi_cmd(struct wi_softc *, int, int, int, int);
-STATIC int wi_read_record(struct wi_softc *, struct wi_ltv_gen *);
-STATIC int wi_write_record(struct wi_softc *, struct wi_ltv_gen *);
-STATIC int wi_read_data(struct wi_softc *, int,
+STATIC int wi_cmd_io(struct wi_softc *, int, int, int, int);
+STATIC int wi_read_record_io(struct wi_softc *, struct wi_ltv_gen *);
+STATIC int wi_write_record_io(struct wi_softc *, struct wi_ltv_gen *);
+STATIC int wi_read_data_io(struct wi_softc *, int,
int, caddr_t, int);
-STATIC int wi_write_data(struct wi_softc *, int,
+STATIC int wi_write_data_io(struct wi_softc *, int,
int, caddr_t, int);
STATIC int wi_seek(struct wi_softc *, int, int, int);
-STATIC int wi_alloc_nicmem(struct wi_softc *, int, int *);
+
STATIC void wi_inquire(void *);
STATIC int wi_setdef(struct wi_softc *, struct wi_req *);
STATIC void wi_get_id(struct wi_softc *);
@@ -172,6 +173,11 @@ STATIC int wi_set_debug(struct wi_softc *, struct wi_req *);
STATIC void wi_do_hostencrypt(struct wi_softc *, caddr_t, int);
STATIC int wi_do_hostdecrypt(struct wi_softc *, caddr_t, int);
+STATIC int wi_alloc_nicmem_io(struct wi_softc *, int, int *);
+STATIC int wi_get_fid_io(struct wi_softc *sc, int fid);
+STATIC void wi_intr_enable(struct wi_softc *sc, int mode);
+STATIC void wi_intr_ack(struct wi_softc *sc, int mode);
+
/* Autoconfig definition of driver back-end */
struct cfdriver wi_cd = {
NULL, "wi", DV_IFNET
@@ -181,15 +187,32 @@ const struct wi_card_ident wi_card_ident[] = {
WI_CARD_IDS
};
+struct wi_funcs wi_func_io = {
+ wi_cmd_io,
+ wi_read_record_io,
+ wi_write_record_io,
+ wi_alloc_nicmem_io,
+ wi_read_data_io,
+ wi_write_data_io,
+ wi_get_fid_io,
+ wi_init_io,
+
+ wi_start,
+ wi_ioctl,
+ wi_watchdog,
+ wi_inquire,
+};
+
int
-wi_attach(sc)
- struct wi_softc *sc;
+wi_attach(struct wi_softc *sc, struct wi_funcs *funcs)
{
struct wi_ltv_macaddr mac;
struct wi_ltv_gen gen;
struct ifnet *ifp;
int error;
+ sc->sc_funcs = funcs;
+
wi_reset(sc);
/* Read the station address. */
@@ -210,9 +233,9 @@ wi_attach(sc)
bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_ioctl = wi_ioctl;
- ifp->if_start = wi_start;
- ifp->if_watchdog = wi_watchdog;
+ ifp->if_ioctl = funcs->f_ioctl;
+ ifp->if_start = funcs->f_start;
+ ifp->if_watchdog = funcs->f_watchdog;
ifp->if_baudrate = 10000000;
IFQ_SET_READY(&ifp->if_snd);
@@ -292,7 +315,7 @@ wi_attach(sc)
gen.wi_len = 2;
if (wi_read_record(sc, &gen) == 0 && gen.wi_val != htole16(0))
sc->wi_flags |= WI_FLAGS_HAS_WEP;
- timeout_set(&sc->sc_timo, wi_inquire, sc);
+ timeout_set(&sc->sc_timo, funcs->f_inquire, sc);
bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
@@ -401,6 +424,20 @@ wi_attach(sc)
return (0);
}
+STATIC void
+wi_intr_enable(struct wi_softc *sc, int mode)
+{
+ if (!(sc->wi_flags & WI_FLAGS_BUS_USB))
+ CSR_WRITE_2(sc, WI_INT_EN, mode);
+}
+
+STATIC void
+wi_intr_ack(struct wi_softc *sc, int mode)
+{
+ if (!(sc->wi_flags & WI_FLAGS_BUS_USB))
+ CSR_WRITE_2(sc, WI_EVENT_ACK, mode);
+}
+
int
wi_intr(vsc)
void *vsc;
@@ -466,7 +503,14 @@ wi_intr(vsc)
return (1);
}
-STATIC void
+STATIC int
+wi_get_fid_io(struct wi_softc *sc, int fid)
+{
+ return CSR_READ_2(sc, fid);
+}
+
+
+void
wi_rxeof(sc)
struct wi_softc *sc;
{
@@ -480,7 +524,7 @@ wi_rxeof(sc)
ifp = &sc->sc_arpcom.ac_if;
- id = CSR_READ_2(sc, WI_RX_FID);
+ id = wi_get_fid(sc, WI_RX_FID);
if (sc->wi_procframe || sc->wi_debug.wi_monitor) {
struct wi_frame *rx_frame;
@@ -774,7 +818,7 @@ wi_rxeof(sc)
return;
}
-STATIC void
+void
wi_txeof(sc, status)
struct wi_softc *sc;
int status;
@@ -834,7 +878,7 @@ wi_update_stats(sc)
ifp = &sc->sc_arpcom.ac_if;
- id = CSR_READ_2(sc, WI_INFO_FID);
+ id = wi_get_fid(sc, WI_INFO_FID);
wi_read_data(sc, id, 0, (char *)&gen, 4);
@@ -853,7 +897,11 @@ wi_update_stats(sc)
ptr = (u_int32_t *)&sc->wi_stats;
for (i = 0; i < len; i++) {
- t = CSR_READ_2(sc, WI_DATA1);
+ if (sc->wi_flags & WI_FLAGS_BUS_USB) {
+ wi_read_data(sc, id, 4 + i*2, (char *)&t, 2);
+ t = letoh16(t);
+ } else
+ t = CSR_READ_2(sc, WI_DATA1);
#ifdef WI_HERMES_STATS_WAR
if (t > 0xF000)
t = ~t & 0xFFFF;
@@ -869,7 +917,7 @@ wi_update_stats(sc)
}
STATIC int
-wi_cmd(sc, cmd, val0, val1, val2)
+wi_cmd_io(sc, cmd, val0, val1, val2)
struct wi_softc *sc;
int cmd;
int val0;
@@ -932,8 +980,8 @@ wi_reset(sc)
else
sc->wi_flags |= WI_FLAGS_INITIALIZED;
- CSR_WRITE_2(sc, WI_INT_EN, 0);
- CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
+ wi_intr_enable(sc, 0);
+ wi_intr_ack(sc, 0xffff);
/* Calibrate timer. */
WI_SETVAL(WI_RID_TICK_TIME, 8);
@@ -973,7 +1021,7 @@ wi_cor_reset(sc)
* Read an LTV record from the NIC.
*/
STATIC int
-wi_read_record(sc, ltv)
+wi_read_record_io(sc, ltv)
struct wi_softc *sc;
struct wi_ltv_gen *ltv;
{
@@ -1075,7 +1123,7 @@ wi_read_record(sc, ltv)
* Same as read, except we inject data instead of reading it.
*/
STATIC int
-wi_write_record(sc, ltv)
+wi_write_record_io(sc, ltv)
struct wi_softc *sc;
struct wi_ltv_gen *ltv;
{
@@ -1230,7 +1278,7 @@ wi_seek(sc, id, off, chan)
}
STATIC int
-wi_read_data(sc, id, off, buf, len)
+wi_read_data_io(sc, id, off, buf, len)
struct wi_softc *sc;
int id, off;
caddr_t buf;
@@ -1260,7 +1308,7 @@ wi_read_data(sc, id, off, buf, len)
* we expect them, we preform the transfer over again.
*/
STATIC int
-wi_write_data(sc, id, off, buf, len)
+wi_write_data_io(sc, id, off, buf, len)
struct wi_softc *sc;
int id, off;
caddr_t buf;
@@ -1298,7 +1346,7 @@ again:
* it out.
*/
STATIC int
-wi_alloc_nicmem(sc, len, id)
+wi_alloc_nicmem_io(sc, len, id)
struct wi_softc *sc;
int len;
int *id;
@@ -1792,7 +1840,7 @@ wi_ioctl(ifp, command, data)
}
STATIC void
-wi_init(sc)
+wi_init_io(sc)
struct wi_softc *sc;
{
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
@@ -1922,7 +1970,7 @@ wi_init(sc)
sc->wi_tx_mgmt_id = id;
/* enable interrupts */
- CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
+ wi_intr_enable(sc, WI_INTRS);
wihap_init(sc);
@@ -2116,7 +2164,7 @@ wi_do_hostdecrypt(struct wi_softc *sc, caddr_t buf, int len)
return 0;
}
-STATIC void
+void
wi_start(ifp)
struct ifnet *ifp;
{
@@ -2258,9 +2306,6 @@ nextpkt:
m_freem(m0);
- if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id, 0, 0))
- printf(WI_PRT_FMT ": wi_start: xmit failed\n", WI_PRT_ARG(sc));
-
ifp->if_flags |= IFF_OACTIVE;
/*
@@ -2268,6 +2313,9 @@ nextpkt:
*/
ifp->if_timer = 5;
+ if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id, 0, 0))
+ printf(WI_PRT_FMT ": wi_start: xmit failed\n", WI_PRT_ARG(sc));
+
return;
}
@@ -2312,7 +2360,7 @@ wi_mgmt_xmit(sc, data, len)
return(0);
}
-STATIC void
+void
wi_stop(sc)
struct wi_softc *sc;
{
@@ -2329,7 +2377,7 @@ wi_stop(sc)
ifp = &sc->sc_arpcom.ac_if;
- CSR_WRITE_2(sc, WI_INT_EN, 0);
+ wi_intr_enable(sc, 0);
wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0, 0, 0);
ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
@@ -2338,7 +2386,8 @@ wi_stop(sc)
return;
}
-STATIC void
+
+void
wi_watchdog(ifp)
struct ifnet *ifp;
{
@@ -2366,9 +2415,10 @@ wi_detach(sc)
if (ifp->if_flags & IFF_RUNNING)
wi_stop(sc);
- sc->wi_flags &= ~WI_FLAGS_ATTACHED;
- shutdownhook_disestablish(sc->sc_sdhook);
-
+ if (sc->wi_flags & WI_FLAGS_ATTACHED) {
+ sc->wi_flags &= ~WI_FLAGS_ATTACHED;
+ shutdownhook_disestablish(sc->sc_sdhook);
+ }
}
STATIC void
diff --git a/sys/dev/ic/if_wi_ieee.h b/sys/dev/ic/if_wi_ieee.h
index e134293c4a8..9a888d5b486 100644
--- a/sys/dev/ic/if_wi_ieee.h
+++ b/sys/dev/ic/if_wi_ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wi_ieee.h,v 1.18 2003/10/21 18:58:49 jmc Exp $ */
+/* $OpenBSD: if_wi_ieee.h,v 1.19 2003/10/26 15:34:15 drahn Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -797,6 +797,8 @@ struct wi_scan_p2_hdr {
#define WI_NIC_P3_MINI_ATL 0x8023
#define WI_NIC_P3_MINI_ATS 0x8024
+#define WI_NIC_P3_USB_NETGEAR 0x8026 /* Prism3 USB */
+
struct wi_card_ident {
const u_int16_t card_id;
const char *card_name;
@@ -933,6 +935,10 @@ struct wi_card_ident {
"PRISM3 ISL37300P(PCI)", \
WI_INTERSIL \
}, { \
+ WI_NIC_P3_USB_NETGEAR, \
+ "PRISM3 (USB)", \
+ WI_INTERSIL \
+ }, { \
0, \
NULL, \
WI_NOTYPE \
diff --git a/sys/dev/ic/if_wivar.h b/sys/dev/ic/if_wivar.h
index f4c2edd94c2..8710a630c79 100644
--- a/sys/dev/ic/if_wivar.h
+++ b/sys/dev/ic/if_wivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wivar.h,v 1.21 2003/09/06 20:53:57 drahn Exp $ */
+/* $OpenBSD: if_wivar.h,v 1.22 2003/10/26 15:34:15 drahn Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -109,7 +109,18 @@ struct wi_softc {
u_int16_t wi_confbits_param0;
} wi_debug;
void *sc_sdhook;
+ struct wi_usb_softc *wi_usb_cdata;
+
+ struct wi_funcs *sc_funcs;
};
+#define wi_cmd sc->sc_funcs->f_cmd
+#define wi_read_record sc->sc_funcs->f_read_record
+#define wi_write_record sc->sc_funcs->f_write_record
+#define wi_alloc_nicmem sc->sc_funcs->f_alloc_nicmem
+#define wi_read_data sc->sc_funcs->f_read_data
+#define wi_write_data sc->sc_funcs->f_write_data
+#define wi_get_fid sc->sc_funcs->f_get_fid
+#define wi_init sc->sc_funcs->f_init
/* Values for wi_flags. */
#define WI_FLAGS_ATTACHED 0x0001
@@ -122,14 +133,40 @@ struct wi_softc {
#define WI_FLAGS_HAS_DIVERSITY 0x0080
#define WI_FLAGS_HAS_HOSTAP 0x0100
#define WI_FLAGS_BUS_PCMCIA 0x0200
+#define WI_FLAGS_BUS_USB 0x0400
#define WI_PRT_FMT "%s"
#define WI_PRT_ARG(sc) (sc)->sc_dev.dv_xname
-int wi_attach(struct wi_softc *);
+struct wi_funcs {
+ int (*f_cmd)(struct wi_softc *sc, int cmd, int val0, int val1,
+ int val2);
+ int (*f_read_record)(struct wi_softc *sc, struct wi_ltv_gen *ltv);
+ int (*f_write_record)(struct wi_softc *sc,
+ struct wi_ltv_gen *ltv);
+ int (*f_alloc_nicmem)(struct wi_softc *sc, int len, int *id);
+ int (*f_read_data)(struct wi_softc *sc, int id, int off,
+ caddr_t buf, int len);
+ int (*f_write_data)(struct wi_softc *sc, int id, int off,
+ caddr_t buf, int len);
+ int (*f_get_fid)(struct wi_softc *sc, int fid);
+ void (*f_init)(struct wi_softc *sc);
+
+ void (*f_start)(struct ifnet *ifp);
+ int (*f_ioctl)(struct ifnet *, u_long, caddr_t);
+ void (*f_watchdog)(struct ifnet *ifp);
+ void (*f_inquire)(void *xsc);
+};
+
+extern struct wi_funcs wi_func_io;
+
+int wi_attach(struct wi_softc *, struct wi_funcs *);
void wi_detach(struct wi_softc *);
int wi_intr(void *);
-void wi_init(struct wi_softc *);
void wi_stop(struct wi_softc *);
void wi_cor_reset(struct wi_softc *);
int wi_mgmt_xmit(struct wi_softc *, caddr_t, int);
+
+void wi_update_stats(struct wi_softc *sc);
+void wi_rxeof(struct wi_softc *sc);
+void wi_txeof(struct wi_softc *sc, int status);