From 86734cc40e1a7992c58fd870bdc2ed3a376c0bb5 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Mon, 7 Jan 2019 20:15:41 -0500 Subject: [PATCH] idualwifi7260: Upgrade to FreeBSD 12. Tested on a 7265D. --- .../kernel/drivers/network/wlan/Jamfile | 4 +- .../network/wlan/idualwifi7260/Jamfile | 1 + .../wlan/idualwifi7260/dev/iwm/if_iwm.c | 412 ++++++------------ .../wlan/idualwifi7260/dev/iwm/if_iwm_7000.c | 10 +- .../wlan/idualwifi7260/dev/iwm/if_iwm_8000.c | 2 +- .../idualwifi7260/dev/iwm/if_iwm_binding.c | 11 +- .../idualwifi7260/dev/iwm/if_iwm_binding.h | 2 +- .../idualwifi7260/dev/iwm/if_iwm_config.h | 3 +- .../idualwifi7260/dev/iwm/if_iwm_constants.h | 2 +- .../wlan/idualwifi7260/dev/iwm/if_iwm_debug.h | 4 +- .../wlan/idualwifi7260/dev/iwm/if_iwm_fw.c | 2 +- .../wlan/idualwifi7260/dev/iwm/if_iwm_fw.h | 2 +- .../wlan/idualwifi7260/dev/iwm/if_iwm_led.c | 2 +- .../wlan/idualwifi7260/dev/iwm/if_iwm_led.h | 2 +- .../idualwifi7260/dev/iwm/if_iwm_mac_ctxt.c | 2 +- .../idualwifi7260/dev/iwm/if_iwm_mac_ctxt.h | 2 +- .../idualwifi7260/dev/iwm/if_iwm_notif_wait.c | 2 +- .../idualwifi7260/dev/iwm/if_iwm_notif_wait.h | 2 +- .../idualwifi7260/dev/iwm/if_iwm_pcie_trans.c | 2 +- .../idualwifi7260/dev/iwm/if_iwm_pcie_trans.h | 2 +- .../idualwifi7260/dev/iwm/if_iwm_phy_ctxt.c | 2 +- .../idualwifi7260/dev/iwm/if_iwm_phy_ctxt.h | 2 +- .../idualwifi7260/dev/iwm/if_iwm_phy_db.c | 2 +- .../idualwifi7260/dev/iwm/if_iwm_phy_db.h | 2 +- .../wlan/idualwifi7260/dev/iwm/if_iwm_power.c | 63 ++- .../wlan/idualwifi7260/dev/iwm/if_iwm_power.h | 4 +- .../wlan/idualwifi7260/dev/iwm/if_iwm_scan.c | 156 ++++++- .../wlan/idualwifi7260/dev/iwm/if_iwm_scan.h | 10 +- .../wlan/idualwifi7260/dev/iwm/if_iwm_sf.c | 330 ++++++++++++++ .../wlan/idualwifi7260/dev/iwm/if_iwm_sf.h | 82 ++++ .../wlan/idualwifi7260/dev/iwm/if_iwm_sta.c | 2 +- .../wlan/idualwifi7260/dev/iwm/if_iwm_sta.h | 2 +- .../idualwifi7260/dev/iwm/if_iwm_time_event.c | 2 +- .../idualwifi7260/dev/iwm/if_iwm_time_event.h | 2 +- .../wlan/idualwifi7260/dev/iwm/if_iwm_util.c | 5 +- .../wlan/idualwifi7260/dev/iwm/if_iwm_util.h | 2 +- .../wlan/idualwifi7260/dev/iwm/if_iwmreg.h | 27 +- .../wlan/idualwifi7260/dev/iwm/if_iwmvar.h | 14 +- 38 files changed, 794 insertions(+), 386 deletions(-) create mode 100644 src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sf.c create mode 100644 src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sf.h diff --git a/src/add-ons/kernel/drivers/network/wlan/Jamfile b/src/add-ons/kernel/drivers/network/wlan/Jamfile index fd12e63630..2604b308be 100644 --- a/src/add-ons/kernel/drivers/network/wlan/Jamfile +++ b/src/add-ons/kernel/drivers/network/wlan/Jamfile @@ -14,5 +14,7 @@ SubInclude HAIKU_TOP src add-ons kernel drivers network wlan realtekwifi ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan wavelanwifi ; # FreeBSD 11.2 drivers -SubInclude HAIKU_TOP src add-ons kernel drivers network wlan idualwifi7260 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi2200 ; + +# FreeBSD 12 drivers +SubInclude HAIKU_TOP src add-ons kernel drivers network wlan idualwifi7260 ; diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/Jamfile b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/Jamfile index d9b7882382..fd2affe854 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/Jamfile +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/Jamfile @@ -28,6 +28,7 @@ KernelAddon idualwifi7260 : if_iwm_phy_db.c if_iwm_power.c if_iwm_scan.c + if_iwm_sf.c if_iwm_sta.c if_iwm_time_event.c if_iwm_util.c diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm.c index facebd73ae..02b5c8df13 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm.c @@ -103,7 +103,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm.c 330784 2018-03-11 22:49:46Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm.c 339038 2018-10-01 10:44:33Z bz $"); #include "opt_wlan.h" #include "opt_iwm.h" @@ -164,6 +164,7 @@ __FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm.c 330784 2018-03-11 22:49:46Z #include #include #include +#include #include #include @@ -230,8 +231,8 @@ struct iwm_nvm_section { uint8_t *data; }; -#define IWM_MVM_UCODE_ALIVE_TIMEOUT (10*hz) -#define IWM_MVM_UCODE_CALIB_TIMEOUT (2*hz) +#define IWM_MVM_UCODE_ALIVE_TIMEOUT (5*hz) +#define IWM_MVM_UCODE_CALIB_TIMEOUT (10*hz) struct iwm_mvm_alive_data { int valid; @@ -348,7 +349,6 @@ static int iwm_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static int iwm_mvm_update_quotas(struct iwm_softc *, struct iwm_vap *); static int iwm_auth(struct ieee80211vap *, struct iwm_softc *); -static int iwm_assoc(struct ieee80211vap *, struct iwm_softc *); static int iwm_release(struct iwm_softc *, struct iwm_node *); static struct ieee80211_node * iwm_node_alloc(struct ieee80211vap *, @@ -357,10 +357,6 @@ static void iwm_setrates(struct iwm_softc *, struct iwm_node *); static int iwm_media_change(struct ifnet *); static int iwm_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void iwm_endscan_cb(void *, int); -static void iwm_mvm_fill_sf_command(struct iwm_softc *, - struct iwm_sf_cfg_cmd *, - struct ieee80211_node *); -static int iwm_mvm_sf_config(struct iwm_softc *, enum iwm_sf_state); static int iwm_send_bt_init_conf(struct iwm_softc *); static boolean_t iwm_mvm_is_lar_supported(struct iwm_softc *); static boolean_t iwm_mvm_is_wifi_mcc_supported(struct iwm_softc *); @@ -547,12 +543,14 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) { struct iwm_fw_info *fw = &sc->sc_fw; const struct iwm_tlv_ucode_header *uhdr; - struct iwm_ucode_tlv tlv; + const struct iwm_ucode_tlv *tlv; struct iwm_ucode_capabilities *capa = &sc->ucode_capa; enum iwm_ucode_tlv_type tlv_type; const struct firmware *fwp; const uint8_t *data; + uint32_t tlv_len; uint32_t usniffer_img; + const uint8_t *tlv_data; uint32_t paging_mem_size; int num_of_cpus; int error = 0; @@ -605,24 +603,20 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) goto out; } - snprintf(sc->sc_fwver, sizeof(sc->sc_fwver), "%d.%d (API ver %d)", + snprintf(sc->sc_fwver, sizeof(sc->sc_fwver), "%u.%u (API ver %u)", IWM_UCODE_MAJOR(le32toh(uhdr->ver)), IWM_UCODE_MINOR(le32toh(uhdr->ver)), IWM_UCODE_API(le32toh(uhdr->ver))); data = uhdr->data; len = fw->fw_fp->datasize - sizeof(*uhdr); - while (len >= sizeof(tlv)) { - size_t tlv_len; - const void *tlv_data; + while (len >= sizeof(*tlv)) { + len -= sizeof(*tlv); + tlv = (const void *)data; - memcpy(&tlv, data, sizeof(tlv)); - tlv_len = le32toh(tlv.length); - tlv_type = le32toh(tlv.type); - - len -= sizeof(tlv); - data += sizeof(tlv); - tlv_data = data; + tlv_len = le32toh(tlv->length); + tlv_type = le32toh(tlv->type); + tlv_data = tlv->data; if (len < tlv_len) { device_printf(sc->sc_dev, @@ -631,19 +625,21 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) error = EINVAL; goto parse_out; } + len -= roundup2(tlv_len, 4); + data += sizeof(tlv) + roundup2(tlv_len, 4); switch ((int)tlv_type) { case IWM_UCODE_TLV_PROBE_MAX_LEN: - if (tlv_len < sizeof(uint32_t)) { + if (tlv_len != sizeof(uint32_t)) { device_printf(sc->sc_dev, - "%s: PROBE_MAX_LEN (%d) < sizeof(uint32_t)\n", + "%s: PROBE_MAX_LEN (%d) != sizeof(uint32_t)\n", __func__, (int) tlv_len); error = EINVAL; goto parse_out; } capa->max_probe_length = - le32toh(*(const uint32_t *)tlv_data); + le32_to_cpup((const uint32_t *)tlv_data); /* limit it to something sensible */ if (capa->max_probe_length > IWM_SCAN_OFFLOAD_PROBE_REQ_SIZE) { @@ -674,6 +670,14 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) error = EINVAL; goto parse_out; } + if (tlv_len % sizeof(uint32_t)) { + device_printf(sc->sc_dev, + "%s: IWM_UCODE_TLV_FLAGS: tlv_len (%d) %% sizeof(uint32_t)\n", + __func__, + (int) tlv_len); + error = EINVAL; + goto parse_out; + } /* * Apparently there can be many flags, but Linux driver * parses only the first one, and so do we. @@ -685,7 +689,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) * 2) TLV_FLAGS contains TLV_FLAGS_PAN * ==> this resets TLV_PAN to itself... hnnnk */ - capa->flags = le32toh(*(const uint32_t *)tlv_data); + capa->flags = le32_to_cpup((const uint32_t *)tlv_data); break; case IWM_UCODE_TLV_CSCHEME: if ((error = iwm_store_cscheme(sc, @@ -706,7 +710,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) error = EINVAL; goto parse_out; } - num_of_cpus = le32toh(*(const uint32_t *)tlv_data); + num_of_cpus = le32_to_cpup((const uint32_t *)tlv_data); if (num_of_cpus == 2) { fw->fw_sects[IWM_UCODE_REGULAR].is_dual_cpus = TRUE; @@ -780,7 +784,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) goto parse_out; } sc->sc_fw.phy_config = - le32toh(*(const uint32_t *)tlv_data); + le32_to_cpup((const uint32_t *)tlv_data); sc->sc_fw.valid_tx_ant = (sc->sc_fw.phy_config & IWM_FW_PHY_CFG_TX_CHAIN) >> IWM_FW_PHY_CFG_TX_CHAIN_POS; @@ -831,7 +835,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) error = EINVAL; goto parse_out; } - paging_mem_size = le32toh(*(const uint32_t *)tlv_data); + paging_mem_size = le32_to_cpup((const uint32_t *)tlv_data); IWM_DPRINTF(sc, IWM_DEBUG_FIRMWARE_TLV, "%s: Paging: paging enabled (size = %u bytes)\n", @@ -864,7 +868,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) goto parse_out; } capa->n_scan_channels = - le32toh(*(const uint32_t *)tlv_data); + le32_to_cpup((const uint32_t *)tlv_data); break; case IWM_UCODE_TLV_FW_VERSION: @@ -889,9 +893,6 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) error = EINVAL; goto parse_out; } - - len -= roundup(tlv_len, 4); - data += roundup(tlv_len, 4); } KASSERT(error == 0, ("unhandled error")); @@ -1439,10 +1440,10 @@ iwm_nic_rx_init(struct iwm_softc *sc) IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG, IWM_FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | IWM_FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | /* HW bug */ -//#ifdef __HAIKU__ +#ifdef __HAIKU__ /* multi-frame RX seems to cause UAFs and double-frees */ IWM_FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK | -//#endif +#endif IWM_FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | IWM_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K | (IWM_RX_RB_TIMEOUT << IWM_FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS) | @@ -3004,11 +3005,6 @@ iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm) goto error; } - /* Init Smart FIFO. */ - ret = iwm_mvm_sf_config(sc, IWM_SF_INIT_OFF); - if (ret) - goto error; - /* Send TX valid antennas before triggering calibrations */ ret = iwm_send_tx_ant_cfg(sc, iwm_mvm_get_valid_tx_ant(sc)); if (ret) { @@ -3265,8 +3261,11 @@ iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, uint32_t offset, /* rssi is in 1/2db units */ rxs.c_rssi = rssi * 2; rxs.c_nf = sc->sc_noise; - if (ieee80211_add_rx_params(m, &rxs) == 0) + if (ieee80211_add_rx_params(m, &rxs) == 0) { + if (ni) + ieee80211_free_node(ni); goto fail; + } if (ieee80211_radiotap_active_vap(vap)) { struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap; @@ -3313,7 +3312,8 @@ iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, uint32_t offset, return TRUE; -fail: counter_u64_add(ic->ic_ierrors, 1); +fail: + counter_u64_add(ic->ic_ierrors, 1); return FALSE; } @@ -3557,7 +3557,9 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, tx->rts_retry_limit = IWM_RTS_DFAULT_RETRY_LIMIT; tx->data_retry_limit = IWM_DEFAULT_TX_RETRY; - if (type == IEEE80211_FC0_TYPE_MGT) { + if (type == IEEE80211_FC0_TYPE_MGT || + type == IEEE80211_FC0_TYPE_CTL || + (m->m_flags & M_EAPOL) != 0) { ridx = iwm_tx_rateidx_global_lookup(sc, tp->mgmtrate); IWM_DPRINTF(sc, IWM_DEBUG_TXRATE, "%s: MGT (%d)\n", __func__, tp->mgmtrate); @@ -3569,11 +3571,7 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, ridx = iwm_tx_rateidx_global_lookup(sc, tp->ucastrate); IWM_DPRINTF(sc, IWM_DEBUG_TXRATE, "%s: FIXED_RATE (%d)\n", __func__, tp->ucastrate); - } else if (m->m_flags & M_EAPOL) { - ridx = iwm_tx_rateidx_global_lookup(sc, tp->mgmtrate); - IWM_DPRINTF(sc, IWM_DEBUG_TXRATE, - "%s: EAPOL\n", __func__); - } else if (type == IEEE80211_FC0_TYPE_DATA) { + } else { int i; /* for data frames, use RS table */ @@ -3590,10 +3588,6 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in, IWM_DPRINTF(sc, IWM_DEBUG_XMIT | IWM_DEBUG_TXRATE, "%s: start with i=%d, txrate %d\n", __func__, i, iwm_rates[ridx].rate); - } else { - ridx = iwm_tx_rateidx_global_lookup(sc, tp->mgmtrate); - IWM_DPRINTF(sc, IWM_DEBUG_TXRATE, "%s: DEFAULT (%d)\n", - __func__, tp->mgmtrate); } IWM_DPRINTF(sc, IWM_DEBUG_XMIT | IWM_DEBUG_TXRATE, @@ -4016,10 +4010,6 @@ iwm_auth(struct ieee80211vap *vap, struct iwm_softc *sc) goto out; } - error = iwm_mvm_sf_config(sc, IWM_SF_FULL_ON); - if (error != 0) - return error; - error = iwm_allow_mcast(vap, sc); if (error) { device_printf(sc->sc_dev, @@ -4048,55 +4038,45 @@ iwm_auth(struct ieee80211vap *vap, struct iwm_softc *sc) "%s: failed to update MAC\n", __func__); goto out; } - if ((error = iwm_mvm_phy_ctxt_changed(sc, &sc->sc_phyctxt[0], - in->in_ni.ni_chan, 1, 1)) != 0) { - device_printf(sc->sc_dev, - "%s: failed update phy ctxt\n", __func__); - goto out; - } - iv->phy_ctxt = &sc->sc_phyctxt[0]; - - if ((error = iwm_mvm_binding_add_vif(sc, iv)) != 0) { - device_printf(sc->sc_dev, - "%s: binding update cmd\n", __func__); - goto out; - } - if ((error = iwm_mvm_update_sta(sc, in)) != 0) { - device_printf(sc->sc_dev, - "%s: failed to update sta\n", __func__); - goto out; - } } else { if ((error = iwm_mvm_mac_ctxt_add(sc, vap)) != 0) { device_printf(sc->sc_dev, "%s: failed to add MAC\n", __func__); goto out; } - if ((error = iwm_mvm_power_update_mac(sc)) != 0) { - device_printf(sc->sc_dev, - "%s: failed to update power management\n", - __func__); - goto out; - } - if ((error = iwm_mvm_phy_ctxt_changed(sc, &sc->sc_phyctxt[0], - in->in_ni.ni_chan, 1, 1)) != 0) { - device_printf(sc->sc_dev, - "%s: failed add phy ctxt!\n", __func__); - error = ETIMEDOUT; - goto out; - } - iv->phy_ctxt = &sc->sc_phyctxt[0]; + } - if ((error = iwm_mvm_binding_add_vif(sc, iv)) != 0) { - device_printf(sc->sc_dev, - "%s: binding add cmd\n", __func__); - goto out; - } - if ((error = iwm_mvm_add_sta(sc, in)) != 0) { - device_printf(sc->sc_dev, - "%s: failed to add sta\n", __func__); - goto out; - } + if ((error = iwm_mvm_phy_ctxt_changed(sc, &sc->sc_phyctxt[0], + in->in_ni.ni_chan, 1, 1)) != 0) { + device_printf(sc->sc_dev, + "%s: failed update phy ctxt\n", __func__); + goto out; + } + iv->phy_ctxt = &sc->sc_phyctxt[0]; + + if ((error = iwm_mvm_binding_add_vif(sc, iv)) != 0) { + device_printf(sc->sc_dev, + "%s: binding update cmd\n", __func__); + goto out; + } + /* + * Authentication becomes unreliable when powersaving is left enabled + * here. Powersaving will be activated again when association has + * finished or is aborted. + */ + iv->ps_disabled = TRUE; + error = iwm_mvm_power_update_mac(sc); + iv->ps_disabled = FALSE; + if (error != 0) { + device_printf(sc->sc_dev, + "%s: failed to update power management\n", + __func__); + goto out; + } + if ((error = iwm_mvm_add_sta(sc, in)) != 0) { + device_printf(sc->sc_dev, + "%s: failed to add sta\n", __func__); + goto out; } /* @@ -4114,28 +4094,6 @@ out: return (error); } -static int -iwm_assoc(struct ieee80211vap *vap, struct iwm_softc *sc) -{ - struct iwm_node *in = IWM_NODE(vap->iv_bss); - int error; - - if ((error = iwm_mvm_update_sta(sc, in)) != 0) { - device_printf(sc->sc_dev, - "%s: failed to update STA\n", __func__); - return error; - } - - in->in_assoc = 1; - if ((error = iwm_mvm_mac_ctxt_changed(sc, vap)) != 0) { - device_printf(sc->sc_dev, - "%s: failed to update MAC\n", __func__); - return error; - } - - return 0; -} - static int iwm_release(struct iwm_softc *sc, struct iwm_node *in) { @@ -4472,6 +4430,12 @@ iwm_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) __func__, error); } ivp->phy_ctxt = NULL; + error = iwm_mvm_power_update_mac(sc); + if (error != 0) { + device_printf(sc->sc_dev, + "%s: failed to update power management\n", + __func__); + } IWM_UNLOCK(sc); IEEE80211_LOCK(ic); return myerr; @@ -4483,33 +4447,38 @@ iwm_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) device_printf(sc->sc_dev, "%s: could not move to auth state: %d\n", __func__, error); - break; } break; case IEEE80211_S_ASSOC: - if ((error = iwm_assoc(vap, sc)) != 0) { - device_printf(sc->sc_dev, - "%s: failed to associate: %d\n", __func__, - error); - break; - } + /* + * EBS may be disabled due to previous failures reported by FW. + * Reset EBS status here assuming environment has been changed. + */ + sc->last_ebs_successful = TRUE; break; case IEEE80211_S_RUN: + in = IWM_NODE(vap->iv_bss); /* Update the association state, now we have it all */ /* (eg associd comes in at this point */ - error = iwm_assoc(vap, sc); + error = iwm_mvm_update_sta(sc, in); if (error != 0) { device_printf(sc->sc_dev, - "%s: failed to update association state: %d\n", - __func__, - error); - break; + "%s: failed to update STA\n", __func__); + IWM_UNLOCK(sc); + IEEE80211_LOCK(ic); + return error; + } + in->in_assoc = 1; + error = iwm_mvm_mac_ctxt_changed(sc, vap); + if (error != 0) { + device_printf(sc->sc_dev, + "%s: failed to update MAC: %d\n", __func__, error); } - in = IWM_NODE(vap->iv_bss); - iwm_mvm_enable_beacon_filter(sc, in); + iwm_mvm_sf_update(sc, vap, FALSE); + iwm_mvm_enable_beacon_filter(sc, ivp); iwm_mvm_power_update_mac(sc); iwm_mvm_update_quotas(sc, ivp); iwm_setrates(sc, in); @@ -4544,142 +4513,6 @@ iwm_endscan_cb(void *arg, int pending) ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps)); } -/* - * Aging and idle timeouts for the different possible scenarios - * in default configuration - */ -static const uint32_t -iwm_sf_full_timeout_def[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = { - { - htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER_DEF), - htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER_DEF) - }, - { - htole32(IWM_SF_AGG_UNICAST_AGING_TIMER_DEF), - htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER_DEF) - }, - { - htole32(IWM_SF_MCAST_AGING_TIMER_DEF), - htole32(IWM_SF_MCAST_IDLE_TIMER_DEF) - }, - { - htole32(IWM_SF_BA_AGING_TIMER_DEF), - htole32(IWM_SF_BA_IDLE_TIMER_DEF) - }, - { - htole32(IWM_SF_TX_RE_AGING_TIMER_DEF), - htole32(IWM_SF_TX_RE_IDLE_TIMER_DEF) - }, -}; - -/* - * Aging and idle timeouts for the different possible scenarios - * in single BSS MAC configuration. - */ -static const uint32_t -iwm_sf_full_timeout[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = { - { - htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER), - htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER) - }, - { - htole32(IWM_SF_AGG_UNICAST_AGING_TIMER), - htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER) - }, - { - htole32(IWM_SF_MCAST_AGING_TIMER), - htole32(IWM_SF_MCAST_IDLE_TIMER) - }, - { - htole32(IWM_SF_BA_AGING_TIMER), - htole32(IWM_SF_BA_IDLE_TIMER) - }, - { - htole32(IWM_SF_TX_RE_AGING_TIMER), - htole32(IWM_SF_TX_RE_IDLE_TIMER) - }, -}; - -static void -iwm_mvm_fill_sf_command(struct iwm_softc *sc, struct iwm_sf_cfg_cmd *sf_cmd, - struct ieee80211_node *ni) -{ - int i, j, watermark; - - sf_cmd->watermark[IWM_SF_LONG_DELAY_ON] = htole32(IWM_SF_W_MARK_SCAN); - - /* - * If we are in association flow - check antenna configuration - * capabilities of the AP station, and choose the watermark accordingly. - */ - if (ni) { - if (ni->ni_flags & IEEE80211_NODE_HT) { -#ifdef notyet - if (ni->ni_rxmcs[2] != 0) - watermark = IWM_SF_W_MARK_MIMO3; - else if (ni->ni_rxmcs[1] != 0) - watermark = IWM_SF_W_MARK_MIMO2; - else -#endif - watermark = IWM_SF_W_MARK_SISO; - } else { - watermark = IWM_SF_W_MARK_LEGACY; - } - /* default watermark value for unassociated mode. */ - } else { - watermark = IWM_SF_W_MARK_MIMO2; - } - sf_cmd->watermark[IWM_SF_FULL_ON] = htole32(watermark); - - for (i = 0; i < IWM_SF_NUM_SCENARIO; i++) { - for (j = 0; j < IWM_SF_NUM_TIMEOUT_TYPES; j++) { - sf_cmd->long_delay_timeouts[i][j] = - htole32(IWM_SF_LONG_DELAY_AGING_TIMER); - } - } - - if (ni) { - memcpy(sf_cmd->full_on_timeouts, iwm_sf_full_timeout, - sizeof(iwm_sf_full_timeout)); - } else { - memcpy(sf_cmd->full_on_timeouts, iwm_sf_full_timeout_def, - sizeof(iwm_sf_full_timeout_def)); - } -} - -static int -iwm_mvm_sf_config(struct iwm_softc *sc, enum iwm_sf_state new_state) -{ - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct iwm_sf_cfg_cmd sf_cmd = { - .state = htole32(IWM_SF_FULL_ON), - }; - int ret = 0; - - if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) - sf_cmd.state |= htole32(IWM_SF_CFG_DUMMY_NOTIF_OFF); - - switch (new_state) { - case IWM_SF_UNINIT: - case IWM_SF_INIT_OFF: - iwm_mvm_fill_sf_command(sc, &sf_cmd, NULL); - break; - case IWM_SF_FULL_ON: - iwm_mvm_fill_sf_command(sc, &sf_cmd, vap->iv_bss); - break; - default: - IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE, - "Invalid state: %d. not sending Smart Fifo cmd\n", - new_state); - return EINVAL; - } - - ret = iwm_mvm_send_cmd_pdu(sc, IWM_REPLY_SF_CFG_CMD, IWM_CMD_ASYNC, - sizeof(sf_cmd), &sf_cmd); - return ret; -} - static int iwm_send_bt_init_conf(struct iwm_softc *sc) { @@ -4815,6 +4648,8 @@ iwm_init_hw(struct iwm_softc *sc) struct ieee80211com *ic = &sc->sc_ic; int error, i, ac; + sc->sf_state = IWM_SF_UNINIT; + if ((error = iwm_start_hw(sc)) != 0) { printf("iwm_start_hw: failed %d\n", error); return error; @@ -4843,6 +4678,10 @@ iwm_init_hw(struct iwm_softc *sc) goto error; } + error = iwm_mvm_sf_update(sc, NULL, FALSE); + if (error) + device_printf(sc->sc_dev, "Failed to initialize Smart Fifo\n"); + if ((error = iwm_send_bt_init_conf(sc)) != 0) { device_printf(sc->sc_dev, "bt init conf failed\n"); goto error; @@ -5543,36 +5382,27 @@ iwm_handle_rxb(struct iwm_softc *sc, struct mbuf *m) case IWM_INIT_COMPLETE_NOTIF: break; - case IWM_SCAN_OFFLOAD_COMPLETE: { - struct iwm_periodic_scan_complete *notif; - notif = (void *)pkt->data; + case IWM_SCAN_OFFLOAD_COMPLETE: + iwm_mvm_rx_lmac_scan_complete_notif(sc, pkt); if (sc->sc_flags & IWM_FLAG_SCAN_RUNNING) { sc->sc_flags &= ~IWM_FLAG_SCAN_RUNNING; ieee80211_runtask(ic, &sc->sc_es_task); } break; - } case IWM_SCAN_ITERATION_COMPLETE: { struct iwm_lmac_scan_complete_notif *notif; notif = (void *)pkt->data; - ieee80211_runtask(&sc->sc_ic, &sc->sc_es_task); - break; + break; } - case IWM_SCAN_COMPLETE_UMAC: { - struct iwm_umac_scan_complete *notif; - notif = (void *)pkt->data; - - IWM_DPRINTF(sc, IWM_DEBUG_SCAN, - "UMAC scan complete, status=0x%x\n", - notif->status); + case IWM_SCAN_COMPLETE_UMAC: + iwm_mvm_rx_umac_scan_complete_notif(sc, pkt); if (sc->sc_flags & IWM_FLAG_SCAN_RUNNING) { sc->sc_flags &= ~IWM_FLAG_SCAN_RUNNING; ieee80211_runtask(ic, &sc->sc_es_task); } break; - } case IWM_SCAN_ITERATION_COMPLETE_UMAC: { struct iwm_umac_scan_iter_complete_notif *notif; @@ -5581,7 +5411,6 @@ iwm_handle_rxb(struct iwm_softc *sc, struct mbuf *m) IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "UMAC scan iteration " "complete, status=0x%x, %d channels scanned\n", notif->status, notif->scanned_channels); - ieee80211_runtask(&sc->sc_ic, &sc->sc_es_task); break; } @@ -5868,6 +5697,7 @@ iwm_intr(void *arg) #define PCI_PRODUCT_INTEL_WL_3160_2 0x08b4 #define PCI_PRODUCT_INTEL_WL_3165_1 0x3165 #define PCI_PRODUCT_INTEL_WL_3165_2 0x3166 +#define PCI_PRODUCT_INTEL_WL_3168_1 0x24fb #define PCI_PRODUCT_INTEL_WL_7260_1 0x08b1 #define PCI_PRODUCT_INTEL_WL_7260_2 0x08b2 #define PCI_PRODUCT_INTEL_WL_7265_1 0x095a @@ -5884,6 +5714,7 @@ static const struct iwm_devices { { PCI_PRODUCT_INTEL_WL_3160_2, &iwm3160_cfg }, { PCI_PRODUCT_INTEL_WL_3165_1, &iwm3165_cfg }, { PCI_PRODUCT_INTEL_WL_3165_2, &iwm3165_cfg }, + { PCI_PRODUCT_INTEL_WL_3168_1, &iwm3168_cfg }, { PCI_PRODUCT_INTEL_WL_7260_1, &iwm7260_cfg }, { PCI_PRODUCT_INTEL_WL_7260_2, &iwm7260_cfg }, { PCI_PRODUCT_INTEL_WL_7265_1, &iwm7265_cfg }, @@ -6026,6 +5857,8 @@ iwm_attach(device_t dev) goto fail; } + sc->sf_state = IWM_SF_UNINIT; + /* Init phy db */ sc->sc_phy_db = iwm_phy_db_init(sc); if (!sc->sc_phy_db) { @@ -6033,6 +5866,9 @@ iwm_attach(device_t dev) goto fail; } + /* Set EBS as successful as long as not stated otherwise by the FW. */ + sc->last_ebs_successful = TRUE; + /* PCI attach */ error = iwm_pci_attach(dev); if (error != 0) @@ -6165,9 +6001,7 @@ iwm_attach(device_t dev) // IEEE80211_C_BGSCAN /* capable of bg scanning */ ; /* Advertise full-offload scanning */ -#ifndef __HAIKU__ ic->ic_flags_ext = IEEE80211_FEXT_SCAN_OFFLOAD; -#endif for (i = 0; i < nitems(sc->sc_phyctxt); i++) { sc->sc_phyctxt[i].id = i; sc->sc_phyctxt[i].color = 0; @@ -6222,6 +6056,7 @@ iwm_wme_update(struct ieee80211com *ic) { #define IWM_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */ struct iwm_softc *sc = ic->ic_softc; + struct chanAccParams chp; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct iwm_vap *ivp = IWM_VAP(vap); struct iwm_node *in; @@ -6231,9 +6066,11 @@ iwm_wme_update(struct ieee80211com *ic) if (vap == NULL) return (0); + ieee80211_wme_ic_getparams(ic, &chp); + IEEE80211_LOCK(ic); for (aci = 0; aci < WME_NUM_AC; aci++) - tmp[aci] = ic->ic_wme.wme_chanParams.cap_wmeParams[aci]; + tmp[aci] = chp.cap_wmeParams[aci]; IEEE80211_UNLOCK(ic); IWM_LOCK(sc); @@ -6376,6 +6213,7 @@ iwm_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ivp->color = IWM_DEFAULT_COLOR; ivp->have_wme = FALSE; + ivp->ps_disabled = FALSE; ieee80211_ratectl_init(vap); /* Complete setup. */ @@ -6637,6 +6475,8 @@ static driver_t iwm_pci_driver = { static devclass_t iwm_devclass; DRIVER_MODULE(iwm, pci, iwm_pci_driver, iwm_devclass, NULL, NULL); +MODULE_PNP_INFO("U16:device;P:#;T:vendor=0x8086", pci, iwm_pci_driver, + iwm_devices, nitems(iwm_devices)); MODULE_DEPEND(iwm, firmware, 1, 1, 1); MODULE_DEPEND(iwm, pci, 1, 1, 1); MODULE_DEPEND(iwm, wlan, 1, 1, 1); diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_7000.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_7000.c index 948253676c..b70809ba06 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_7000.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_7000.c @@ -70,7 +70,7 @@ *****************************************************************************/ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_7000.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_7000.c 331665 2018-03-28 07:59:16Z eadler $"); #include "opt_wlan.h" #include "opt_iwm.h" @@ -81,6 +81,7 @@ __FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_7000.c 330455 2018-03-05 08:0 #define IWM7260_FW "iwm7260fw" #define IWM3160_FW "iwm3160fw" +#define IWM3168_FW "iwm3168fw" #define IWM7265_FW "iwm7265fw" #define IWM7265D_FW "iwm7265Dfw" @@ -113,6 +114,13 @@ const struct iwm_cfg iwm3165_cfg = { .host_interrupt_operation_mode = 0, }; +const struct iwm_cfg iwm3168_cfg = { + .name = "Intel(R) Dual Band Wireless AC 3168", + .fw_name = IWM3168_FW, + IWM_DEVICE_7000_COMMON, + .host_interrupt_operation_mode = 0, +}; + const struct iwm_cfg iwm7265_cfg = { .name = "Intel(R) Dual Band Wireless AC 7265", .fw_name = IWM7265_FW, diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_8000.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_8000.c index 320d894377..b648770fd6 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_8000.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_8000.c @@ -69,7 +69,7 @@ *****************************************************************************/ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_8000.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_8000.c 324434 2017-10-09 15:48:56Z gnn $"); #include "opt_wlan.h" #include "opt_iwm.h" diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_binding.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_binding.c index 64dab3f5a1..48ad9d1196 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_binding.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_binding.c @@ -87,7 +87,7 @@ */ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_binding.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_binding.c 319577 2017-06-04 21:05:58Z adrian $"); #include "opt_wlan.h" #include "opt_iwm.h" @@ -140,6 +140,7 @@ __FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_binding.c 330455 2018-03-05 0 #include #include #include +#include /* * BEGIN iwlwifi/mvm/binding.c @@ -223,14 +224,12 @@ iwm_mvm_binding_add_vif(struct iwm_softc *sc, struct iwm_vap *ivp) if (!ivp->phy_ctxt) return EINVAL; -#ifdef notyet /* * Update SF - Disable if needed. if this fails, SF might still be on * while many macs are bound, which is forbidden - so fail the binding. */ - if (iwm_mvm_sf_update(sc, ivp, FALSE)) + if (iwm_mvm_sf_update(sc, &ivp->iv_vap, FALSE)) return EINVAL; -#endif return iwm_mvm_binding_update(sc, ivp, ivp->phy_ctxt, TRUE); } @@ -245,13 +244,11 @@ iwm_mvm_binding_remove_vif(struct iwm_softc *sc, struct iwm_vap *ivp) ret = iwm_mvm_binding_update(sc, ivp, ivp->phy_ctxt, FALSE); -#ifdef notyet if (!ret) { - if (iwm_mvm_sf_update(sc, ivp, TRUE)) + if (iwm_mvm_sf_update(sc, &ivp->iv_vap, TRUE)) device_printf(sc->sc_dev, "Failed to update SF state\n"); } -#endif return ret; } diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_binding.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_binding.h index ea755bcf70..41514238c8 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_binding.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_binding.h @@ -1,5 +1,5 @@ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_binding.h 330204 2018-03-01 06:36:41Z eadler $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_binding.h 318212 2017-05-12 05:19:08Z adrian $ */ /* * Copyright (c) 2014 genua mbh * Copyright (c) 2014 Fixup Software Ltd. diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_config.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_config.h index a114592c1d..55421422d4 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_config.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_config.h @@ -68,7 +68,7 @@ *****************************************************************************/ /* - * $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_config.h 330227 2018-03-01 06:57:38Z eadler $ + * $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_config.h 331665 2018-03-28 07:59:16Z eadler $ */ #ifndef __IWM_CONFIG_H__ @@ -128,6 +128,7 @@ struct iwm_cfg { extern const struct iwm_cfg iwm7260_cfg; extern const struct iwm_cfg iwm3160_cfg; extern const struct iwm_cfg iwm3165_cfg; +extern const struct iwm_cfg iwm3168_cfg; extern const struct iwm_cfg iwm7265_cfg; extern const struct iwm_cfg iwm7265d_cfg; extern const struct iwm_cfg iwm8260_cfg; diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_constants.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_constants.h index 0d1cf42812..acb6323e91 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_constants.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_constants.h @@ -69,7 +69,7 @@ * *****************************************************************************/ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_constants.h 330201 2018-03-01 06:34:21Z eadler $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_constants.h 318005 2017-05-09 04:15:07Z adrian $ */ #ifndef __IF_IWM_CONSTANTS_H #define __IF_IWM_CONSTANTS_H diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_debug.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_debug.h index 80254a30ea..39c63f21d7 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_debug.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_debug.h @@ -13,7 +13,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_debug.h 330217 2018-03-01 06:47:52Z eadler $ + * $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_debug.h 319578 2017-06-04 21:10:14Z adrian $ */ #ifndef __IF_IWM_DEBUG_H__ @@ -51,7 +51,7 @@ enum { }; #define IWM_DPRINTF(sc, m, fmt, ...) do { \ - if (sc->sc_debug & (m)) \ + if (sc->sc_debug & (m)) \ device_printf(sc->sc_dev, fmt, ##__VA_ARGS__); \ } while (0) #else diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_fw.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_fw.c index a7b087d952..d714d9377b 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_fw.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_fw.c @@ -71,7 +71,7 @@ */ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_fw.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_fw.c 318001 2017-05-09 02:38:23Z adrian $"); #include "opt_wlan.h" #include "opt_iwm.h" diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_fw.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_fw.h index 277674bbb0..90a4666c8b 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_fw.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_fw.h @@ -71,7 +71,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - * $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_fw.h 330192 2018-03-01 06:22:14Z eadler $ + * $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_fw.h 314209 2017-02-24 15:17:43Z adrian $ */ #ifndef __IF_IWM_FW_H__ #define __IF_IWM_FW_H__ diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_led.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_led.c index 21a3a269f5..ce14cdbaf1 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_led.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_led.c @@ -87,7 +87,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_led.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_led.c 318001 2017-05-09 02:38:23Z adrian $"); #include "opt_wlan.h" #include "opt_iwm.h" diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_led.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_led.h index 1b19c23508..acf0a152be 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_led.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_led.h @@ -86,7 +86,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_led.h 303628 2016-08-01 17:51:35Z sbruno $ + * $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_led.h 303327 2016-07-26 00:02:17Z sbruno $ */ #ifndef __IF_IWM_LED_H__ #define __IF_IWM_LED_H__ diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_mac_ctxt.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_mac_ctxt.c index c3d258399f..59b205d5da 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_mac_ctxt.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_mac_ctxt.c @@ -103,7 +103,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_mac_ctxt.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_mac_ctxt.c 318219 2017-05-12 05:50:38Z adrian $"); #include "opt_wlan.h" #include "opt_iwm.h" diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_mac_ctxt.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_mac_ctxt.h index 3a05305685..b0d0c19fd9 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_mac_ctxt.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_mac_ctxt.h @@ -1,5 +1,5 @@ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_mac_ctxt.h 330209 2018-03-01 06:40:08Z eadler $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_mac_ctxt.h 318219 2017-05-12 05:50:38Z adrian $ */ /* * Copyright (c) 2014 genua mbh diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_notif_wait.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_notif_wait.c index 9b98373b49..67ae03b329 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_notif_wait.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_notif_wait.c @@ -67,7 +67,7 @@ *****************************************************************************/ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_notif_wait.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_notif_wait.c 318001 2017-05-09 02:38:23Z adrian $"); #include "opt_wlan.h" #include "opt_iwm.h" diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_notif_wait.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_notif_wait.h index 6a447c65f7..7608fe5151 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_notif_wait.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_notif_wait.h @@ -66,7 +66,7 @@ * *****************************************************************************/ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_notif_wait.h 330170 2018-03-01 05:48:20Z eadler $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_notif_wait.h 313322 2017-02-06 05:27:07Z adrian $ */ #ifndef __IF_IWN_NOTIF_WAIT_H__ #define __IF_IWN_NOTIF_WAIT_H__ diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_pcie_trans.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_pcie_trans.c index 1fb8041c11..6ff4c42b3e 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_pcie_trans.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_pcie_trans.c @@ -103,7 +103,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_pcie_trans.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_pcie_trans.c 318003 2017-05-09 02:42:53Z adrian $"); #include "opt_wlan.h" #include "opt_iwm.h" diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_pcie_trans.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_pcie_trans.h index b34456501d..8fef440e53 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_pcie_trans.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_pcie_trans.h @@ -1,4 +1,4 @@ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_pcie_trans.h 330175 2018-03-01 05:53:12Z eadler $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_pcie_trans.h 313415 2017-02-08 06:53:23Z adrian $ */ /* * Copyright (c) 2014 genua mbh * Copyright (c) 2014 Fixup Software Ltd. diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_ctxt.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_ctxt.c index 2e978ea35c..b3caac60a1 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_ctxt.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_ctxt.c @@ -103,7 +103,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_phy_ctxt.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_phy_ctxt.c 318012 2017-05-09 05:31:38Z adrian $"); #include "opt_wlan.h" #include "opt_iwm.h" diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_ctxt.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_ctxt.h index 827f3365e6..92b828e8b0 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_ctxt.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_ctxt.h @@ -1,5 +1,5 @@ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_phy_ctxt.h 286441 2015-08-08 06:06:48Z rpaulo $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_phy_ctxt.h 286441 2015-08-08 06:06:48Z rpaulo $ */ /* * Copyright (c) 2014 genua mbh diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_db.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_db.c index ad537dbec3..98c42259b4 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_db.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_db.c @@ -103,7 +103,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_phy_db.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_phy_db.c 319581 2017-06-04 21:13:13Z adrian $"); #include "opt_wlan.h" #include "opt_iwm.h" diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_db.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_db.h index 869be68dbc..90dc904708 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_db.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_phy_db.h @@ -1,5 +1,5 @@ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_phy_db.h 330169 2018-03-01 05:46:11Z eadler $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_phy_db.h 313317 2017-02-06 05:09:42Z adrian $ */ /* * Copyright (c) 2014 genua mbh diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_power.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_power.c index acc684496a..1a2773fa36 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_power.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_power.c @@ -87,7 +87,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_power.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_power.c 318228 2017-05-12 06:31:57Z adrian $"); #include "opt_wlan.h" #include "opt_iwm.h" @@ -201,7 +201,7 @@ iwm_mvm_beacon_filter_send_cmd(struct iwm_softc *sc, static void iwm_mvm_beacon_filter_set_cqm_params(struct iwm_softc *sc, - struct iwm_node *in, struct iwm_beacon_filter_cmd *cmd) + struct iwm_vap *ivp, struct iwm_beacon_filter_cmd *cmd) { cmd->ba_enable_beacon_abort = htole32(sc->sc_bf.ba_enabled); } @@ -212,7 +212,7 @@ iwm_mvm_power_log(struct iwm_softc *sc, struct iwm_mac_power_cmd *cmd) IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD, "Sending power table command on mac id 0x%X for " "power level %d, flags = 0x%X\n", - cmd->id_and_color, IWM_POWER_SCHEME_CAM, le16toh(cmd->flags)); + cmd->id_and_color, iwm_power_scheme, le16toh(cmd->flags)); IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD, "Keep alive = %u sec\n", le16toh(cmd->keep_alive_seconds)); @@ -278,15 +278,14 @@ iwm_mvm_power_config_skip_dtim(struct iwm_softc *sc, } static void -iwm_mvm_power_build_cmd(struct iwm_softc *sc, struct iwm_node *in, +iwm_mvm_power_build_cmd(struct iwm_softc *sc, struct iwm_vap *ivp, struct iwm_mac_power_cmd *cmd) { - struct ieee80211_node *ni = &in->in_ni; + struct ieee80211vap *vap = &ivp->iv_vap; + struct ieee80211_node *ni = vap->iv_bss; int dtimper, dtimper_msec; int keep_alive; - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct iwm_vap *ivp = IWM_VAP(vap); + boolean_t bss_conf_ps = FALSE; cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id, ivp->color)); @@ -308,6 +307,14 @@ iwm_mvm_power_build_cmd(struct iwm_softc *sc, struct iwm_node *in, return; cmd->flags |= htole16(IWM_POWER_FLAGS_POWER_SAVE_ENA_MSK); + + if (IWM_NODE(ni)->in_assoc && + (vap->iv_flags & IEEE80211_F_PMGTON) != 0) { + bss_conf_ps = TRUE; + } + if (!bss_conf_ps) + return; + cmd->flags |= htole16(IWM_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); iwm_mvm_power_config_skip_dtim(sc, cmd); @@ -319,11 +326,11 @@ iwm_mvm_power_build_cmd(struct iwm_softc *sc, struct iwm_node *in, } static int -iwm_mvm_power_send_cmd(struct iwm_softc *sc, struct iwm_node *in) +iwm_mvm_power_send_cmd(struct iwm_softc *sc, struct iwm_vap *ivp) { struct iwm_mac_power_cmd cmd = {}; - iwm_mvm_power_build_cmd(sc, in, &cmd); + iwm_mvm_power_build_cmd(sc, ivp, &cmd); iwm_mvm_power_log(sc, &cmd); return iwm_mvm_send_cmd_pdu(sc, IWM_MAC_PM_POWER_TABLE, 0, @@ -331,12 +338,12 @@ iwm_mvm_power_send_cmd(struct iwm_softc *sc, struct iwm_node *in) } static int -_iwm_mvm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_node *in, +_iwm_mvm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_vap *ivp, struct iwm_beacon_filter_cmd *cmd) { int ret; - iwm_mvm_beacon_filter_set_cqm_params(sc, in, cmd); + iwm_mvm_beacon_filter_set_cqm_params(sc, ivp, cmd); ret = iwm_mvm_beacon_filter_send_cmd(sc, cmd); if (!ret) @@ -346,14 +353,14 @@ _iwm_mvm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_node *in, } int -iwm_mvm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_node *in) +iwm_mvm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_vap *ivp) { struct iwm_beacon_filter_cmd cmd = { IWM_BF_CMD_CONFIG_DEFAULTS, .bf_enable_beacon_filter = htole32(1), }; - return _iwm_mvm_enable_beacon_filter(sc, in, &cmd); + return _iwm_mvm_enable_beacon_filter(sc, ivp, &cmd); } int @@ -372,15 +379,18 @@ iwm_mvm_disable_beacon_filter(struct iwm_softc *sc) static int iwm_mvm_power_set_ps(struct iwm_softc *sc) { - struct ieee80211vap *vap = TAILQ_FIRST(&sc->sc_ic.ic_vaps); + struct ieee80211vap *vap; boolean_t disable_ps; int ret; /* disable PS if CAM */ disable_ps = (iwm_power_scheme == IWM_POWER_SCHEME_CAM); /* ...or if any of the vifs require PS to be off */ - if (vap != NULL && (vap->iv_flags & IEEE80211_F_PMGTON) == 0) - disable_ps = TRUE; + TAILQ_FOREACH(vap, &sc->sc_ic.ic_vaps, iv_next) { + struct iwm_vap *ivp = IWM_VAP(vap); + if (ivp->phy_ctxt != NULL && ivp->ps_disabled) + disable_ps = TRUE; + } /* update device power state if it has changed */ if (sc->sc_ps_disabled != disable_ps) { @@ -398,19 +408,26 @@ iwm_mvm_power_set_ps(struct iwm_softc *sc) } static int -iwm_mvm_power_set_ba(struct iwm_softc *sc, struct iwm_node *in) +iwm_mvm_power_set_ba(struct iwm_softc *sc, struct iwm_vap *ivp) { struct iwm_beacon_filter_cmd cmd = { IWM_BF_CMD_CONFIG_DEFAULTS, .bf_enable_beacon_filter = htole32(1), }; + struct ieee80211vap *vap = &ivp->iv_vap; + struct ieee80211_node *ni = vap->iv_bss; + boolean_t bss_conf_ps = FALSE; if (!sc->sc_bf.bf_enabled) return 0; - sc->sc_bf.ba_enabled = !sc->sc_ps_disabled; + if (ni != NULL && IWM_NODE(ni)->in_assoc && + (vap->iv_flags & IEEE80211_F_PMGTON) != 0) { + bss_conf_ps = TRUE; + } + sc->sc_bf.ba_enabled = !sc->sc_ps_disabled && bss_conf_ps; - return _iwm_mvm_enable_beacon_filter(sc, in, &cmd); + return _iwm_mvm_enable_beacon_filter(sc, ivp, &cmd); } int @@ -424,7 +441,7 @@ iwm_mvm_power_update_ps(struct iwm_softc *sc) return ret; if (vap != NULL) - return iwm_mvm_power_set_ba(sc, IWM_NODE(vap->iv_bss)); + return iwm_mvm_power_set_ba(sc, IWM_VAP(vap)); return 0; } @@ -440,13 +457,13 @@ iwm_mvm_power_update_mac(struct iwm_softc *sc) return ret; if (vap != NULL) { - ret = iwm_mvm_power_send_cmd(sc, IWM_NODE(vap->iv_bss)); + ret = iwm_mvm_power_send_cmd(sc, IWM_VAP(vap)); if (ret) return ret; } if (vap != NULL) - return iwm_mvm_power_set_ba(sc, IWM_NODE(vap->iv_bss)); + return iwm_mvm_power_set_ba(sc, IWM_VAP(vap)); return 0; } diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_power.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_power.h index 74857e16cf..95883eba3e 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_power.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_power.h @@ -1,5 +1,5 @@ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_power.h 330201 2018-03-01 06:34:21Z eadler $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_power.h 318226 2017-05-12 06:30:06Z adrian $ */ /* * Copyright (c) 2014 genua mbh @@ -94,7 +94,7 @@ extern int iwm_mvm_power_update_device(struct iwm_softc *sc); extern int iwm_mvm_power_update_mac(struct iwm_softc *sc); extern int iwm_mvm_power_update_ps(struct iwm_softc *sc); extern int iwm_mvm_enable_beacon_filter(struct iwm_softc *sc, - struct iwm_node *in); + struct iwm_vap *ivp); extern int iwm_mvm_disable_beacon_filter(struct iwm_softc *sc); #endif /* __IF_IWM_POWER_H__ */ diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_scan.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_scan.c index b6244bd7ad..a5266b3442 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_scan.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_scan.c @@ -103,7 +103,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_scan.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_scan.c 321507 2017-07-26 05:26:01Z adrian $"); #include "opt_wlan.h" #include "opt_iwm.h" @@ -162,6 +162,9 @@ __FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_scan.c 330455 2018-03-05 08:0 * BEGIN mvm/scan.c */ +#define IWM_DENSE_EBS_SCAN_RATIO 5 +#define IWM_SPARSE_EBS_SCAN_RATIO 1 + static uint16_t iwm_mvm_scan_rx_chain(struct iwm_softc *sc) { @@ -176,6 +179,15 @@ iwm_mvm_scan_rx_chain(struct iwm_softc *sc) return htole16(rx_chain); } +static uint32_t +iwm_mvm_scan_rxon_flags(struct ieee80211_channel *c) +{ + if (IEEE80211_IS_CHAN_2GHZ(c)) + return htole32(IWM_PHY_BAND_24); + else + return htole32(IWM_PHY_BAND_5); +} + static uint32_t iwm_mvm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck) { @@ -199,6 +211,80 @@ iwm_mvm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck) return htole32(IWM_RATE_6M_PLCP | tx_ant); } +static inline boolean_t +iwm_mvm_rrm_scan_needed(struct iwm_softc *sc) +{ + /* require rrm scan whenever the fw supports it */ + return fw_has_capa(&sc->ucode_capa, + IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT); +} + +#ifdef IWM_DEBUG +static const char * +iwm_mvm_ebs_status_str(enum iwm_scan_ebs_status status) +{ + switch (status) { + case IWM_SCAN_EBS_SUCCESS: + return "successful"; + case IWM_SCAN_EBS_INACTIVE: + return "inactive"; + case IWM_SCAN_EBS_FAILED: + case IWM_SCAN_EBS_CHAN_NOT_FOUND: + default: + return "failed"; + } +} + +static const char * +iwm_mvm_offload_status_str(enum iwm_scan_offload_complete_status status) +{ + return (status == IWM_SCAN_OFFLOAD_ABORTED) ? "aborted" : "completed"; +} +#endif + +void +iwm_mvm_rx_lmac_scan_complete_notif(struct iwm_softc *sc, + struct iwm_rx_packet *pkt) +{ + struct iwm_periodic_scan_complete *scan_notif = (void *)pkt->data; + + /* If this happens, the firmware has mistakenly sent an LMAC + * notification during UMAC scans -- warn and ignore it. + */ + if (fw_has_capa(&sc->ucode_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) { + device_printf(sc->sc_dev, + "%s: Mistakenly got LMAC notification during UMAC scan\n", + __func__); + return; + } + + IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Regular scan %s, EBS status %s (FW)\n", + iwm_mvm_offload_status_str(scan_notif->status), + iwm_mvm_ebs_status_str(scan_notif->ebs_status)); + + sc->last_ebs_successful = + scan_notif->ebs_status == IWM_SCAN_EBS_SUCCESS || + scan_notif->ebs_status == IWM_SCAN_EBS_INACTIVE; + +} + +void +iwm_mvm_rx_umac_scan_complete_notif(struct iwm_softc *sc, + struct iwm_rx_packet *pkt) +{ + struct iwm_umac_scan_complete *notif = (void *)pkt->data; + + IWM_DPRINTF(sc, IWM_DEBUG_SCAN, + "Scan completed, uid %u, status %s, EBS status %s\n", + le32toh(notif->uid), + iwm_mvm_offload_status_str(notif->status), + iwm_mvm_ebs_status_str(notif->ebs_status)); + + if (notif->ebs_status != IWM_SCAN_EBS_SUCCESS && + notif->ebs_status != IWM_SCAN_EBS_INACTIVE) + sc->last_ebs_successful = FALSE; +} + static int iwm_mvm_scan_skip_channel(struct ieee80211_channel *c) { @@ -221,15 +307,13 @@ iwm_mvm_lmac_scan_fill_channels(struct iwm_softc *sc, int j; for (nchan = j = 0; - j < ic->ic_nchans && nchan < sc->ucode_capa.n_scan_channels; j++) { - c = &ic->ic_channels[j]; - /* For 2GHz, only populate 11b channels */ - /* For 5GHz, only populate 11a channels */ + j < ss->ss_last && nchan < sc->ucode_capa.n_scan_channels; j++) { + c = ss->ss_chans[j]; /* * Catch other channels, in case we have 900MHz channels or * something in the chanlist. */ - if (iwm_mvm_scan_skip_channel(c)) { + if (!IEEE80211_IS_CHAN_2GHZ(c) && !IEEE80211_IS_CHAN_5GHZ(c)) { IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_EEPROM, "%s: skipping channel (freq=%d, ieee=%d, flags=0x%08x)\n", __func__, c->ic_freq, c->ic_ieee, c->ic_flags); @@ -260,20 +344,19 @@ iwm_mvm_umac_scan_fill_channels(struct iwm_softc *sc, struct iwm_scan_channel_cfg_umac *chan, int n_ssids) { struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_scan_state *ss = ic->ic_scan; struct ieee80211_channel *c; uint8_t nchan; int j; for (nchan = j = 0; - j < ic->ic_nchans && nchan < sc->ucode_capa.n_scan_channels; j++) { - c = &ic->ic_channels[j]; - /* For 2GHz, only populate 11b channels */ - /* For 5GHz, only populate 11a channels */ + j < ss->ss_last && nchan < sc->ucode_capa.n_scan_channels; j++) { + c = ss->ss_chans[j]; /* * Catch other channels, in case we have 900MHz channels or * something in the chanlist. */ - if (iwm_mvm_scan_skip_channel(c)) { + if (!IEEE80211_IS_CHAN_2GHZ(c) && !IEEE80211_IS_CHAN_5GHZ(c)) { IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_EEPROM, "%s: skipping channel (freq=%d, ieee=%d, flags=0x%08x)\n", __func__, c->ic_freq, c->ic_ieee, c->ic_flags); @@ -347,8 +430,7 @@ iwm_mvm_fill_probe_req(struct iwm_softc *sc, struct iwm_scan_probe_req *preq) preq->band_data[0].len = htole16(frm - pos); remain -= frm - pos; - if (fw_has_capa(&sc->ucode_capa, - IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT)) { + if (iwm_mvm_rrm_scan_needed(sc)) { if (remain < 3) return ENOBUFS; *frm++ = IEEE80211_ELEMID_DSPARMS; @@ -481,6 +563,21 @@ iwm_mvm_config_umac_scan(struct iwm_softc *sc) return ret; } +static boolean_t +iwm_mvm_scan_use_ebs(struct iwm_softc *sc) +{ + const struct iwm_ucode_capabilities *capa = &sc->ucode_capa; + + /* We can only use EBS if: + * 1. the feature is supported; + * 2. the last EBS was successful; + * 3. if only single scan, the single scan EBS API is supported; + * 4. it's not a p2p find operation. + */ + return ((capa->flags & IWM_UCODE_TLV_FLAGS_EBS_SUPPORT) && + sc->last_ebs_successful); +} + int iwm_mvm_umac_scan(struct iwm_softc *sc) { @@ -550,8 +647,12 @@ iwm_mvm_umac_scan(struct iwm_softc *sc) } else req->general_flags |= htole32(IWM_UMAC_SCAN_GEN_FLAGS_PASSIVE); - if (fw_has_capa(&sc->ucode_capa, - IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT)) + if (iwm_mvm_scan_use_ebs(sc)) + req->channel_flags = IWM_SCAN_CHANNEL_FLAG_EBS | + IWM_SCAN_CHANNEL_FLAG_EBS_ACCURATE | + IWM_SCAN_CHANNEL_FLAG_CACHE_ADD; + + if (iwm_mvm_rrm_scan_needed(sc)) req->general_flags |= htole32(IWM_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED); @@ -619,13 +720,11 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc) req->scan_flags = htole32(IWM_MVM_LMAC_SCAN_FLAG_PASS_ALL | IWM_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE | IWM_MVM_LMAC_SCAN_FLAG_EXTENDED_DWELL); - if (fw_has_capa(&sc->ucode_capa, - IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT)) + if (iwm_mvm_rrm_scan_needed(sc)) req->scan_flags |= htole32(IWM_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); - req->flags = htole32(IWM_PHY_BAND_24); - if (sc->nvm_data->sku_cap_band_52GHz_enable) - req->flags |= htole32(IWM_PHY_BAND_5); + req->flags = iwm_mvm_scan_rxon_flags(sc->sc_ic.ic_scan->ss_chans[0]); + req->filter_flags = htole32(IWM_MAC_FILTER_ACCEPT_GRP | IWM_MAC_FILTER_IN_BEACON); @@ -675,9 +774,20 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc) req->schedule[0].iterations = 1; req->schedule[0].full_scan_mul = 1; - /* Disable EBS. */ - req->channel_opt[0].non_ebs_ratio = 1; - req->channel_opt[1].non_ebs_ratio = 1; + if (iwm_mvm_scan_use_ebs(sc)) { + req->channel_opt[0].flags = + htole16(IWM_SCAN_CHANNEL_FLAG_EBS | + IWM_SCAN_CHANNEL_FLAG_EBS_ACCURATE | + IWM_SCAN_CHANNEL_FLAG_CACHE_ADD); + req->channel_opt[0].non_ebs_ratio = + htole16(IWM_DENSE_EBS_SCAN_RATIO); + req->channel_opt[1].flags = + htole16(IWM_SCAN_CHANNEL_FLAG_EBS | + IWM_SCAN_CHANNEL_FLAG_EBS_ACCURATE | + IWM_SCAN_CHANNEL_FLAG_CACHE_ADD); + req->channel_opt[1].non_ebs_ratio = + htole16(IWM_SPARSE_EBS_SCAN_RATIO); + } ret = iwm_send_cmd(sc, &hcmd); if (!ret) { diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_scan.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_scan.h index db59d53782..586e3f2f6f 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_scan.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_scan.h @@ -1,5 +1,5 @@ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_scan.h 330173 2018-03-01 05:51:35Z eadler $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_scan.h 315925 2017-03-25 02:49:20Z adrian $ */ /* * Copyright (c) 2014 genua mbh @@ -106,9 +106,13 @@ #ifndef __IF_IWN_SCAN_H__ #define __IF_IWN_SCAN_H__ -extern int iwm_mvm_lmac_scan(struct iwm_softc *sc); +extern int iwm_mvm_lmac_scan(struct iwm_softc *); extern int iwm_mvm_config_umac_scan(struct iwm_softc *); extern int iwm_mvm_umac_scan(struct iwm_softc *); -extern int iwm_mvm_scan_stop_wait(struct iwm_softc *sc); +extern int iwm_mvm_scan_stop_wait(struct iwm_softc *); +extern void iwm_mvm_rx_lmac_scan_complete_notif(struct iwm_softc *, + struct iwm_rx_packet *); +extern void iwm_mvm_rx_umac_scan_complete_notif(struct iwm_softc *, + struct iwm_rx_packet *); #endif /* __IF_IWN_SCAN_H__ */ diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sf.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sf.c new file mode 100644 index 0000000000..9183535e8f --- /dev/null +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sf.c @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2014 genua mbh + * Copyright (c) 2014 Fixup Software Ltd. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*- + * Based on BSD-licensed source modules in the Linux iwlwifi driver, + * which were used as the reference documentation for this implementation. + * + * Driver version we are currently based off of is + * Linux 4.7.3 (tag id d7f6728f57e3ecbb7ef34eb7d9f564d514775d75) + * + ****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#include +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_sf.c 319580 2017-06-04 21:12:11Z adrian $"); + +#include "opt_wlan.h" +#include "opt_iwm.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * Aging and idle timeouts for the different possible scenarios + * in default configuration + */ +static const uint32_t +sf_full_timeout_def[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = { + { + htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER_DEF), + htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER_DEF) + }, + { + htole32(IWM_SF_AGG_UNICAST_AGING_TIMER_DEF), + htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER_DEF) + }, + { + htole32(IWM_SF_MCAST_AGING_TIMER_DEF), + htole32(IWM_SF_MCAST_IDLE_TIMER_DEF) + }, + { + htole32(IWM_SF_BA_AGING_TIMER_DEF), + htole32(IWM_SF_BA_IDLE_TIMER_DEF) + }, + { + htole32(IWM_SF_TX_RE_AGING_TIMER_DEF), + htole32(IWM_SF_TX_RE_IDLE_TIMER_DEF) + }, +}; + +/* + * Aging and idle timeouts for the different possible scenarios + * in single BSS MAC configuration. + */ +static const uint32_t +sf_full_timeout[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = { + { + htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER), + htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER) + }, + { + htole32(IWM_SF_AGG_UNICAST_AGING_TIMER), + htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER) + }, + { + htole32(IWM_SF_MCAST_AGING_TIMER), + htole32(IWM_SF_MCAST_IDLE_TIMER) + }, + { + htole32(IWM_SF_BA_AGING_TIMER), + htole32(IWM_SF_BA_IDLE_TIMER) + }, + { + htole32(IWM_SF_TX_RE_AGING_TIMER), + htole32(IWM_SF_TX_RE_IDLE_TIMER) + }, +}; + +static void +iwm_mvm_fill_sf_command(struct iwm_softc *sc, struct iwm_sf_cfg_cmd *sf_cmd, + struct ieee80211_node *ni) +{ + int i, j, watermark; + + sf_cmd->watermark[IWM_SF_LONG_DELAY_ON] = htole32(IWM_SF_W_MARK_SCAN); + + /* + * If we are in association flow - check antenna configuration + * capabilities of the AP station, and choose the watermark accordingly. + */ + if (ni) { + if (ni->ni_flags & IEEE80211_NODE_HT) { + watermark = IWM_SF_W_MARK_SISO; + } else { + watermark = IWM_SF_W_MARK_LEGACY; + } + /* default watermark value for unassociated mode. */ + } else { + watermark = IWM_SF_W_MARK_MIMO2; + } + sf_cmd->watermark[IWM_SF_FULL_ON] = htole32(watermark); + + for (i = 0; i < IWM_SF_NUM_SCENARIO; i++) { + for (j = 0; j < IWM_SF_NUM_TIMEOUT_TYPES; j++) { + sf_cmd->long_delay_timeouts[i][j] = + htole32(IWM_SF_LONG_DELAY_AGING_TIMER); + } + } + + if (ni) { + _Static_assert(sizeof(sf_full_timeout) == sizeof(uint32_t) * + IWM_SF_NUM_SCENARIO * IWM_SF_NUM_TIMEOUT_TYPES, + "sf_full_timeout has wrong size"); + + memcpy(sf_cmd->full_on_timeouts, sf_full_timeout, + sizeof(sf_full_timeout)); + } else { + _Static_assert(sizeof(sf_full_timeout_def) == sizeof(uint32_t) * + IWM_SF_NUM_SCENARIO * IWM_SF_NUM_TIMEOUT_TYPES, + "sf_full_timeout_def has wrong size"); + + memcpy(sf_cmd->full_on_timeouts, sf_full_timeout_def, + sizeof(sf_full_timeout_def)); + } +} + +static int +iwm_mvm_sf_config(struct iwm_softc *sc, struct ieee80211_node *ni, + enum iwm_sf_state new_state) +{ + struct iwm_sf_cfg_cmd sf_cmd = { + .state = htole32(new_state), + }; + int ret = 0; + +#ifdef notyet /* only relevant for sdio variants */ + if (sc->cfg->disable_dummy_notification) + sf_cmd.state |= htole32(IWM_SF_CFG_DUMMY_NOTIF_OFF); +#endif + + /* + * If an associated AP sta changed its antenna configuration, the state + * will remain FULL_ON but SF parameters need to be reconsidered. + */ + if (new_state != IWM_SF_FULL_ON && sc->sf_state == new_state) + return 0; + + switch (new_state) { + case IWM_SF_UNINIT: + iwm_mvm_fill_sf_command(sc, &sf_cmd, NULL); + break; + case IWM_SF_FULL_ON: + iwm_mvm_fill_sf_command(sc, &sf_cmd, ni); + break; + case IWM_SF_INIT_OFF: + iwm_mvm_fill_sf_command(sc, &sf_cmd, NULL); + break; + default: + device_printf(sc->sc_dev, + "Invalid state: %d. not sending Smart Fifo cmd\n", + new_state); + return EINVAL; + } + + ret = iwm_mvm_send_cmd_pdu(sc, IWM_REPLY_SF_CFG_CMD, IWM_CMD_ASYNC, + sizeof(sf_cmd), &sf_cmd); + if (!ret) + sc->sf_state = new_state; + + return ret; +} + +/* + * Update Smart fifo: + * Count bound interfaces that are not to be removed, ignoring p2p devices, + * and set new state accordingly. + */ +int +iwm_mvm_sf_update(struct iwm_softc *sc, struct ieee80211vap *changed_vif, + boolean_t remove_vif) +{ + enum iwm_sf_state new_state; + struct ieee80211_node *ni = NULL; + int num_active_macs = 0; + + /* If changed_vif exists and is not to be removed, add to the count */ + if (changed_vif && !remove_vif) + num_active_macs++; + + switch (num_active_macs) { + case 0: + /* If there are no active macs - change state to SF_INIT_OFF */ + new_state = IWM_SF_INIT_OFF; + break; + case 1: + if (!changed_vif) + return EINVAL; + ni = changed_vif->iv_bss; + if (ni != NULL && IWM_NODE(ni)->in_assoc && + changed_vif->iv_dtim_period) { + new_state = IWM_SF_FULL_ON; + } else { + new_state = IWM_SF_INIT_OFF; + } + break; + default: + /* If there are multiple active macs - change to SF_UNINIT */ + new_state = IWM_SF_UNINIT; + } + return iwm_mvm_sf_config(sc, ni, new_state); +} diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sf.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sf.h new file mode 100644 index 0000000000..78cfa80cbd --- /dev/null +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sf.h @@ -0,0 +1,82 @@ +/*- + * Based on BSD-licensed source modules in the Linux iwlwifi driver, + * which were used as the reference documentation for this implementation. + * + * Driver version we are currently based off of is + * Linux 4.7.3 (tag id d7f6728f57e3ecbb7ef34eb7d9f564d514775d75) + * + *********************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2016 Intel Deutschland GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2016 Intel Deutschland GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_sf.h 319577 2017-06-04 21:05:58Z adrian $ + */ +#ifndef __IF_IWM_SF_H__ +#define __IF_IWM_SF_H__ + +extern int iwm_mvm_sf_update(struct iwm_softc *sc, + struct ieee80211vap *changed_vif, + boolean_t remove_vif); + +#endif /* __IF_IWM_SF_H__ */ diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sta.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sta.c index b54c6790d6..1482074aae 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sta.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sta.c @@ -73,7 +73,7 @@ *****************************************************************************/ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_sta.c 330223 2018-03-01 06:55:46Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_sta.c 321508 2017-07-26 05:29:08Z adrian $"); #include "opt_wlan.h" #include "opt_iwm.h" diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sta.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sta.h index 31cb170312..225d6927a9 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sta.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_sta.h @@ -73,7 +73,7 @@ * *****************************************************************************/ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_sta.h 330213 2018-03-01 06:44:32Z eadler $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_sta.h 318229 2017-05-12 06:33:07Z adrian $ */ #ifndef __IF_IWM_STA_H__ #define __IF_IWM_STA_H__ diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_time_event.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_time_event.c index be77ac0415..0d2b491acc 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_time_event.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_time_event.c @@ -103,7 +103,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_time_event.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_time_event.c 318212 2017-05-12 05:19:08Z adrian $"); #include "opt_wlan.h" #include "opt_iwm.h" diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_time_event.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_time_event.h index df007e3b90..e9f5937611 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_time_event.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_time_event.h @@ -1,5 +1,5 @@ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_time_event.h 330204 2018-03-01 06:36:41Z eadler $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_time_event.h 318212 2017-05-12 05:19:08Z adrian $ */ /* * Copyright (c) 2014 genua mbh diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_util.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_util.c index 4c1f2c3238..c698d9269c 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_util.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_util.c @@ -103,7 +103,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include -__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_util.c 330455 2018-03-05 08:05:30Z eadler $"); +__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_util.c 321510 2017-07-26 05:51:31Z adrian $"); #include "opt_wlan.h" #include "opt_iwm.h" @@ -225,12 +225,11 @@ iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd) } if (paylen > datasz) { - size_t totlen; IWM_DPRINTF(sc, IWM_DEBUG_CMD, "large command paylen=%u len0=%u\n", paylen, hcmd->len[0]); /* Command is too large */ - totlen = hdrlen + paylen; + size_t totlen = hdrlen + paylen; if (paylen > IWM_MAX_CMD_PAYLOAD_SIZE) { device_printf(sc->sc_dev, "firmware command too long (%zd bytes)\n", diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_util.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_util.h index 5e5c81330e..60eb8e7afe 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_util.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwm_util.h @@ -1,5 +1,5 @@ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwm_util.h 330225 2018-03-01 06:56:34Z eadler $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_util.h 321510 2017-07-26 05:51:31Z adrian $ */ /* * Copyright (c) 2014 genua mbh diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwmreg.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwmreg.h index bd9c0029bc..8a1bc9493b 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwmreg.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwmreg.h @@ -1,5 +1,5 @@ /* $OpenBSD: if_iwmreg.h,v 1.4 2015/06/15 08:06:11 stsp Exp $ */ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwmreg.h 330446 2018-03-05 06:59:30Z eadler $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwmreg.h 327231 2017-12-27 03:23:21Z eadler $ */ /****************************************************************************** * @@ -844,7 +844,7 @@ struct iwm_fw_cipher_scheme { */ struct iwm_fw_cscheme_list { uint8_t size; - struct iwm_fw_cipher_scheme cs[0]; + struct iwm_fw_cipher_scheme cs[]; } __packed; /* @@ -2012,7 +2012,7 @@ struct iwm_nvm_access_cmd { uint16_t type; uint16_t offset; uint16_t length; - uint8_t data[0]; + uint8_t data[]; } __packed; /* IWM_NVM_ACCESS_CMD_API_S_VER_2 */ #define IWM_NUM_OF_FW_PAGING_BLOCKS 33 /* 32 for data and 1 block for CSS */ @@ -2066,7 +2066,7 @@ struct iwm_nvm_access_resp { uint16_t length; uint16_t type; uint16_t status; - uint8_t data[0]; + uint8_t data[]; } __packed; /* IWM_NVM_ACCESS_CMD_RESP_API_S_VER_2 */ /* IWM_MVM_ALIVE 0x1 */ @@ -4932,7 +4932,7 @@ struct iwm_scan_req_lmac { uint32_t delay; struct iwm_scan_schedule_lmac schedule[IWM_MAX_SCHED_SCAN_PLANS]; struct iwm_scan_channel_opt channel_opt[2]; - uint8_t data[0]; + uint8_t data[]; } __packed; /** @@ -5082,6 +5082,13 @@ enum iwm_scan_offload_complete_status { IWM_SCAN_OFFLOAD_ABORTED = 2, }; +enum iwm_scan_ebs_status { + IWM_SCAN_EBS_SUCCESS, + IWM_SCAN_EBS_FAILED, + IWM_SCAN_EBS_CHAN_NOT_FOUND, + IWM_SCAN_EBS_INACTIVE, +}; + /** * struct iwm_lmac_scan_complete_notif - notifies end of scanning (all channels) * SCAN_COMPLETE_NTF_API_S_VER_3 @@ -5100,7 +5107,7 @@ struct iwm_lmac_scan_complete_notif { uint8_t last_channel; uint32_t tsf_low; uint32_t tsf_high; - struct iwm_scan_results_notif results[0]; + struct iwm_scan_results_notif results[]; } __packed; @@ -5203,7 +5210,7 @@ struct iwm_scan_config { uint8_t mac_addr[IEEE80211_ADDR_LEN]; uint8_t bcast_sta_id; uint8_t channel_flags; - uint8_t channel_array[0]; + uint8_t channel_array[]; } __packed; /* SCAN_CONFIG_DB_CMD_API_S */ /** @@ -5322,7 +5329,7 @@ struct iwm_scan_req_umac { uint8_t channel_flags; uint8_t n_channels; uint16_t reserved; - uint8_t data[0]; + uint8_t data[]; } __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_1 */ /** @@ -5419,7 +5426,7 @@ struct iwm_umac_scan_iter_complete_notif { uint8_t last_channel; uint32_t tsf_low; uint32_t tsf_high; - struct iwm_scan_results_notif results[0]; + struct iwm_scan_results_notif results[]; } __packed; /* SCAN_ITER_COMPLETE_NTF_UMAC_API_S_VER_1 */ /* Please keep this enum *SORTED* by hex value. @@ -6086,7 +6093,7 @@ struct iwm_rx_packet { */ uint32_t len_n_flags; struct iwm_cmd_header hdr; - uint8_t data[0]; + uint8_t data[]; } __packed; #define IWM_FH_RSCSR_FRAME_SIZE_MSK 0x00003fff diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwmvar.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwmvar.h index 8d2e701951..d41818fdc0 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwmvar.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/iwm/if_iwmvar.h @@ -1,5 +1,5 @@ /* $OpenBSD: if_iwmvar.h,v 1.7 2015/03/02 13:51:10 jsg Exp $ */ -/* $FreeBSD: releng/11.2/sys/dev/iwm/if_iwmvar.h 330224 2018-03-01 06:56:10Z eadler $ */ +/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwmvar.h 321509 2017-07-26 05:40:52Z adrian $ */ /* * Copyright (c) 2014 genua mbh @@ -233,7 +233,7 @@ struct iwm_nvm_data { uint8_t max_tx_pwr_half_dbm; boolean_t lar_enabled; - uint16_t nvm_ch_flags[0]; + uint16_t nvm_ch_flags[]; }; /* max bufs per tfd the driver will use */ @@ -391,6 +391,9 @@ struct iwm_vap { uint16_t edca_txop; uint8_t aifsn; } queue_params[WME_NUM_AC]; + + /* indicates that this interface requires PS to be disabled */ + boolean_t ps_disabled; }; #define IWM_VAP(_vap) ((struct iwm_vap *)(_vap)) @@ -554,11 +557,18 @@ struct iwm_softc { uint16_t num_of_paging_blk; uint16_t num_of_pages_in_last_blk; + boolean_t last_ebs_successful; + + /* last smart fifo state that was successfully sent to firmware */ + enum iwm_sf_state sf_state; + /* Indicate if device power save is allowed */ boolean_t sc_ps_disabled; +#ifdef __HAIKU__ uint32_t sc_intr_status_1; uint32_t sc_intr_status_2; +#endif }; #define IWM_LOCK_INIT(_sc) \