diff options
author | Marcus Glocker <mglocker@cvs.openbsd.org> | 2007-05-25 21:32:03 +0000 |
---|---|---|
committer | Marcus Glocker <mglocker@cvs.openbsd.org> | 2007-05-25 21:32:03 +0000 |
commit | bb249d4f11269fa18c7a9bb75390befef5d66e60 (patch) | |
tree | 71154290c23b403725fb14d146175dd840a84dfe /sys | |
parent | 4b5549eb7177dfc955b9247f9190ad9252c8039c (diff) |
Make FW commands save in the way that requests/responses must be done
serialized. Establish initial device up/down dance.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pcmcia/if_malo.c | 95 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_maloreg.h | 3 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_malovar.h | 17 |
3 files changed, 89 insertions, 26 deletions
diff --git a/sys/dev/pcmcia/if_malo.c b/sys/dev/pcmcia/if_malo.c index 36d63de7276..cd082007e4a 100644 --- a/sys/dev/pcmcia/if_malo.c +++ b/sys/dev/pcmcia/if_malo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_malo.c,v 1.2 2007/05/25 18:31:01 mglocker Exp $ */ +/* $OpenBSD: if_malo.c,v 1.3 2007/05/25 21:32:02 mglocker Exp $ */ /* * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org> @@ -66,13 +66,14 @@ int cmalo_fw_load_helper(struct malo_softc *); int cmalo_fw_load_main(struct malo_softc *); int cmalo_init(struct ifnet *); void cmalo_stop(struct malo_softc *); -int cmalo_detach(void *); +void cmalo_detach(void *); int cmalo_intr(void *); void cmalo_intr_mask(struct malo_softc *sc, int); void cmalo_hexdump(void *, int); int cmalo_cmd_get_hwspec(struct malo_softc *); int cmalo_cmd_rsp_hwspec(struct malo_softc *); +int cmalo_cmd_set_reset(struct malo_softc *); int cmalo_cmd_response(struct malo_softc *); /* @@ -173,10 +174,8 @@ malo_pcmcia_detach(struct device *dev, int flags) { struct malo_pcmcia_softc *psc = (struct malo_pcmcia_softc *)dev; struct malo_softc *sc = &psc->sc_malo; - int error; - if ((error = cmalo_detach(sc))) - return (error); + cmalo_detach(sc); pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window); pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh); @@ -233,16 +232,16 @@ cmalo_attach(void *arg) return; if (cmalo_fw_load_main(sc) != 0) return; + sc->sc_flags |= MALO_FW_LOADED; /* enable interrupts */ cmalo_intr_mask(sc, 1); /* allocate command buffer */ - sc->sc_cmd = malloc(CMD_BUFFER_SIZE, M_USBDEV, M_WAITOK); + sc->sc_cmd = malloc(MALO_CMD_BUFFER_SIZE, M_USBDEV, M_WAITOK); /* get hardware specs */ cmalo_cmd_get_hwspec(sc); - delay(1000); /* XXX */ /* setup interface */ ifp->if_softc = sc; @@ -349,8 +348,8 @@ cmalo_fw_load_helper(struct malo_softc *sc) /* download the helper firmware */ for (offset = 0; offset < usize; offset += bsize) { - if (usize - offset >= FW_HELPER_BSIZE) - bsize = FW_HELPER_BSIZE; + if (usize - offset >= MALO_FW_HELPER_BSIZE) + bsize = MALO_FW_HELPER_BSIZE; else bsize = usize - offset; @@ -406,7 +405,7 @@ cmalo_fw_load_main(struct malo_softc *sc) /* verify if the helper firmware has been loaded correctly */ for (i = 0; i < 10; i++) { - if (MALO_READ_1(sc, MALO_REG_RBAL) == FW_HELPER_OK) + if (MALO_READ_1(sc, MALO_REG_RBAL) == MALO_FW_HELPER_LOADED) break; delay(1000); } @@ -426,7 +425,7 @@ cmalo_fw_load_main(struct malo_softc *sc) * block until we receive a good integer again, or give up. */ if (val16 & 0x0001) { - if (retry > FW_MAIN_MAX_RETRY) { + if (retry > MALO_FW_MAIN_MAXRETRY) { printf("%s: main FW download failed!\n", sc->sc_dev.dv_xname); free(ucode, M_DEVBUF); @@ -485,7 +484,18 @@ cmalo_fw_load_main(struct malo_softc *sc) int cmalo_init(struct ifnet *ifp) { - //struct malo_softc *sc = ifp->if_softc; + struct malo_softc *sc = ifp->if_softc; + + /* reload the firmware if necessary */ + if (!(sc->sc_flags & MALO_FW_LOADED)) { + if (cmalo_fw_load_helper(sc) != 0) + return (EIO); + if (cmalo_fw_load_main(sc) != 0) + return (EIO); + } + + /* device up */ + ifp->if_flags |= IFF_RUNNING; return (0); } @@ -493,10 +503,20 @@ cmalo_init(struct ifnet *ifp) void cmalo_stop(struct malo_softc *sc) { + struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = &ic->ic_if; + + DPRINTF(1, "%s: device down\n", sc->sc_dev.dv_xname); + + /* power cycle device */ + cmalo_cmd_set_reset(sc); + sc->sc_flags &= ~MALO_FW_LOADED; + /* device down */ + ifp->if_flags &= ~IFF_RUNNING; } -int +void cmalo_detach(void *arg) { struct malo_softc *sc = arg; @@ -509,8 +529,6 @@ cmalo_detach(void *arg) /* detach inferface */ ieee80211_ifdetach(ifp); if_detach(ifp); - - return (0); } int @@ -535,7 +553,7 @@ cmalo_intr(void *arg) if (intr & MALO_VAL_HOST_INTR_CMD) { /* command response */ - cmalo_cmd_response(sc); + sc->sc_cmd_running = 0; } /* acknowledge interrupt */ @@ -588,8 +606,9 @@ cmalo_cmd_get_hwspec(struct malo_softc *sc) { struct malo_cmd_header *hdr = sc->sc_cmd; struct malo_cmd_body_spec *body; + int i; - bzero(sc->sc_cmd, CMD_BUFFER_SIZE); + bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE); hdr->cmd = htole16(MALO_VAL_CMD_HWSPEC); hdr->size = htole16(sizeof(*hdr) + sizeof(*body)); @@ -608,6 +627,22 @@ cmalo_cmd_get_hwspec(struct malo_softc *sc) MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_DNLD_OVER); MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, MALO_VAL_DNLD_OVER); + /* wait for the command response */ + sc->sc_cmd_running = 1; + for (i = 0; i < 50; i++) { + if (sc->sc_cmd_running == 0) + break; + delay(1000); + } + if (i == 50) { + printf("%s: timeout while waiting for cmd response!\n", + sc->sc_dev.dv_xname); + return (EIO); + } + + /* process command repsonse */ + cmalo_cmd_response(sc); + return (0); } @@ -629,12 +664,33 @@ cmalo_cmd_rsp_hwspec(struct malo_softc *sc) } int +cmalo_cmd_set_reset(struct malo_softc *sc) +{ + struct malo_cmd_header *hdr = sc->sc_cmd; + + bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE); + + hdr->cmd = htole16(MALO_VAL_CMD_RESET); + hdr->size = htole16(sizeof(*hdr)); + hdr->seqnum = htole16(1); + hdr->result = 0; + + /* send command request */ + MALO_WRITE_2(sc, MALO_REG_CMD_WRITE_LEN, hdr->size); + MALO_WRITE_MULTI_2(sc, MALO_REG_CMD_WRITE, hdr, hdr->size / 2); + MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_DNLD_OVER); + MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, MALO_VAL_DNLD_OVER); + + return (0); +} + +int cmalo_cmd_response(struct malo_softc *sc) { struct malo_cmd_header *hdr = sc->sc_cmd; int len; - bzero(sc->sc_cmd, CMD_BUFFER_SIZE); + bzero(sc->sc_cmd, MALO_CMD_BUFFER_SIZE); /* read the whole command answer */ len = MALO_READ_2(sc, MALO_REG_CMD_READ_LEN); @@ -655,6 +711,9 @@ cmalo_cmd_response(struct malo_softc *sc) case MALO_VAL_CMD_HWSPEC: cmalo_cmd_rsp_hwspec(sc); break; + case MALO_VAL_CMD_RESET: + /* reset will not send back a response */ + break; default: printf("%s: got unknown command response (0x%04x)!\n", sc->sc_dev.dv_xname, hdr->cmd); diff --git a/sys/dev/pcmcia/if_maloreg.h b/sys/dev/pcmcia/if_maloreg.h index b5202ad4563..cac29f58c59 100644 --- a/sys/dev/pcmcia/if_maloreg.h +++ b/sys/dev/pcmcia/if_maloreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_maloreg.h,v 1.1 2007/05/25 05:33:51 mglocker Exp $ */ +/* $OpenBSD: if_maloreg.h,v 1.2 2007/05/25 21:32:02 mglocker Exp $ */ /* * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org> @@ -42,3 +42,4 @@ /* FW commands */ #define MALO_VAL_CMD_RESP 0x8000 #define MALO_VAL_CMD_HWSPEC 0x0003 +#define MALO_VAL_CMD_RESET 0x0005 diff --git a/sys/dev/pcmcia/if_malovar.h b/sys/dev/pcmcia/if_malovar.h index 5e79ea41483..6dbcacbcf89 100644 --- a/sys/dev/pcmcia/if_malovar.h +++ b/sys/dev/pcmcia/if_malovar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_malovar.h,v 1.1 2007/05/25 05:33:51 mglocker Exp $ */ +/* $OpenBSD: if_malovar.h,v 1.2 2007/05/25 21:32:02 mglocker Exp $ */ /* * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org> @@ -33,10 +33,13 @@ (size)) /* miscellaneous */ -#define FW_HELPER_BSIZE 256 /* helper FW block size */ -#define FW_HELPER_OK 0x10 /* helper FW loaded */ -#define FW_MAIN_MAX_RETRY 20 /* main FW block resend max retry */ -#define CMD_BUFFER_SIZE 256 /* cmd buffer */ +#define MALO_FW_HELPER_BSIZE 256 /* helper FW block size */ +#define MALO_FW_HELPER_LOADED 0x10 /* helper FW loaded */ +#define MALO_FW_MAIN_MAXRETRY 20 /* main FW block resend max retry */ +#define MALO_CMD_BUFFER_SIZE 256 /* cmd buffer */ + +/* device flags */ +#define MALO_FW_LOADED (1 << 0) /* FW command header */ struct malo_cmd_header { @@ -64,11 +67,11 @@ struct malo_cmd_body_spec { struct malo_softc { struct device sc_dev; - struct ieee80211com sc_ic; - bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; + int sc_flags; void *sc_cmd; + uint8_t sc_cmd_running; }; |