diff options
author | Marcus Glocker <mglocker@cvs.openbsd.org> | 2008-01-18 21:31:17 +0000 |
---|---|---|
committer | Marcus Glocker <mglocker@cvs.openbsd.org> | 2008-01-18 21:31:17 +0000 |
commit | ec7a2579b3c778537432615e59b982165728e8ee (patch) | |
tree | 9b70ac2eb9a47e5606b4161538369ce8807141e0 | |
parent | 2d9f09386705e3ca46a181492d20f11cfba8d2af (diff) |
Add LED support.
-rw-r--r-- | sys/dev/usb/if_upgt.c | 97 | ||||
-rw-r--r-- | sys/dev/usb/if_upgtvar.h | 23 |
2 files changed, 117 insertions, 3 deletions
diff --git a/sys/dev/usb/if_upgt.c b/sys/dev/usb/if_upgt.c index 3bac935452d..a4955d40422 100644 --- a/sys/dev/usb/if_upgt.c +++ b/sys/dev/usb/if_upgt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_upgt.c,v 1.18 2008/01/17 20:46:51 mglocker Exp $ */ +/* $OpenBSD: if_upgt.c,v 1.19 2008/01/18 21:31:16 mglocker Exp $ */ /* * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org> @@ -118,6 +118,8 @@ void upgt_rx_cb(usbd_xfer_handle, usbd_private_handle, usbd_status); void upgt_rx(struct upgt_softc *, uint8_t *, int); int upgt_set_macfilter(struct upgt_softc *, uint8_t state); int upgt_set_channel(struct upgt_softc *, unsigned); +void upgt_set_led(struct upgt_softc *, int); +void upgt_set_led_blink(void *); int upgt_get_stats(struct upgt_softc *); int upgt_alloc_tx(struct upgt_softc *); @@ -246,10 +248,11 @@ upgt_attach(struct device *parent, struct device *self, void *aux) return; } - /* init tasks */ + /* setup tasks and timeouts */ usb_init_task(&sc->sc_task_newstate, upgt_newstate_task, sc); usb_init_task(&sc->sc_task_tx, upgt_tx_task, sc); timeout_set(&sc->scan_to, upgt_next_scan, sc); + timeout_set(&sc->led_to, upgt_set_led_blink, sc); /* * Open TX and RX USB bulk pipes. @@ -457,6 +460,7 @@ upgt_detach(struct device *self, int flags) usb_rem_task(sc->sc_udev, &sc->sc_task_newstate); usb_rem_task(sc->sc_udev, &sc->sc_task_tx); timeout_del(&sc->scan_to); + timeout_del(&sc->led_to); /* free xfers */ upgt_free_tx(sc); @@ -1264,6 +1268,7 @@ upgt_newstate_task(void *arg) /* do not accept any frames if the device is down */ upgt_set_macfilter(sc, IEEE80211_S_INIT); + upgt_set_led(sc, UPGT_LED_OFF); break; case IEEE80211_S_SCAN: DPRINTF(1, "%s: newstate is IEEE80211_S_SCAN\n", @@ -1291,6 +1296,7 @@ upgt_newstate_task(void *arg) ni = ic->ic_bss; upgt_set_macfilter(sc, IEEE80211_S_RUN); + upgt_set_led(sc, UPGT_LED_ON); break; } @@ -1422,6 +1428,8 @@ upgt_tx_task(void *arg) s = splusb(); + upgt_set_led(sc, UPGT_LED_BLINK); + for (i = 0; i < UPGT_TX_COUNT; i++) { struct upgt_data *data_tx = &sc->tx_data[i]; @@ -1872,6 +1880,91 @@ upgt_set_channel(struct upgt_softc *sc, unsigned channel) return (0); } +void +upgt_set_led(struct upgt_softc *sc, int action) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct upgt_data *data_cmd = &sc->cmd_data; + struct upgt_lmac_mem *mem; + struct upgt_lmac_led *led; + struct timeval t; + int len; + + /* + * Transmit the URB containing the CMD data. + */ + bzero(data_cmd->buf, MCLBYTES); + + mem = (struct upgt_lmac_mem *)data_cmd->buf; + mem->addr = htole32(sc->sc_memaddr_frame_start + + UPGT_MEMSIZE_FRAME_HEAD); + + led = (struct upgt_lmac_led *)(mem + 1); + + led->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK; + led->header1.type = UPGT_H1_TYPE_CTRL; + led->header1.len = htole16( + sizeof(struct upgt_lmac_led) - + sizeof(struct upgt_lmac_header)); + + led->header2.reqid = htole32(sc->sc_memaddr_frame_start); + led->header2.type = htole16(UPGT_H2_TYPE_LED); + led->header2.flags = 0; + + switch (action) { + case UPGT_LED_OFF: + led->mode = htole16(UPGT_LED_MODE_SET); + led->action_fix = 0; + led->action_tmp = htole16(UPGT_LED_ACTION_OFF); + led->action_tmp_dur = 0; + break; + case UPGT_LED_ON: + led->mode = htole16(UPGT_LED_MODE_SET); + led->action_fix = 0; + led->action_tmp = htole16(UPGT_LED_ACTION_ON); + led->action_tmp_dur = 0; + break; + case UPGT_LED_BLINK: + if (ic->ic_state != IEEE80211_S_RUN) + return; + if (sc->sc_led_blink) + /* previous blink was not finished */ + return; + led->mode = htole16(UPGT_LED_MODE_SET); + led->action_fix = htole16(UPGT_LED_ACTION_OFF); + led->action_tmp = htole16(UPGT_LED_ACTION_ON); + led->action_tmp_dur = htole16(UPGT_LED_ACTION_TMP_DUR); + /* lock blink */ + sc->sc_led_blink = 1; + t.tv_sec = 0; + t.tv_usec = UPGT_LED_ACTION_TMP_DUR * 1000L; + timeout_add(&sc->led_to, tvtohz(&t)); + break; + default: + return; + } + + len = sizeof(*mem) + sizeof(*led); + + mem->chksum = htole32(upgt_chksum((uint32_t *)led, + len - sizeof(*mem))); + + if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) { + printf("%s: could not transmit led CMD URB!\n", + sc->sc_dev.dv_xname); + } +} + +void +upgt_set_led_blink(void *arg) +{ + struct upgt_softc *sc = arg; + + /* blink finished, we are ready for a next one */ + sc->sc_led_blink = 0; + timeout_del(&sc->led_to); +} + int upgt_get_stats(struct upgt_softc *sc) { diff --git a/sys/dev/usb/if_upgtvar.h b/sys/dev/usb/if_upgtvar.h index d99b64b60c5..8dbdade8dd5 100644 --- a/sys/dev/usb/if_upgtvar.h +++ b/sys/dev/usb/if_upgtvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_upgtvar.h,v 1.8 2008/01/17 20:46:51 mglocker Exp $ */ +/* $OpenBSD: if_upgtvar.h,v 1.9 2008/01/18 21:31:16 mglocker Exp $ */ /* * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org> @@ -70,6 +70,11 @@ struct upgt_tx_radiotap_header { /* device flags */ #define UPGT_DEVICE_ATTACHED (1 << 0) +/* leds */ +#define UPGT_LED_OFF 0 +#define UPGT_LED_ON 1 +#define UPGT_LED_BLINK 2 + /* * USB xfers. */ @@ -219,6 +224,7 @@ struct upgt_lmac_h1 { #define UPGT_H2_TYPE_TX_DONE 0x0008 #define UPGT_H2_TYPE_STATS 0x000a #define UPGT_H2_TYPE_EEPROM 0x000c +#define UPGT_H2_TYPE_LED 0x000d #define UPGT_H2_FLAGS_TX_ACK_NO 0x0101 #define UPGT_H2_FLAGS_TX_ACK_YES 0x0707 struct upgt_lmac_h2 { @@ -304,6 +310,19 @@ struct upgt_lmac_channel { uint32_t pad2; } __packed; +#define UPGT_LED_MODE_SET 0x0003 +#define UPGT_LED_ACTION_OFF 0x0002 +#define UPGT_LED_ACTION_ON 0x0003 +#define UPGT_LED_ACTION_TMP_DUR 100 /* ms */ +struct upgt_lmac_led { + struct upgt_lmac_h1 header1; + struct upgt_lmac_h2 header2; + uint16_t mode; + uint16_t action_fix; + uint16_t action_tmp; + uint16_t action_tmp_dur; +} __packed; + struct upgt_lmac_stats { struct upgt_lmac_h1 header1; struct upgt_lmac_h2 header2; @@ -400,6 +419,8 @@ struct upgt_softc { int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int); struct timeout scan_to; + struct timeout led_to; + int sc_led_blink; unsigned sc_curchan; int sc_flags; |