On Sun, Jun 07, 2015 at 02:23:44PM +0200, Stefan Sperling wrote:
> This diff enables the wifi LED with iwm(4) devices.
>
> Tested using a non-thinkpad netbook with wifi LED. I'm not sure
> if any modern thinkpads even have wifi LEDs these days :-/
>
> Unfortunately, there seems to be know way of controlling blinking
> in hardware so use a timeout instead.
>
> OK?
bump
>
> Index: if_iwm.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
> retrieving revision 1.42
> diff -u -p -r1.42 if_iwm.c
> --- if_iwm.c 30 May 2015 02:49:23 -0000 1.42
> +++ if_iwm.c 7 Jun 2015 12:21:45 -0000
> @@ -347,6 +347,12 @@ void iwm_update_sched(struct iwm_softc *
> 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 *
> }
> #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);
> }
> @@ -6628,6 +6692,7 @@ iwm_attach(struct device *parent, struct
> 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);
>
> /*
> Index: if_iwmvar.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_iwmvar.h,v
> retrieving revision 1.7
> diff -u -p -r1.7 if_iwmvar.h
> --- if_iwmvar.h 2 Mar 2015 13:51:10 -0000 1.7
> +++ if_iwmvar.h 7 Jun 2015 11:19:15 -0000
> @@ -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;
>