-/* $OpenBSD: if_iwn.c,v 1.250 2021/10/11 09:01:05 stsp Exp $ */
+/* $OpenBSD: if_iwn.c,v 1.251 2021/11/11 13:36:58 stsp Exp $ */
/*-
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
struct ieee80211_key *);
void iwn_updateprot(struct ieee80211com *);
void iwn_updateslot(struct ieee80211com *);
-void iwn_update_rxon(struct iwn_softc *);
+void iwn_update_rxon_restore_power(struct iwn_softc *);
+void iwn5000_update_rxon(struct iwn_softc *);
+void iwn4965_update_rxon(struct iwn_softc *);
int iwn_ampdu_rx_start(struct ieee80211com *,
struct ieee80211_node *, uint8_t);
void iwn_ampdu_rx_stop(struct ieee80211com *,
ops->nic_config = iwn4965_nic_config;
ops->reset_sched = iwn4965_reset_sched;
ops->update_sched = iwn4965_update_sched;
+ ops->update_rxon = iwn4965_update_rxon;
ops->get_temperature = iwn4965_get_temperature;
ops->get_rssi = iwn4965_get_rssi;
ops->set_txpower = iwn4965_set_txpower;
ops->nic_config = iwn5000_nic_config;
ops->reset_sched = iwn5000_reset_sched;
ops->update_sched = iwn5000_update_sched;
+ ops->update_rxon = iwn5000_update_rxon;
ops->get_temperature = iwn5000_get_temperature;
ops->get_rssi = iwn5000_get_rssi;
ops->set_txpower = iwn5000_set_txpower;
sc->rxon.flags &= ~htole32(IWN_RXON_HT_PROTMODE(3));
sc->rxon.flags |= htole32(IWN_RXON_HT_PROTMODE(htprot));
- iwn_update_rxon(sc);
+ sc->ops.update_rxon(sc);
}
void
else
sc->rxon.flags &= ~htole32(IWN_RXON_SHPREAMBLE);
- iwn_update_rxon(sc);
+ sc->ops.update_rxon(sc);
}
+
void
-iwn_update_rxon(struct iwn_softc *sc)
+iwn_update_rxon_restore_power(struct iwn_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
struct iwn_ops *ops = &sc->ops;
+ int error;
+
+ DELAY(100);
+
+ /* All RXONs wipe the firmware's txpower table. Restore it. */
+ error = ops->set_txpower(sc, 1);
+ if (error != 0)
+ printf("%s: could not set TX power\n", sc->sc_dev.dv_xname);
+
+ DELAY(100);
+
+ /* Restore power saving level */
+ if (ic->ic_flags & IEEE80211_F_PMGTON)
+ error = iwn_set_pslevel(sc, 0, 3, 1);
+ else
+ error = iwn_set_pslevel(sc, 0, 0, 1);
+ if (error != 0)
+ printf("%s: could not set PS level\n", sc->sc_dev.dv_xname);
+}
+
+void
+iwn5000_update_rxon(struct iwn_softc *sc)
+{
struct iwn_rxon_assoc rxon_assoc;
int s, error;
if (error != 0)
printf("%s: RXON_ASSOC command failed\n", sc->sc_dev.dv_xname);
- DELAY(100);
+ iwn_update_rxon_restore_power(sc);
- /* All RXONs wipe the firmware's txpower table. Restore it. */
- error = ops->set_txpower(sc, 1);
- if (error != 0)
- printf("%s: could not set TX power\n", sc->sc_dev.dv_xname);
+ splx(s);
+}
- DELAY(100);
+void
+iwn4965_update_rxon(struct iwn_softc *sc)
+{
+ struct iwn4965_rxon_assoc rxon_assoc;
+ int s, error;
- /* Restore power saving level */
- if (ic->ic_flags & IEEE80211_F_PMGTON)
- error = iwn_set_pslevel(sc, 0, 3, 1);
- else
- error = iwn_set_pslevel(sc, 0, 0, 1);
+ /* Update RXON config. */
+ memset(&rxon_assoc, 0, sizeof(rxon_assoc));
+ rxon_assoc.flags = sc->rxon.flags;
+ rxon_assoc.filter = sc->rxon.filter;
+ rxon_assoc.ofdm_mask = sc->rxon.ofdm_mask;
+ rxon_assoc.cck_mask = sc->rxon.cck_mask;
+ rxon_assoc.ht_single_mask = sc->rxon.ht_single_mask;
+ rxon_assoc.ht_dual_mask = sc->rxon.ht_dual_mask;
+ rxon_assoc.rxchain = sc->rxon.rxchain;
+
+ s = splnet();
+
+ error = iwn_cmd(sc, IWN_CMD_RXON_ASSOC, &rxon_assoc,
+ sizeof(rxon_assoc), 1);
if (error != 0)
- printf("%s: could not set PS level\n", sc->sc_dev.dv_xname);
+ printf("%s: RXON_ASSOC command failed\n", sc->sc_dev.dv_xname);
+
+ iwn_update_rxon_restore_power(sc);
splx(s);
}