diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_iwm.c | 118 | ||||
-rw-r--r-- | sys/dev/pci/if_iwmvar.h | 6 |
2 files changed, 67 insertions, 57 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c index cfa244ac24c..f4a3dffb84e 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.136 2016/09/21 13:29:11 stsp Exp $ */ +/* $OpenBSD: if_iwm.c,v 1.137 2016/09/21 13:53:18 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh <info@genua.de> @@ -402,10 +402,10 @@ int iwm_config_umac_scan(struct iwm_softc *); int iwm_umac_scan(struct iwm_softc *); void iwm_ack_rates(struct iwm_softc *, struct iwm_node *, int *, int *); void iwm_mac_ctxt_cmd_common(struct iwm_softc *, struct iwm_node *, - struct iwm_mac_ctx_cmd *, uint32_t); + struct iwm_mac_ctx_cmd *, uint32_t, int); void iwm_mac_ctxt_cmd_fill_sta(struct iwm_softc *, struct iwm_node *, struct iwm_mac_data_sta *, int); -int iwm_mac_ctxt_cmd(struct iwm_softc *, struct iwm_node *, uint32_t); +int iwm_mac_ctxt_cmd(struct iwm_softc *, struct iwm_node *, uint32_t, int); int iwm_update_quotas(struct iwm_softc *, struct iwm_node *); int iwm_auth(struct iwm_softc *); int iwm_assoc(struct iwm_softc *); @@ -2432,7 +2432,7 @@ iwm_htprot_task(void *arg) int err; /* This call updates HT protection based on in->in_ni.ni_htop1. */ - err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY); + err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY, 1); if (err) printf("%s: could not change HT protection: error %d\n", DEVNAME(sc), err); @@ -4992,7 +4992,7 @@ iwm_ack_rates(struct iwm_softc *sc, struct iwm_node *in, int *cck_rates, void iwm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in, - struct iwm_mac_ctx_cmd *cmd, uint32_t action) + struct iwm_mac_ctx_cmd *cmd, uint32_t action, int assoc) { #define IWM_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */ struct ieee80211com *ic = &sc->sc_ic; @@ -5005,14 +5005,11 @@ iwm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in, cmd->action = htole32(action); cmd->mac_type = htole32(IWM_FW_MAC_TYPE_BSS_STA); - cmd->tsf_id = htole32(in->in_tsfid); + cmd->tsf_id = htole32(IWM_TSF_ID_A); IEEE80211_ADDR_COPY(cmd->node_addr, ic->ic_myaddr); - if (in->in_assoc) { - IEEE80211_ADDR_COPY(cmd->bssid_addr, ni->ni_bssid); - } else { - IEEE80211_ADDR_COPY(cmd->bssid_addr, etherbroadcastaddr); - } + IEEE80211_ADDR_COPY(cmd->bssid_addr, ni->ni_bssid); + iwm_ack_rates(sc, in, &cck_ack_rates, &ofdm_ack_rates); cmd->cck_rates = htole32(cck_ack_rates); cmd->ofdm_rates = htole32(ofdm_ack_rates); @@ -5067,45 +5064,47 @@ iwm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in, void iwm_mac_ctxt_cmd_fill_sta(struct iwm_softc *sc, struct iwm_node *in, - struct iwm_mac_data_sta *ctxt_sta, int force_assoc_off) + struct iwm_mac_data_sta *sta, int assoc) { struct ieee80211_node *ni = &in->in_ni; - struct ieee80211com *ic = &sc->sc_ic; + uint32_t dtim_off; + uint64_t tsf; - ctxt_sta->is_assoc = htole32(0); - ctxt_sta->bi = htole32(ni->ni_intval); - ctxt_sta->bi_reciprocal = htole32(iwm_reciprocal(ni->ni_intval)); - ctxt_sta->dtim_interval = htole32(ni->ni_intval * ic->ic_dtim_period); - ctxt_sta->dtim_reciprocal = - htole32(iwm_reciprocal(ni->ni_intval * ic->ic_dtim_period)); + dtim_off = ni->ni_dtimcount * ni->ni_intval * IEEE80211_DUR_TU; + memcpy(&tsf, ni->ni_tstamp, sizeof(tsf)); + tsf = letoh64(tsf); - /* 10 = CONN_MAX_LISTEN_INTERVAL */ - ctxt_sta->listen_interval = htole32(10); - ctxt_sta->assoc_id = htole32(ni->ni_associd); + sta->is_assoc = htole32(assoc); + sta->dtim_time = htole32(ni->ni_rstamp + dtim_off); + sta->dtim_tsf = htole64(tsf + dtim_off); + sta->bi = htole32(ni->ni_intval); + sta->bi_reciprocal = htole32(iwm_reciprocal(ni->ni_intval)); + sta->dtim_interval = htole32(ni->ni_intval * ni->ni_dtimperiod); + sta->dtim_reciprocal = htole32(iwm_reciprocal(sta->dtim_interval)); + sta->listen_interval = htole32(10); + sta->assoc_id = htole32(ni->ni_associd); + sta->assoc_beacon_arrive_time = htole32(ni->ni_rstamp); } int -iwm_mac_ctxt_cmd(struct iwm_softc *sc, struct iwm_node *in, uint32_t action) +iwm_mac_ctxt_cmd(struct iwm_softc *sc, struct iwm_node *in, uint32_t action, + int assoc) { + struct ieee80211_node *ni = &in->in_ni; struct iwm_mac_ctx_cmd cmd; memset(&cmd, 0, sizeof(cmd)); - iwm_mac_ctxt_cmd_common(sc, in, &cmd, action); + iwm_mac_ctxt_cmd_common(sc, in, &cmd, action, assoc); /* Allow beacons to pass through as long as we are not associated or we * do not have dtim period information */ - if (!in->in_assoc || !sc->sc_ic.ic_dtim_period) + if (!assoc || !ni->ni_associd || !ni->ni_dtimperiod) cmd.filter_flags |= htole32(IWM_MAC_FILTER_IN_BEACON); else - cmd.filter_flags &= ~htole32(IWM_MAC_FILTER_IN_BEACON); + iwm_mac_ctxt_cmd_fill_sta(sc, in, &cmd.sta, assoc); - /* Fill the data specific for station mode */ - iwm_mac_ctxt_cmd_fill_sta(sc, in, - &cmd.sta, action == IWM_FW_CTXT_ACTION_ADD); - - return iwm_send_cmd_pdu(sc, IWM_MAC_CONTEXT_CMD, 0, sizeof(cmd), - &cmd); + return iwm_send_cmd_pdu(sc, IWM_MAC_CONTEXT_CMD, 0, sizeof(cmd), &cmd); } int @@ -5179,8 +5178,6 @@ iwm_auth(struct iwm_softc *sc) uint32_t duration; int err; - in->in_assoc = 0; - err = iwm_sf_config(sc, IWM_SF_FULL_ON); if (err) return err; @@ -5204,7 +5201,7 @@ iwm_auth(struct iwm_softc *sc) if (err) return err; - err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY); + err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY, 0); if (err) { printf("%s: failed to update MAC\n", DEVNAME(sc)); return err; @@ -5233,14 +5230,6 @@ iwm_assoc(struct iwm_softc *sc) if (err) return err; - in->in_assoc = 1; - - err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY); - if (err) { - printf("%s: failed to update MAC\n", DEVNAME(sc)); - return err; - } - return 0; } @@ -5444,10 +5433,6 @@ iwm_newstate_task(void *psc) /* Reset the device if moving out of AUTH, ASSOC, or RUN. */ /* XXX Is there a way to switch states without a full reset? */ if (ostate > IEEE80211_S_SCAN && nstate < ostate) { - in = (struct iwm_node *)ic->ic_bss; - if (in) - in->in_assoc = 0; - iwm_stop_device(sc); iwm_init_hw(sc); @@ -5501,16 +5486,46 @@ iwm_newstate_task(void *psc) case IEEE80211_S_RUN: in = (struct iwm_node *)ic->ic_bss; - iwm_power_mac_update_mode(sc, in); + + /* We have now been assigned an associd by the AP. */ + err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY, 1); + if (err) { + printf("%s: failed to update MAC\n", DEVNAME(sc)); + return; + } + + err = iwm_power_update_device(sc); + if (err) { + printf("%s: could send power command (error %d)\n", + DEVNAME(sc), err); + return; + } #ifdef notyet /* * Disabled for now. Default beacon filter settings * prevent net80211 from getting ERP and HT protection * updates from beacons. */ - iwm_enable_beacon_filter(sc, in); + err = iwm_enable_beacon_filter(sc, in); + if (err) { + printf("%s: could not enable beacon filter\n", + DEVNAME(sc)); + return; + } #endif - iwm_update_quotas(sc, in); + err = iwm_power_mac_update_mode(sc, in); + if (err) { + printf("%s: could not update MAC power (error %d)\n", + DEVNAME(sc), err); + return; + } + + err = iwm_update_quotas(sc, in); + if (err) { + printf("%s: could not update quotas (error %d)\n", + DEVNAME(sc), err); + return; + } ieee80211_amrr_node_init(&sc->sc_amrr, &in->in_amn); @@ -5875,7 +5890,7 @@ iwm_init_hw(struct iwm_softc *sc) } } - err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_ADD); + err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_ADD, 0); if (err) { printf("%s: could not add MAC context (error %d)\n", DEVNAME(sc), err); @@ -6031,7 +6046,6 @@ iwm_stop(struct ifnet *ifp, int disable) ifq_clr_oactive(&ifp->if_snd); in->in_phyctxt = NULL; - in->in_assoc = 0; task_del(systq, &sc->init_task); task_del(sc->sc_nswq, &sc->newstate_task); diff --git a/sys/dev/pci/if_iwmvar.h b/sys/dev/pci/if_iwmvar.h index 4273254a4c3..42244ab8130 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.23 2016/09/12 10:18:26 stsp Exp $ */ +/* $OpenBSD: if_iwmvar.h,v 1.24 2016/09/21 13:53:18 stsp Exp $ */ /* * Copyright (c) 2014 genua mbh <info@genua.de> @@ -501,10 +501,6 @@ struct iwm_node { uint16_t in_id; uint16_t in_color; - int in_tsfid; - - /* status "bits" */ - int in_assoc; struct iwm_lq_cmd in_lq; struct ieee80211_amrr_node in_amn; |