summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2015-06-15 07:50:45 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2015-06-15 07:50:45 +0000
commita18d9a0dfad67f8531d8c3d506873e142e19a637 (patch)
treebeab8bc43d42fe4bb83e5e94e34f865ce4aba5b4 /sys
parent6453c872ec55a2674e27f9f1ea1bcdc92c9edca5 (diff)
Make the wifi LED work with iwm(4).
The bad news: Many laptops sold with iwm(4) cards don't have a wifi LED :-( The good news: Laptops with LEDs and no wifi device white-list in BIOS actually exist! Tested in one such machine. ok kettenis@ deraadt@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_iwm.c69
-rw-r--r--sys/dev/pci/if_iwmvar.h3
2 files changed, 69 insertions, 3 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c
index f129041ebdf..d223f8be584 100644
--- a/sys/dev/pci/if_iwm.c
+++ b/sys/dev/pci/if_iwm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwm.c,v 1.43 2015/06/12 13:11:27 stsp Exp $ */
+/* $OpenBSD: if_iwm.c,v 1.44 2015/06/15 07:50:44 stsp Exp $ */
/*
* Copyright (c) 2014 genua mbh <info@genua.de>
@@ -347,6 +347,12 @@ void iwm_update_sched(struct iwm_softc *, int, int, uint8_t, uint16_t);
const struct iwm_rate *iwm_tx_fill_cmd(struct iwm_softc *, struct iwm_node *,
struct ieee80211_frame *, struct iwm_tx_cmd *);
int iwm_tx(struct iwm_softc *, struct mbuf *, struct ieee80211_node *, int);
+void iwm_mvm_led_enable(struct iwm_softc *);
+void iwm_mvm_led_disable(struct iwm_softc *);
+int iwm_mvm_led_is_enabled(struct iwm_softc *);
+void iwm_led_blink_timeout(void *);
+void iwm_led_blink_start(struct iwm_softc *);
+void iwm_led_blink_stop(struct iwm_softc *);
int iwm_mvm_beacon_filter_send_cmd(struct iwm_softc *,
struct iwm_beacon_filter_cmd *);
void iwm_mvm_beacon_filter_set_cqm_params(struct iwm_softc *,
@@ -3975,6 +3981,59 @@ iwm_mvm_flush_tx_path(struct iwm_softc *sc, int tfd_msk, int sync)
}
#endif
+/*
+ * BEGIN mvm/led.c
+ */
+
+/* Set led register on */
+void
+iwm_mvm_led_enable(struct iwm_softc *sc)
+{
+ IWM_WRITE(sc, IWM_CSR_LED_REG, IWM_CSR_LED_REG_TURN_ON);
+}
+
+/* Set led register off */
+void
+iwm_mvm_led_disable(struct iwm_softc *sc)
+{
+ IWM_WRITE(sc, IWM_CSR_LED_REG, IWM_CSR_LED_REG_TURN_OFF);
+}
+
+/*
+ * END mvm/led.c
+ */
+
+int
+iwm_mvm_led_is_enabled(struct iwm_softc *sc)
+{
+ return (IWM_READ(sc, IWM_CSR_LED_REG) == IWM_CSR_LED_REG_TURN_ON);
+}
+
+void
+iwm_led_blink_timeout(void *arg)
+{
+ struct iwm_softc *sc = arg;
+
+ if (iwm_mvm_led_is_enabled(sc))
+ iwm_mvm_led_disable(sc);
+ else
+ iwm_mvm_led_enable(sc);
+
+ timeout_add_msec(&sc->sc_led_blink_to, 200);
+}
+
+void
+iwm_led_blink_start(struct iwm_softc *sc)
+{
+ timeout_add(&sc->sc_led_blink_to, 0);
+}
+
+void
+iwm_led_blink_stop(struct iwm_softc *sc)
+{
+ timeout_del(&sc->sc_led_blink_to);
+ iwm_mvm_led_disable(sc);
+}
/*
* BEGIN mvm/power.c
@@ -5328,6 +5387,9 @@ iwm_newstate_cb(void *wk)
DPRINTF(("switching state %d->%d\n", ic->ic_state, nstate));
+ if (ic->ic_state == IEEE80211_S_SCAN && nstate != ic->ic_state)
+ iwm_led_blink_stop(sc);
+
/* disable beacon filtering if we're hopping out of RUN */
if (ic->ic_state == IEEE80211_S_RUN && nstate != ic->ic_state) {
iwm_mvm_disable_beacon_filter(sc, (void *)ic->ic_bss);
@@ -5373,6 +5435,7 @@ iwm_newstate_cb(void *wk)
return;
}
ic->ic_state = nstate;
+ iwm_led_blink_start(sc);
return;
case IEEE80211_S_AUTH:
@@ -5411,7 +5474,7 @@ iwm_newstate_cb(void *wk)
}
timeout_add_msec(&sc->sc_calib_to, 500);
-
+ iwm_mvm_led_enable(sc);
break; }
default:
@@ -5704,6 +5767,7 @@ iwm_stop(struct ifnet *ifp, int disable)
ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
timeout_del(&sc->sc_calib_to);
+ iwm_led_blink_stop(sc);
ifp->if_timer = sc->sc_tx_timer = 0;
iwm_stop_device(sc);
}
@@ -6627,6 +6691,7 @@ iwm_attach(struct device *parent, struct device *self, void *aux)
iwm_radiotap_attach(sc);
#endif
timeout_set(&sc->sc_calib_to, iwm_calib_timeout, sc);
+ timeout_set(&sc->sc_led_blink_to, iwm_led_blink_timeout, sc);
task_set(&sc->init_task, iwm_init_task, sc);
/*
diff --git a/sys/dev/pci/if_iwmvar.h b/sys/dev/pci/if_iwmvar.h
index 5ed81e7d339..d1638c9e55a 100644
--- a/sys/dev/pci/if_iwmvar.h
+++ b/sys/dev/pci/if_iwmvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwmvar.h,v 1.7 2015/03/02 13:51:10 jsg Exp $ */
+/* $OpenBSD: if_iwmvar.h,v 1.8 2015/06/15 07:50:44 stsp Exp $ */
/*
* Copyright (c) 2014 genua mbh <info@genua.de>
@@ -370,6 +370,7 @@ struct iwm_softc {
struct ieee80211_amrr sc_amrr;
struct timeout sc_calib_to;
+ struct timeout sc_led_blink_to;
struct task init_task;