idualwifi7260: Port changes from newer FreeBSD.

This adds support for the 9xxx series of devices.

Change-Id: I43385e91b91201732397b79c38bd9bb4f3a18f1b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2733
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Augustin Cavalier
2020-05-17 23:34:32 +00:00
committed by waddlesplash
parent a3a192c1cb
commit ba5694b017
42 changed files with 1856 additions and 964 deletions
@@ -18,6 +18,8 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) dev iwm ] ;
KernelAddon idualwifi7260 : KernelAddon idualwifi7260 :
if_iwm_7000.c if_iwm_7000.c
if_iwm_8000.c if_iwm_8000.c
if_iwm_9000.c
if_iwm_9260.c
if_iwm_binding.c if_iwm_binding.c
if_iwm_fw.c if_iwm_fw.c
if_iwm_led.c if_iwm_led.c
@@ -42,9 +44,11 @@ KernelAddon idualwifi7260 :
HAIKU_WIFI_FIRMWARE_PACKAGES on idualwifi7260 = HAIKU_WIFI_FIRMWARE_PACKAGES on idualwifi7260 =
iwm-3160-ucode-17 iwm-3168-ucode-22 iwm-3160-ucode-17 iwm-3168-ucode-22
iwm-7260-ucode-17 iwm-7265-ucode-17 iwm-7265D-ucode-22 iwm-7260-ucode-17 iwm-7265-ucode-17 iwm-7265D-ucode-22
iwm-8000C-ucode-22 iwm-8265-ucode-22 ; iwm-8000C-ucode-22 iwm-8265-ucode-22
iwm-9000-ucode-34 iwm-9260-ucode-34 ;
HAIKU_WIFI_FIRMWARE_ARCHIVES on idualwifi7260 = HAIKU_WIFI_FIRMWARE_ARCHIVES on idualwifi7260 =
iwm-3160-ucode-17.tgz iwm-3168-ucode-22.tgz iwm-3160-ucode-17.tgz iwm-3168-ucode-22.tgz
iwm-7260-ucode-17.tgz iwm-7265-ucode-17.tgz iwm-7265D-ucode-22.tgz iwm-7260-ucode-17.tgz iwm-7265-ucode-17.tgz iwm-7265D-ucode-22.tgz
iwm-8000C-ucode-22.tgz iwm-8265-ucode-22.tgz ; iwm-8000C-ucode-22.tgz iwm-8265-ucode-22.tgz
iwm-9000-ucode-34.tgz iwm-9260-ucode-34.tgz ;
HAIKU_WIFI_FIRMWARE_DO_EXTRACT on idualwifi7260 = true ; HAIKU_WIFI_FIRMWARE_DO_EXTRACT on idualwifi7260 = true ;
File diff suppressed because it is too large Load Diff
@@ -70,7 +70,7 @@
*****************************************************************************/ *****************************************************************************/
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_7000.c 331665 2018-03-28 07:59:16Z eadler $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -119,6 +119,7 @@ const struct iwm_cfg iwm3168_cfg = {
.fw_name = IWM3168_FW, .fw_name = IWM3168_FW,
IWM_DEVICE_7000_COMMON, IWM_DEVICE_7000_COMMON,
.host_interrupt_operation_mode = 0, .host_interrupt_operation_mode = 0,
.nvm_type = IWM_NVM_SDP,
}; };
const struct iwm_cfg iwm7265_cfg = { const struct iwm_cfg iwm7265_cfg = {
@@ -69,7 +69,7 @@
*****************************************************************************/ *****************************************************************************/
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_8000.c 324434 2017-10-09 15:48:56Z gnn $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -0,0 +1,97 @@
/*-
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
* which were used as the reference documentation for this implementation.
*
******************************************************************************
*
* 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) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 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 <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_wlan.h"
#include "opt_iwm.h"
#include <sys/param.h>
#include "if_iwm_config.h"
#define IWM9000_FW "iwm9000fw"
#define IWM_NVM_HW_SECTION_NUM_FAMILY_9000 10
#define IWM_DEVICE_9000_COMMON \
.device_family = IWM_DEVICE_FAMILY_9000, \
.eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_9000, \
.nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_9000
const struct iwm_cfg iwm9560_cfg = {
.name = "Intel(R) Dual Band Wireless AC 9560",
.fw_name = IWM9000_FW,
IWM_DEVICE_9000_COMMON,
.host_interrupt_operation_mode = 0,
.mqrx_supported = 1,
.integrated = 1,
};
@@ -0,0 +1,96 @@
/*-
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
* which were used as the reference documentation for this implementation.
*
******************************************************************************
*
* 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) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 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 <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_wlan.h"
#include "opt_iwm.h"
#include <sys/param.h>
#include "if_iwm_config.h"
#define IWM9260_FW "iwm9260fw"
#define IWM_NVM_HW_SECTION_NUM_FAMILY_9260 10
#define IWM_DEVICE_9260_COMMON \
.device_family = IWM_DEVICE_FAMILY_9000, \
.eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_9000, \
.nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_9260
const struct iwm_cfg iwm9260_cfg = {
.name = "Intel(R) Dual Band Wireless AC 9260",
.fw_name = IWM9260_FW,
IWM_DEVICE_9260_COMMON,
.host_interrupt_operation_mode = 0,
.mqrx_supported = 1,
};
@@ -87,7 +87,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_binding.c 319577 2017-06-04 21:05:58Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -146,21 +146,21 @@ __FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_binding.c 319577 2017-06-04 2
* BEGIN iwlwifi/mvm/binding.c * BEGIN iwlwifi/mvm/binding.c
*/ */
struct iwm_mvm_iface_iterator_data { struct iwm_iface_iterator_data {
int idx; int idx;
struct iwm_mvm_phy_ctxt *phyctxt; struct iwm_phy_ctxt *phyctxt;
uint16_t ids[IWM_MAX_MACS_IN_BINDING]; uint16_t ids[IWM_MAX_MACS_IN_BINDING];
int16_t colors[IWM_MAX_MACS_IN_BINDING]; int16_t colors[IWM_MAX_MACS_IN_BINDING];
}; };
static int static int
iwm_mvm_binding_cmd(struct iwm_softc *sc, uint32_t action, iwm_binding_cmd(struct iwm_softc *sc, uint32_t action,
struct iwm_mvm_iface_iterator_data *data) struct iwm_iface_iterator_data *data)
{ {
struct iwm_binding_cmd cmd; struct iwm_binding_cmd cmd;
struct iwm_mvm_phy_ctxt *phyctxt = data->phyctxt; struct iwm_phy_ctxt *phyctxt = data->phyctxt;
int i, ret; int i, ret;
uint32_t status; uint32_t status;
@@ -178,7 +178,7 @@ iwm_mvm_binding_cmd(struct iwm_softc *sc, uint32_t action,
data->colors[i])); data->colors[i]));
status = 0; status = 0;
ret = iwm_mvm_send_cmd_pdu_status(sc, IWM_BINDING_CONTEXT_CMD, ret = iwm_send_cmd_pdu_status(sc, IWM_BINDING_CONTEXT_CMD,
sizeof(cmd), &cmd, &status); sizeof(cmd), &cmd, &status);
if (ret) { if (ret) {
device_printf(sc->sc_dev, device_printf(sc->sc_dev,
@@ -196,10 +196,10 @@ iwm_mvm_binding_cmd(struct iwm_softc *sc, uint32_t action,
} }
static int static int
iwm_mvm_binding_update(struct iwm_softc *sc, struct iwm_vap *ivp, iwm_binding_update(struct iwm_softc *sc, struct iwm_vap *ivp,
struct iwm_mvm_phy_ctxt *phyctxt, boolean_t add) struct iwm_phy_ctxt *phyctxt, boolean_t add)
{ {
struct iwm_mvm_iface_iterator_data data = { struct iwm_iface_iterator_data data = {
.phyctxt = phyctxt, .phyctxt = phyctxt,
}; };
uint32_t action; uint32_t action;
@@ -215,11 +215,11 @@ iwm_mvm_binding_update(struct iwm_softc *sc, struct iwm_vap *ivp,
data.idx++; data.idx++;
} }
return iwm_mvm_binding_cmd(sc, action, &data); return iwm_binding_cmd(sc, action, &data);
} }
int int
iwm_mvm_binding_add_vif(struct iwm_softc *sc, struct iwm_vap *ivp) iwm_binding_add_vif(struct iwm_softc *sc, struct iwm_vap *ivp)
{ {
if (!ivp->phy_ctxt) if (!ivp->phy_ctxt)
return EINVAL; return EINVAL;
@@ -228,24 +228,24 @@ iwm_mvm_binding_add_vif(struct iwm_softc *sc, struct iwm_vap *ivp)
* Update SF - Disable if needed. if this fails, SF might still be on * 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. * while many macs are bound, which is forbidden - so fail the binding.
*/ */
if (iwm_mvm_sf_update(sc, &ivp->iv_vap, FALSE)) if (iwm_sf_update(sc, &ivp->iv_vap, FALSE))
return EINVAL; return EINVAL;
return iwm_mvm_binding_update(sc, ivp, ivp->phy_ctxt, TRUE); return iwm_binding_update(sc, ivp, ivp->phy_ctxt, TRUE);
} }
int int
iwm_mvm_binding_remove_vif(struct iwm_softc *sc, struct iwm_vap *ivp) iwm_binding_remove_vif(struct iwm_softc *sc, struct iwm_vap *ivp)
{ {
int ret; int ret;
if (!ivp->phy_ctxt) if (!ivp->phy_ctxt)
return EINVAL; return EINVAL;
ret = iwm_mvm_binding_update(sc, ivp, ivp->phy_ctxt, FALSE); ret = iwm_binding_update(sc, ivp, ivp->phy_ctxt, FALSE);
if (!ret) { if (!ret) {
if (iwm_mvm_sf_update(sc, &ivp->iv_vap, TRUE)) if (iwm_sf_update(sc, &ivp->iv_vap, TRUE))
device_printf(sc->sc_dev, device_printf(sc->sc_dev,
"Failed to update SF state\n"); "Failed to update SF state\n");
} }
@@ -1,5 +1,5 @@
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_binding.h 318212 2017-05-12 05:19:08Z adrian $ */ /* $FreeBSD$ */
/* /*
* Copyright (c) 2014 genua mbh <info@genua.de> * Copyright (c) 2014 genua mbh <info@genua.de>
* Copyright (c) 2014 Fixup Software Ltd. * Copyright (c) 2014 Fixup Software Ltd.
@@ -105,7 +105,7 @@
#ifndef __IF_IWM_BINDING_H__ #ifndef __IF_IWM_BINDING_H__
#define __IF_IWM_BINDING_H__ #define __IF_IWM_BINDING_H__
extern int iwm_mvm_binding_add_vif(struct iwm_softc *sc, struct iwm_vap *ivp); extern int iwm_binding_add_vif(struct iwm_softc *sc, struct iwm_vap *ivp);
extern int iwm_mvm_binding_remove_vif(struct iwm_softc *sc, struct iwm_vap *ivp); extern int iwm_binding_remove_vif(struct iwm_softc *sc, struct iwm_vap *ivp);
#endif /* __IF_IWM_BINDING_H__ */ #endif /* __IF_IWM_BINDING_H__ */
@@ -68,7 +68,7 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_config.h 331665 2018-03-28 07:59:16Z eadler $ * $FreeBSD$
*/ */
#ifndef __IWM_CONFIG_H__ #ifndef __IWM_CONFIG_H__
@@ -78,6 +78,7 @@ enum iwm_device_family {
IWM_DEVICE_FAMILY_UNDEFINED, IWM_DEVICE_FAMILY_UNDEFINED,
IWM_DEVICE_FAMILY_7000, IWM_DEVICE_FAMILY_7000,
IWM_DEVICE_FAMILY_8000, IWM_DEVICE_FAMILY_8000,
IWM_DEVICE_FAMILY_9000,
}; };
#define IWM_DEFAULT_MAX_TX_POWER 22 #define IWM_DEFAULT_MAX_TX_POWER 22
@@ -104,6 +105,19 @@ static inline uint8_t num_of_ant(uint8_t mask)
#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000 (32 * 512 * sizeof(uint16_t)) /* 32 KB */ #define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000 (32 * 512 * sizeof(uint16_t)) /* 32 KB */
#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_9000 IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000 #define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_9000 IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000
/**
* enum iwl_nvm_type - nvm formats
* @IWM_NVM: the regular format
* @IWM_NVM_EXT: extended NVM format
* @IWM_NVM_SDP: NVM format used by 3168 series
*/
enum iwm_nvm_type {
IWM_NVM,
IWM_NVM_EXT,
IWM_NVM_SDP,
};
/** /**
* struct iwm_cfg * struct iwm_cfg
* @name: Official name of the device * @name: Official name of the device
@@ -113,6 +127,7 @@ static inline uint8_t num_of_ant(uint8_t mask)
* @nvm_hw_section_num: the ID of the HW NVM section * @nvm_hw_section_num: the ID of the HW NVM section
* @apmg_wake_up_wa: should the MAC access REQ be asserted when a command * @apmg_wake_up_wa: should the MAC access REQ be asserted when a command
* is in flight. This is due to a HW bug in 7260, 3160 and 7265. * is in flight. This is due to a HW bug in 7260, 3160 and 7265.
* @nvm_type: see &enum iwl_nvm_type
*/ */
struct iwm_cfg { struct iwm_cfg {
const char *name; const char *name;
@@ -120,8 +135,11 @@ struct iwm_cfg {
uint16_t eeprom_size; uint16_t eeprom_size;
enum iwm_device_family device_family; enum iwm_device_family device_family;
int host_interrupt_operation_mode; int host_interrupt_operation_mode;
int mqrx_supported;
int integrated;
uint8_t nvm_hw_section_num; uint8_t nvm_hw_section_num;
int apmg_wake_up_wa; int apmg_wake_up_wa;
enum iwm_nvm_type nvm_type;
}; };
/* /*
@@ -135,5 +153,7 @@ extern const struct iwm_cfg iwm7265_cfg;
extern const struct iwm_cfg iwm7265d_cfg; extern const struct iwm_cfg iwm7265d_cfg;
extern const struct iwm_cfg iwm8260_cfg; extern const struct iwm_cfg iwm8260_cfg;
extern const struct iwm_cfg iwm8265_cfg; extern const struct iwm_cfg iwm8265_cfg;
extern const struct iwm_cfg iwm9560_cfg;
extern const struct iwm_cfg iwm9260_cfg;
#endif /* __IWM_CONFIG_H__ */ #endif /* __IWM_CONFIG_H__ */
@@ -69,86 +69,86 @@
* *
*****************************************************************************/ *****************************************************************************/
/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_constants.h 318005 2017-05-09 04:15:07Z adrian $ */ /* $FreeBSD$ */
#ifndef __IF_IWM_CONSTANTS_H #ifndef __IF_IWM_CONSTANTS_H
#define __IF_IWM_CONSTANTS_H #define __IF_IWM_CONSTANTS_H
/* <netproto/802_11/ieee80211_var.h> */ /* <netproto/802_11/ieee80211_var.h> */
#define IWM_MVM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * 1000) #define IWM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * 1000)
#define IWM_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * 1000) #define IWM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * 1000)
#define IWM_MVM_WOWLAN_PS_TX_DATA_TIMEOUT (10 * 1000) #define IWM_WOWLAN_PS_TX_DATA_TIMEOUT (10 * 1000)
#define IWM_MVM_WOWLAN_PS_RX_DATA_TIMEOUT (10 * 1000) #define IWM_WOWLAN_PS_RX_DATA_TIMEOUT (10 * 1000)
#define IWM_MVM_SHORT_PS_TX_DATA_TIMEOUT (2 * 1024) /* defined in TU */ #define IWM_SHORT_PS_TX_DATA_TIMEOUT (2 * 1024) /* defined in TU */
#define IWM_MVM_SHORT_PS_RX_DATA_TIMEOUT (40 * 1024) /* defined in TU */ #define IWM_SHORT_PS_RX_DATA_TIMEOUT (40 * 1024) /* defined in TU */
#define IWM_MVM_P2P_LOWLATENCY_PS_ENABLE 0 #define IWM_P2P_LOWLATENCY_PS_ENABLE 0
#define IWM_MVM_UAPSD_RX_DATA_TIMEOUT (50 * 1000) #define IWM_UAPSD_RX_DATA_TIMEOUT (50 * 1000)
#define IWM_MVM_UAPSD_TX_DATA_TIMEOUT (50 * 1000) #define IWM_UAPSD_TX_DATA_TIMEOUT (50 * 1000)
#ifdef notyet #ifdef notyet
/* XXX Find corresponding values from net80211 */ /* XXX Find corresponding values from net80211 */
#define IWM_MVM_UAPSD_QUEUES (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\ #define IWM_UAPSD_QUEUES (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\
IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\ IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\
IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\ IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\
IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
#endif #endif
#define IWM_MVM_PS_HEAVY_TX_THLD_PACKETS 20 #define IWM_PS_HEAVY_TX_THLD_PACKETS 20
#define IWM_MVM_PS_HEAVY_RX_THLD_PACKETS 8 #define IWM_PS_HEAVY_RX_THLD_PACKETS 8
#define IWM_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30 #define IWM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30
#define IWM_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS 20 #define IWM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS 20
#define IWM_MVM_PS_HEAVY_TX_THLD_PERCENT 50 #define IWM_PS_HEAVY_TX_THLD_PERCENT 50
#define IWM_MVM_PS_HEAVY_RX_THLD_PERCENT 50 #define IWM_PS_HEAVY_RX_THLD_PERCENT 50
#define IWM_MVM_PS_SNOOZE_INTERVAL 25 #define IWM_PS_SNOOZE_INTERVAL 25
#define IWM_MVM_PS_SNOOZE_WINDOW 50 #define IWM_PS_SNOOZE_WINDOW 50
#define IWM_MVM_WOWLAN_PS_SNOOZE_WINDOW 25 #define IWM_WOWLAN_PS_SNOOZE_WINDOW 25
#define IWM_MVM_LOWLAT_QUOTA_MIN_PERCENT 64 #define IWM_LOWLAT_QUOTA_MIN_PERCENT 64
#define IWM_MVM_BT_COEX_EN_RED_TXP_THRESH 62 #define IWM_BT_COEX_EN_RED_TXP_THRESH 62
#define IWM_MVM_BT_COEX_DIS_RED_TXP_THRESH 65 #define IWM_BT_COEX_DIS_RED_TXP_THRESH 65
#define IWM_MVM_BT_COEX_SYNC2SCO 1 #define IWM_BT_COEX_SYNC2SCO 1
#define IWM_MVM_BT_COEX_CORUNNING 0 #define IWM_BT_COEX_CORUNNING 0
#define IWM_MVM_BT_COEX_MPLUT 1 #define IWM_BT_COEX_MPLUT 1
#define IWM_MVM_BT_COEX_RRC 1 #define IWM_BT_COEX_RRC 1
#define IWM_MVM_BT_COEX_TTC 1 #define IWM_BT_COEX_TTC 1
#define IWM_MVM_BT_COEX_MPLUT_REG0 0x22002200 #define IWM_BT_COEX_MPLUT_REG0 0x22002200
#define IWM_MVM_BT_COEX_MPLUT_REG1 0x11118451 #define IWM_BT_COEX_MPLUT_REG1 0x11118451
#define IWM_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30 #define IWM_BT_COEX_ANTENNA_COUPLING_THRS 30
#define IWM_MVM_FW_MCAST_FILTER_PASS_ALL 0 #define IWM_FW_MCAST_FILTER_PASS_ALL 0
#define IWM_MVM_FW_BCAST_FILTER_PASS_ALL 0 #define IWM_FW_BCAST_FILTER_PASS_ALL 0
#define IWM_MVM_QUOTA_THRESHOLD 4 #define IWM_QUOTA_THRESHOLD 4
#define IWM_MVM_RS_RSSI_BASED_INIT_RATE 0 #define IWM_RS_RSSI_BASED_INIT_RATE 0
#define IWM_MVM_RS_80_20_FAR_RANGE_TWEAK 1 #define IWM_RS_80_20_FAR_RANGE_TWEAK 1
#define IWM_MVM_TOF_IS_RESPONDER 0 #define IWM_TOF_IS_RESPONDER 0
#define IWM_MVM_SW_TX_CSUM_OFFLOAD 0 #define IWM_SW_TX_CSUM_OFFLOAD 0
#define IWM_MVM_HW_CSUM_DISABLE 0 #define IWM_HW_CSUM_DISABLE 0
#define IWM_MVM_COLLECT_FW_ERR_DUMP 1 #define IWM_COLLECT_FW_ERR_DUMP 1
#define IWM_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1 #define IWM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1
#define IWM_MVM_RS_HT_VHT_RETRIES_PER_RATE 2 #define IWM_RS_HT_VHT_RETRIES_PER_RATE 2
#define IWM_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW 1 #define IWM_RS_HT_VHT_RETRIES_PER_RATE_TW 1
#define IWM_MVM_RS_INITIAL_MIMO_NUM_RATES 3 #define IWM_RS_INITIAL_MIMO_NUM_RATES 3
#define IWM_MVM_RS_INITIAL_SISO_NUM_RATES 3 #define IWM_RS_INITIAL_SISO_NUM_RATES 3
#define IWM_MVM_RS_INITIAL_LEGACY_NUM_RATES 2 #define IWM_RS_INITIAL_LEGACY_NUM_RATES 2
#define IWM_MVM_RS_INITIAL_LEGACY_RETRIES 2 #define IWM_RS_INITIAL_LEGACY_RETRIES 2
#define IWM_MVM_RS_SECONDARY_LEGACY_RETRIES 1 #define IWM_RS_SECONDARY_LEGACY_RETRIES 1
#define IWM_MVM_RS_SECONDARY_LEGACY_NUM_RATES 16 #define IWM_RS_SECONDARY_LEGACY_NUM_RATES 16
#define IWM_MVM_RS_SECONDARY_SISO_NUM_RATES 3 #define IWM_RS_SECONDARY_SISO_NUM_RATES 3
#define IWM_MVM_RS_SECONDARY_SISO_RETRIES 1 #define IWM_RS_SECONDARY_SISO_RETRIES 1
#define IWM_MVM_RS_RATE_MIN_FAILURE_TH 3 #define IWM_RS_RATE_MIN_FAILURE_TH 3
#define IWM_MVM_RS_RATE_MIN_SUCCESS_TH 8 #define IWM_RS_RATE_MIN_SUCCESS_TH 8
#define IWM_MVM_RS_STAY_IN_COLUMN_TIMEOUT 5 /* Seconds */ #define IWM_RS_STAY_IN_COLUMN_TIMEOUT 5 /* Seconds */
#define IWM_MVM_RS_IDLE_TIMEOUT 5 /* Seconds */ #define IWM_RS_IDLE_TIMEOUT 5 /* Seconds */
#define IWM_MVM_RS_MISSED_RATE_MAX 15 #define IWM_RS_MISSED_RATE_MAX 15
#define IWM_MVM_RS_LEGACY_FAILURE_LIMIT 160 #define IWM_RS_LEGACY_FAILURE_LIMIT 160
#define IWM_MVM_RS_LEGACY_SUCCESS_LIMIT 480 #define IWM_RS_LEGACY_SUCCESS_LIMIT 480
#define IWM_MVM_RS_LEGACY_TABLE_COUNT 160 #define IWM_RS_LEGACY_TABLE_COUNT 160
#define IWM_MVM_RS_NON_LEGACY_FAILURE_LIMIT 400 #define IWM_RS_NON_LEGACY_FAILURE_LIMIT 400
#define IWM_MVM_RS_NON_LEGACY_SUCCESS_LIMIT 4500 #define IWM_RS_NON_LEGACY_SUCCESS_LIMIT 4500
#define IWM_MVM_RS_NON_LEGACY_TABLE_COUNT 1500 #define IWM_RS_NON_LEGACY_TABLE_COUNT 1500
#define IWM_MVM_RS_SR_FORCE_DECREASE 15 /* percent */ #define IWM_RS_SR_FORCE_DECREASE 15 /* percent */
#define IWM_MVM_RS_SR_NO_DECREASE 85 /* percent */ #define IWM_RS_SR_NO_DECREASE 85 /* percent */
#define IWM_MVM_RS_AGG_TIME_LIMIT 4000 /* 4 msecs. valid 100-8000 */ #define IWM_RS_AGG_TIME_LIMIT 4000 /* 4 msecs. valid 100-8000 */
#define IWM_MVM_RS_AGG_DISABLE_START 3 #define IWM_RS_AGG_DISABLE_START 3
#define IWM_MVM_RS_TPC_SR_FORCE_INCREASE 75 /* percent */ #define IWM_RS_TPC_SR_FORCE_INCREASE 75 /* percent */
#define IWM_MVM_RS_TPC_SR_NO_INCREASE 85 /* percent */ #define IWM_RS_TPC_SR_NO_INCREASE 85 /* percent */
#define IWM_MVM_RS_TPC_TX_POWER_STEP 3 #define IWM_RS_TPC_TX_POWER_STEP 3
#endif /* __IF_IWM_CONSTANTS_H */ #endif /* __IF_IWM_CONSTANTS_H */
@@ -13,7 +13,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_debug.h 319578 2017-06-04 21:10:14Z adrian $ * $FreeBSD$
*/ */
#ifndef __IF_IWM_DEBUG_H__ #ifndef __IF_IWM_DEBUG_H__
@@ -71,7 +71,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_fw.c 318001 2017-05-09 02:38:23Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -336,7 +336,7 @@ iwm_send_paging_cmd(struct iwm_softc *sc, const struct iwm_fw_img *fw)
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
} }
return iwm_mvm_send_cmd_pdu(sc, iwm_cmd_id(IWM_FW_PAGING_BLOCK_CMD, return iwm_send_cmd_pdu(sc, iwm_cmd_id(IWM_FW_PAGING_BLOCK_CMD,
IWM_ALWAYS_LONG_GROUP, 0), IWM_ALWAYS_LONG_GROUP, 0),
0, sizeof(fw_paging_cmd), &fw_paging_cmd); 0, sizeof(fw_paging_cmd), &fw_paging_cmd);
} }
@@ -71,7 +71,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/* /*
* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_fw.h 314209 2017-02-24 15:17:43Z adrian $ * $FreeBSD$
*/ */
#ifndef __IF_IWM_FW_H__ #ifndef __IF_IWM_FW_H__
#define __IF_IWM_FW_H__ #define __IF_IWM_FW_H__
@@ -87,7 +87,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_led.c 318001 2017-05-09 02:38:23Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -139,20 +139,20 @@ __FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_led.c 318001 2017-05-09 02:38
/* Set led register on */ /* Set led register on */
void void
iwm_mvm_led_enable(struct iwm_softc *sc) iwm_led_enable(struct iwm_softc *sc)
{ {
IWM_WRITE(sc, IWM_CSR_LED_REG, IWM_CSR_LED_REG_TURN_ON); IWM_WRITE(sc, IWM_CSR_LED_REG, IWM_CSR_LED_REG_TURN_ON);
} }
/* Set led register off */ /* Set led register off */
void void
iwm_mvm_led_disable(struct iwm_softc *sc) iwm_led_disable(struct iwm_softc *sc)
{ {
IWM_WRITE(sc, IWM_CSR_LED_REG, IWM_CSR_LED_REG_TURN_OFF); IWM_WRITE(sc, IWM_CSR_LED_REG, IWM_CSR_LED_REG_TURN_OFF);
} }
static int static int
iwm_mvm_led_is_enabled(struct iwm_softc *sc) iwm_led_is_enabled(struct iwm_softc *sc)
{ {
return (IWM_READ(sc, IWM_CSR_LED_REG) == IWM_CSR_LED_REG_TURN_ON); return (IWM_READ(sc, IWM_CSR_LED_REG) == IWM_CSR_LED_REG_TURN_ON);
} }
@@ -165,10 +165,10 @@ iwm_led_blink_timeout(void *arg)
if (sc->sc_attached == 0) if (sc->sc_attached == 0)
return; return;
if (iwm_mvm_led_is_enabled(sc)) if (iwm_led_is_enabled(sc))
iwm_mvm_led_disable(sc); iwm_led_disable(sc);
else else
iwm_mvm_led_enable(sc); iwm_led_enable(sc);
callout_reset(&sc->sc_led_blink_to, (200 * hz) / 1000, callout_reset(&sc->sc_led_blink_to, (200 * hz) / 1000,
iwm_led_blink_timeout, sc); iwm_led_blink_timeout, sc);
@@ -184,5 +184,5 @@ void
iwm_led_blink_stop(struct iwm_softc *sc) iwm_led_blink_stop(struct iwm_softc *sc)
{ {
callout_stop(&sc->sc_led_blink_to); callout_stop(&sc->sc_led_blink_to);
iwm_mvm_led_disable(sc); iwm_led_disable(sc);
} }
@@ -86,13 +86,13 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_led.h 303327 2016-07-26 00:02:17Z sbruno $ * $FreeBSD$
*/ */
#ifndef __IF_IWM_LED_H__ #ifndef __IF_IWM_LED_H__
#define __IF_IWM_LED_H__ #define __IF_IWM_LED_H__
extern void iwm_mvm_led_enable(struct iwm_softc *); extern void iwm_led_enable(struct iwm_softc *);
extern void iwm_mvm_led_disable(struct iwm_softc *); extern void iwm_led_disable(struct iwm_softc *);
extern void iwm_led_blink_start(struct iwm_softc *); extern void iwm_led_blink_start(struct iwm_softc *);
extern void iwm_led_blink_stop(struct iwm_softc *); extern void iwm_led_blink_stop(struct iwm_softc *);
@@ -103,7 +103,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_mac_ctxt.c 318219 2017-05-12 05:50:38Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -161,15 +161,15 @@ __FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_mac_ctxt.c 318219 2017-05-12
* BEGIN mvm/mac-ctxt.c * BEGIN mvm/mac-ctxt.c
*/ */
const uint8_t iwm_mvm_ac_to_tx_fifo[] = { const uint8_t iwm_ac_to_tx_fifo[] = {
IWM_MVM_TX_FIFO_BE, IWM_TX_FIFO_BE,
IWM_MVM_TX_FIFO_BK, IWM_TX_FIFO_BK,
IWM_MVM_TX_FIFO_VI, IWM_TX_FIFO_VI,
IWM_MVM_TX_FIFO_VO, IWM_TX_FIFO_VO,
}; };
static void static void
iwm_mvm_ack_rates(struct iwm_softc *sc, int is2ghz, iwm_ack_rates(struct iwm_softc *sc, int is2ghz,
int *cck_rates, int *ofdm_rates, struct iwm_node *in) int *cck_rates, int *ofdm_rates, struct iwm_node *in)
{ {
int lowest_present_ofdm = 100; int lowest_present_ofdm = 100;
@@ -253,7 +253,7 @@ iwm_mvm_ack_rates(struct iwm_softc *sc, int is2ghz,
} }
static void static void
iwm_mvm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in, 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)
{ {
struct ieee80211com *ic = &sc->sc_ic; struct ieee80211com *ic = &sc->sc_ic;
@@ -305,8 +305,8 @@ iwm_mvm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in,
* XXX This workaround makes the firmware behave more correctly once * XXX This workaround makes the firmware behave more correctly once
* we are associated, regularly giving us statistics notifications, * we are associated, regularly giving us statistics notifications,
* as well as signaling missed beacons to us. * as well as signaling missed beacons to us.
* Since we only call iwm_mvm_mac_ctxt_add() and * Since we only call iwm_mac_ctxt_add() and
* iwm_mvm_mac_ctxt_changed() when already authenticating or * iwm_mac_ctxt_changed() when already authenticating or
* associating, ni->ni_bssid should always make sense here. * associating, ni->ni_bssid should always make sense here.
*/ */
if (ivp->iv_auth) { if (ivp->iv_auth) {
@@ -325,7 +325,7 @@ iwm_mvm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in,
} else { } else {
is2ghz = 1; is2ghz = 1;
} }
iwm_mvm_ack_rates(sc, is2ghz, &cck_ack_rates, &ofdm_ack_rates, in); iwm_ack_rates(sc, is2ghz, &cck_ack_rates, &ofdm_ack_rates, in);
cmd->cck_rates = htole32(cck_ack_rates); cmd->cck_rates = htole32(cck_ack_rates);
cmd->ofdm_rates = htole32(ofdm_ack_rates); cmd->ofdm_rates = htole32(ofdm_ack_rates);
@@ -342,7 +342,7 @@ iwm_mvm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in,
*/ */
for (i = 0; i < WME_NUM_AC; i++) { for (i = 0; i < WME_NUM_AC; i++) {
uint8_t txf = iwm_mvm_ac_to_tx_fifo[i]; uint8_t txf = iwm_ac_to_tx_fifo[i];
cmd->ac[txf].cw_min = htole16(ivp->queue_params[i].cw_min); cmd->ac[txf].cw_min = htole16(ivp->queue_params[i].cw_min);
cmd->ac[txf].cw_max = htole16(ivp->queue_params[i].cw_max); cmd->ac[txf].cw_max = htole16(ivp->queue_params[i].cw_max);
@@ -362,9 +362,9 @@ iwm_mvm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in,
} }
static int static int
iwm_mvm_mac_ctxt_send_cmd(struct iwm_softc *sc, struct iwm_mac_ctx_cmd *cmd) iwm_mac_ctxt_send_cmd(struct iwm_softc *sc, struct iwm_mac_ctx_cmd *cmd)
{ {
int ret = iwm_mvm_send_cmd_pdu(sc, IWM_MAC_CONTEXT_CMD, IWM_CMD_SYNC, int ret = iwm_send_cmd_pdu(sc, IWM_MAC_CONTEXT_CMD, IWM_CMD_SYNC,
sizeof(*cmd), cmd); sizeof(*cmd), cmd);
if (ret) if (ret)
device_printf(sc->sc_dev, device_printf(sc->sc_dev,
@@ -377,7 +377,7 @@ iwm_mvm_mac_ctxt_send_cmd(struct iwm_softc *sc, struct iwm_mac_ctx_cmd *cmd)
* Fill the specific data for mac context of type station or p2p client * Fill the specific data for mac context of type station or p2p client
*/ */
static void static void
iwm_mvm_mac_ctxt_cmd_fill_sta(struct iwm_softc *sc, struct iwm_node *in, 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 *ctxt_sta, int force_assoc_off)
{ {
struct ieee80211_node *ni = &in->in_ni; struct ieee80211_node *ni = &in->in_ni;
@@ -444,15 +444,15 @@ iwm_mvm_mac_ctxt_cmd_fill_sta(struct iwm_softc *sc, struct iwm_node *in,
"%s: ni_intval: %d, bi_reciprocal: %d, dtim_interval: %d, dtim_reciprocal: %d\n", "%s: ni_intval: %d, bi_reciprocal: %d, dtim_interval: %d, dtim_reciprocal: %d\n",
__func__, __func__,
ni->ni_intval, ni->ni_intval,
iwm_mvm_reciprocal(ni->ni_intval), iwm_reciprocal(ni->ni_intval),
ni->ni_intval * dtim_period, ni->ni_intval * dtim_period,
iwm_mvm_reciprocal(ni->ni_intval * dtim_period)); iwm_reciprocal(ni->ni_intval * dtim_period));
ctxt_sta->bi = htole32(ni->ni_intval); ctxt_sta->bi = htole32(ni->ni_intval);
ctxt_sta->bi_reciprocal = htole32(iwm_mvm_reciprocal(ni->ni_intval)); ctxt_sta->bi_reciprocal = htole32(iwm_reciprocal(ni->ni_intval));
ctxt_sta->dtim_interval = htole32(ni->ni_intval * dtim_period); ctxt_sta->dtim_interval = htole32(ni->ni_intval * dtim_period);
ctxt_sta->dtim_reciprocal = ctxt_sta->dtim_reciprocal =
htole32(iwm_mvm_reciprocal(ni->ni_intval * dtim_period)); htole32(iwm_reciprocal(ni->ni_intval * dtim_period));
/* 10 = CONN_MAX_LISTEN_INTERVAL */ /* 10 = CONN_MAX_LISTEN_INTERVAL */
ctxt_sta->listen_interval = htole32(10); ctxt_sta->listen_interval = htole32(10);
@@ -462,7 +462,7 @@ iwm_mvm_mac_ctxt_cmd_fill_sta(struct iwm_softc *sc, struct iwm_node *in,
} }
static int static int
iwm_mvm_mac_ctxt_cmd_station(struct iwm_softc *sc, struct ieee80211vap *vap, iwm_mac_ctxt_cmd_station(struct iwm_softc *sc, struct ieee80211vap *vap,
uint32_t action) uint32_t action)
{ {
struct ieee80211_node *ni = vap->iv_bss; struct ieee80211_node *ni = vap->iv_bss;
@@ -473,7 +473,7 @@ iwm_mvm_mac_ctxt_cmd_station(struct iwm_softc *sc, struct ieee80211vap *vap,
"%s: called; action=%d\n", __func__, action); "%s: called; action=%d\n", __func__, action);
/* Fill the common data for all mac context types */ /* Fill the common data for all mac context types */
iwm_mvm_mac_ctxt_cmd_common(sc, in, &cmd, action); iwm_mac_ctxt_cmd_common(sc, in, &cmd, action);
/* Allow beacons to pass through as long as we are not associated,or we /* Allow beacons to pass through as long as we are not associated,or we
* do not have dtim period information */ * do not have dtim period information */
@@ -483,21 +483,21 @@ iwm_mvm_mac_ctxt_cmd_station(struct iwm_softc *sc, struct ieee80211vap *vap,
cmd.filter_flags &= ~htole32(IWM_MAC_FILTER_IN_BEACON); cmd.filter_flags &= ~htole32(IWM_MAC_FILTER_IN_BEACON);
/* Fill the data specific for station mode */ /* Fill the data specific for station mode */
iwm_mvm_mac_ctxt_cmd_fill_sta(sc, in, iwm_mac_ctxt_cmd_fill_sta(sc, in,
&cmd.sta, action == IWM_FW_CTXT_ACTION_ADD); &cmd.sta, action == IWM_FW_CTXT_ACTION_ADD);
return iwm_mvm_mac_ctxt_send_cmd(sc, &cmd); return iwm_mac_ctxt_send_cmd(sc, &cmd);
} }
static int static int
iwm_mvm_mac_ctx_send(struct iwm_softc *sc, struct ieee80211vap *vap, iwm_mac_ctx_send(struct iwm_softc *sc, struct ieee80211vap *vap,
uint32_t action) uint32_t action)
{ {
return iwm_mvm_mac_ctxt_cmd_station(sc, vap, action); return iwm_mac_ctxt_cmd_station(sc, vap, action);
} }
int int
iwm_mvm_mac_ctxt_add(struct iwm_softc *sc, struct ieee80211vap *vap) iwm_mac_ctxt_add(struct iwm_softc *sc, struct ieee80211vap *vap)
{ {
struct iwm_vap *iv = IWM_VAP(vap); struct iwm_vap *iv = IWM_VAP(vap);
int ret; int ret;
@@ -508,7 +508,7 @@ iwm_mvm_mac_ctxt_add(struct iwm_softc *sc, struct ieee80211vap *vap)
return (EIO); return (EIO);
} }
ret = iwm_mvm_mac_ctx_send(sc, vap, IWM_FW_CTXT_ACTION_ADD); ret = iwm_mac_ctx_send(sc, vap, IWM_FW_CTXT_ACTION_ADD);
if (ret) if (ret)
return (ret); return (ret);
iv->is_uploaded = 1; iv->is_uploaded = 1;
@@ -516,7 +516,7 @@ iwm_mvm_mac_ctxt_add(struct iwm_softc *sc, struct ieee80211vap *vap)
} }
int int
iwm_mvm_mac_ctxt_changed(struct iwm_softc *sc, struct ieee80211vap *vap) iwm_mac_ctxt_changed(struct iwm_softc *sc, struct ieee80211vap *vap)
{ {
struct iwm_vap *iv = IWM_VAP(vap); struct iwm_vap *iv = IWM_VAP(vap);
@@ -525,12 +525,12 @@ iwm_mvm_mac_ctxt_changed(struct iwm_softc *sc, struct ieee80211vap *vap)
__func__); __func__);
return (EIO); return (EIO);
} }
return iwm_mvm_mac_ctx_send(sc, vap, IWM_FW_CTXT_ACTION_MODIFY); return iwm_mac_ctx_send(sc, vap, IWM_FW_CTXT_ACTION_MODIFY);
} }
#if 0 #if 0
static int static int
iwm_mvm_mac_ctxt_remove(struct iwm_softc *sc, struct iwm_node *in) iwm_mac_ctxt_remove(struct iwm_softc *sc, struct iwm_node *in)
{ {
struct iwm_mac_ctx_cmd cmd; struct iwm_mac_ctx_cmd cmd;
int ret; int ret;
@@ -547,7 +547,7 @@ iwm_mvm_mac_ctxt_remove(struct iwm_softc *sc, struct iwm_node *in)
IWM_DEFAULT_COLOR)); IWM_DEFAULT_COLOR));
cmd.action = htole32(IWM_FW_CTXT_ACTION_REMOVE); cmd.action = htole32(IWM_FW_CTXT_ACTION_REMOVE);
ret = iwm_mvm_send_cmd_pdu(sc, ret = iwm_send_cmd_pdu(sc,
IWM_MAC_CONTEXT_CMD, IWM_CMD_SYNC, sizeof(cmd), &cmd); IWM_MAC_CONTEXT_CMD, IWM_CMD_SYNC, sizeof(cmd), &cmd);
if (ret) { if (ret) {
device_printf(sc->sc_dev, device_printf(sc->sc_dev,
@@ -1,5 +1,5 @@
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_mac_ctxt.h 318219 2017-05-12 05:50:38Z adrian $ */ /* $FreeBSD$ */
/* /*
* Copyright (c) 2014 genua mbh <info@genua.de> * Copyright (c) 2014 genua mbh <info@genua.de>
@@ -106,10 +106,10 @@
#ifndef __IF_IWM_MAC_CTXT_H__ #ifndef __IF_IWM_MAC_CTXT_H__
#define __IF_IWM_MAC_CTXT_H__ #define __IF_IWM_MAC_CTXT_H__
extern const uint8_t iwm_mvm_ac_to_tx_fifo[]; extern const uint8_t iwm_ac_to_tx_fifo[];
extern int iwm_mvm_mac_ctxt_add(struct iwm_softc *sc, struct ieee80211vap *vap); extern int iwm_mac_ctxt_add(struct iwm_softc *sc, struct ieee80211vap *vap);
extern int iwm_mvm_mac_ctxt_changed(struct iwm_softc *sc, struct ieee80211vap *vap); extern int iwm_mac_ctxt_changed(struct iwm_softc *sc, struct ieee80211vap *vap);
extern int iwm_mvm_mac_ctxt_remove(struct iwm_softc *sc, struct ieee80211vap *vap); extern int iwm_mac_ctxt_remove(struct iwm_softc *sc, struct ieee80211vap *vap);
#endif /* __IF_IWM_MAC_CTXT_H__ */ #endif /* __IF_IWM_MAC_CTXT_H__ */
@@ -67,7 +67,7 @@
*****************************************************************************/ *****************************************************************************/
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_notif_wait.c 318001 2017-05-09 02:38:23Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -76,9 +76,9 @@ __FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_notif_wait.c 318001 2017-05-0
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/bus.h> #include <sys/bus.h>
#include <sys/kernel.h> #include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h> #include <sys/malloc.h>
#include <sys/mutex.h> #include <sys/mutex.h>
#include <sys/lock.h>
#include <sys/queue.h> #include <sys/queue.h>
#include <dev/iwm/if_iwm_notif_wait.h> #include <dev/iwm/if_iwm_notif_wait.h>
@@ -66,7 +66,7 @@
* *
*****************************************************************************/ *****************************************************************************/
/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_notif_wait.h 313322 2017-02-06 05:27:07Z adrian $ */ /* $FreeBSD$ */
#ifndef __IF_IWN_NOTIF_WAIT_H__ #ifndef __IF_IWN_NOTIF_WAIT_H__
#define __IF_IWN_NOTIF_WAIT_H__ #define __IF_IWN_NOTIF_WAIT_H__
@@ -103,7 +103,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_pcie_trans.c 318003 2017-05-09 02:42:53Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -185,6 +185,27 @@ iwm_write_prph(struct iwm_softc *sc, uint32_t addr, uint32_t val)
IWM_WRITE(sc, IWM_HBUS_TARG_PRPH_WDAT, val); IWM_WRITE(sc, IWM_HBUS_TARG_PRPH_WDAT, val);
} }
void
iwm_write_prph64(struct iwm_softc *sc, uint64_t addr, uint64_t val)
{
iwm_write_prph(sc, (uint32_t)addr, val & 0xffffffff);
iwm_write_prph(sc, (uint32_t)addr + 4, val >> 32);
}
int
iwm_poll_prph(struct iwm_softc *sc, uint32_t addr, uint32_t bits, uint32_t mask,
int timeout)
{
do {
if ((iwm_read_prph(sc, addr) & mask) == (bits & mask))
return (0);
DELAY(10);
timeout -= 10;
} while (timeout > 0);
return (ETIMEDOUT);
}
#ifdef IWM_DEBUG #ifdef IWM_DEBUG
/* iwlwifi: pcie/trans.c */ /* iwlwifi: pcie/trans.c */
int int
@@ -261,7 +282,7 @@ iwm_nic_lock(struct iwm_softc *sc)
IWM_SETBITS(sc, IWM_CSR_GP_CNTRL, IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000)
DELAY(2); DELAY(2);
if (iwm_poll_bit(sc, IWM_CSR_GP_CNTRL, if (iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
@@ -325,6 +346,8 @@ iwm_enable_rfkill_int(struct iwm_softc *sc)
{ {
sc->sc_intmask = IWM_CSR_INT_BIT_RF_KILL; sc->sc_intmask = IWM_CSR_INT_BIT_RF_KILL;
IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask); IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
IWM_CSR_GP_CNTRL_REG_FLAG_RFKILL_WAKE_L1A_EN);
} }
int int
@@ -383,7 +406,9 @@ iwm_prepare_card_hw(struct iwm_softc *sc)
if (iwm_set_hw_ready(sc)) if (iwm_set_hw_ready(sc))
goto out; goto out;
DELAY(100); IWM_SETBITS(sc, IWM_CSR_DBG_LINK_PWR_MGMT_REG,
IWM_CSR_RESET_LINK_PWR_MGMT_DISABLED);
DELAY(1000);
/* If HW is not ready, prepare the conditions to check again */ /* If HW is not ready, prepare the conditions to check again */
IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG, IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
@@ -454,7 +479,7 @@ iwm_apm_init(struct iwm_softc *sc)
IWM_DPRINTF(sc, IWM_DEBUG_RESET, "iwm apm start\n"); IWM_DPRINTF(sc, IWM_DEBUG_RESET, "iwm apm start\n");
/* Disable L0S exit timer (platform NMI Work/Around) */ /* Disable L0S exit timer (platform NMI Work/Around) */
if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) { if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) {
IWM_SETBITS(sc, IWM_CSR_GIO_CHICKEN_BITS, IWM_SETBITS(sc, IWM_CSR_GIO_CHICKEN_BITS,
IWM_CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); IWM_CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
} }
@@ -569,6 +594,16 @@ iwm_apm_init(struct iwm_softc *sc)
void void
iwm_apm_stop(struct iwm_softc *sc) iwm_apm_stop(struct iwm_softc *sc)
{ {
IWM_SETBITS(sc, IWM_CSR_DBG_LINK_PWR_MGMT_REG,
IWM_CSR_RESET_LINK_PWR_MGMT_DISABLED);
IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
IWM_CSR_HW_IF_CONFIG_REG_PREPARE |
IWM_CSR_HW_IF_CONFIG_REG_ENABLE_PME);
DELAY(1000);
IWM_CLRBITS(sc, IWM_CSR_DBG_LINK_PWR_MGMT_REG,
IWM_CSR_RESET_LINK_PWR_MGMT_DISABLED);
DELAY(5000);
/* stop device's busmaster DMA activity */ /* stop device's busmaster DMA activity */
IWM_SETBITS(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_STOP_MASTER); IWM_SETBITS(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_STOP_MASTER);
@@ -576,6 +611,14 @@ iwm_apm_stop(struct iwm_softc *sc)
IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED, IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED,
IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED, 100)) IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED, 100))
device_printf(sc->sc_dev, "timeout waiting for master\n"); device_printf(sc->sc_dev, "timeout waiting for master\n");
/*
* Clear "initialization complete" bit to move adapter from
* D0A* (powered-up Active) --> D0U* (Uninitialized) state.
*/
IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
IWM_CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
IWM_DPRINTF(sc, IWM_DEBUG_TRANS, "%s: iwm apm stop\n", __func__); IWM_DPRINTF(sc, IWM_DEBUG_TRANS, "%s: iwm apm stop\n", __func__);
} }
@@ -590,11 +633,15 @@ iwm_start_hw(struct iwm_softc *sc)
/* Reset the entire device */ /* Reset the entire device */
IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_SW_RESET); IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_SW_RESET);
DELAY(10); DELAY(5000);
if ((error = iwm_apm_init(sc)) != 0) if ((error = iwm_apm_init(sc)) != 0)
return error; return error;
/* On newer chipsets MSI is disabled by default. */
if (sc->cfg->mqrx_supported)
iwm_write_prph(sc, IWM_UREG_CHICK, IWM_UREG_CHICK_MSI_ENABLE);
iwm_enable_rfkill_int(sc); iwm_enable_rfkill_int(sc);
iwm_check_rfkill(sc); iwm_check_rfkill(sc);
@@ -613,13 +660,21 @@ iwm_set_pwr(struct iwm_softc *sc)
int int
iwm_pcie_rx_stop(struct iwm_softc *sc) iwm_pcie_rx_stop(struct iwm_softc *sc)
{ {
int ret = 0; int ret;
ret = 0;
if (iwm_nic_lock(sc)) { if (iwm_nic_lock(sc)) {
if (sc->cfg->mqrx_supported) {
iwm_write_prph(sc, IWM_RFH_RXF_DMA_CFG, 0);
ret = iwm_poll_prph(sc, IWM_RFH_GEN_STATUS,
IWM_RXF_DMA_IDLE, IWM_RXF_DMA_IDLE, 1000);
} else {
IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
ret = iwm_poll_bit(sc, IWM_FH_MEM_RSSR_RX_STATUS_REG, ret = iwm_poll_bit(sc, IWM_FH_MEM_RSSR_RX_STATUS_REG,
IWM_FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, IWM_FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
IWM_FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, IWM_FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
1000); 1000);
}
iwm_nic_unlock(sc); iwm_nic_unlock(sc);
} }
return ret; return ret;
@@ -1,4 +1,4 @@
/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_pcie_trans.h 313415 2017-02-08 06:53:23Z adrian $ */ /* $FreeBSD$ */
/* /*
* Copyright (c) 2014 genua mbh <info@genua.de> * Copyright (c) 2014 genua mbh <info@genua.de>
* Copyright (c) 2014 Fixup Software Ltd. * Copyright (c) 2014 Fixup Software Ltd.
@@ -106,6 +106,10 @@
extern uint32_t iwm_read_prph(struct iwm_softc *sc, uint32_t addr); extern uint32_t iwm_read_prph(struct iwm_softc *sc, uint32_t addr);
extern void iwm_write_prph(struct iwm_softc *sc, uint32_t addr, uint32_t val); extern void iwm_write_prph(struct iwm_softc *sc, uint32_t addr, uint32_t val);
extern void iwm_write_prph64(struct iwm_softc *sc, uint64_t addr,
uint64_t val);
extern int iwm_poll_prph(struct iwm_softc *sc, uint32_t addr, uint32_t bits,
uint32_t mask, int timeout);
extern int iwm_read_mem(struct iwm_softc *sc, uint32_t addr, void *buf, int dwords); extern int iwm_read_mem(struct iwm_softc *sc, uint32_t addr, void *buf, int dwords);
extern int iwm_write_mem(struct iwm_softc *sc, uint32_t addr, const void *buf, extern int iwm_write_mem(struct iwm_softc *sc, uint32_t addr, const void *buf,
int dwords); int dwords);
@@ -103,7 +103,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_phy_ctxt.c 318012 2017-05-09 05:31:38Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -165,7 +165,7 @@ __FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_phy_ctxt.c 318012 2017-05-09
* Construct the generic fields of the PHY context command * Construct the generic fields of the PHY context command
*/ */
static void static void
iwm_mvm_phy_ctxt_cmd_hdr(struct iwm_softc *sc, struct iwm_mvm_phy_ctxt *ctxt, iwm_phy_ctxt_cmd_hdr(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt,
struct iwm_phy_context_cmd *cmd, uint32_t action, uint32_t apply_time) struct iwm_phy_context_cmd *cmd, uint32_t action, uint32_t apply_time)
{ {
memset(cmd, 0, sizeof(struct iwm_phy_context_cmd)); memset(cmd, 0, sizeof(struct iwm_phy_context_cmd));
@@ -188,7 +188,7 @@ iwm_mvm_phy_ctxt_cmd_hdr(struct iwm_softc *sc, struct iwm_mvm_phy_ctxt *ctxt,
* Add the phy configuration to the PHY context command * Add the phy configuration to the PHY context command
*/ */
static void static void
iwm_mvm_phy_ctxt_cmd_data(struct iwm_softc *sc, iwm_phy_ctxt_cmd_data(struct iwm_softc *sc,
struct iwm_phy_context_cmd *cmd, struct ieee80211_channel *chan, struct iwm_phy_context_cmd *cmd, struct ieee80211_channel *chan,
uint8_t chains_static, uint8_t chains_dynamic) uint8_t chains_static, uint8_t chains_dynamic)
{ {
@@ -203,8 +203,8 @@ iwm_mvm_phy_ctxt_cmd_data(struct iwm_softc *sc,
ieee80211_chan2ieee(ic, chan), ieee80211_chan2ieee(ic, chan),
chains_static, chains_static,
chains_dynamic, chains_dynamic,
iwm_mvm_get_valid_rx_ant(sc), iwm_get_valid_rx_ant(sc),
iwm_mvm_get_valid_tx_ant(sc)); iwm_get_valid_tx_ant(sc));
cmd->ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ? cmd->ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
@@ -225,18 +225,18 @@ iwm_mvm_phy_ctxt_cmd_data(struct iwm_softc *sc,
* between the two antennas is sufficiently different to impact * between the two antennas is sufficiently different to impact
* performance. * performance.
*/ */
if (active_cnt == 1 && iwm_mvm_rx_diversity_allowed(sc)) { if (active_cnt == 1 && iwm_rx_diversity_allowed(sc)) {
idle_cnt = 2; idle_cnt = 2;
active_cnt = 2; active_cnt = 2;
} }
cmd->rxchain_info = htole32(iwm_mvm_get_valid_rx_ant(sc) << cmd->rxchain_info = htole32(iwm_get_valid_rx_ant(sc) <<
IWM_PHY_RX_CHAIN_VALID_POS); IWM_PHY_RX_CHAIN_VALID_POS);
cmd->rxchain_info |= htole32(idle_cnt << IWM_PHY_RX_CHAIN_CNT_POS); cmd->rxchain_info |= htole32(idle_cnt << IWM_PHY_RX_CHAIN_CNT_POS);
cmd->rxchain_info |= htole32(active_cnt << cmd->rxchain_info |= htole32(active_cnt <<
IWM_PHY_RX_CHAIN_MIMO_CNT_POS); IWM_PHY_RX_CHAIN_MIMO_CNT_POS);
cmd->txchain_info = htole32(iwm_mvm_get_valid_tx_ant(sc)); cmd->txchain_info = htole32(iwm_get_valid_tx_ant(sc));
} }
/* /*
@@ -246,8 +246,8 @@ iwm_mvm_phy_ctxt_cmd_data(struct iwm_softc *sc,
* configuration changed from the previous apply. * configuration changed from the previous apply.
*/ */
static int static int
iwm_mvm_phy_ctxt_apply(struct iwm_softc *sc, iwm_phy_ctxt_apply(struct iwm_softc *sc,
struct iwm_mvm_phy_ctxt *ctxt, struct iwm_phy_ctxt *ctxt,
uint8_t chains_static, uint8_t chains_dynamic, uint8_t chains_static, uint8_t chains_dynamic,
uint32_t action, uint32_t apply_time) uint32_t action, uint32_t apply_time)
{ {
@@ -260,13 +260,13 @@ iwm_mvm_phy_ctxt_apply(struct iwm_softc *sc,
ctxt->channel); ctxt->channel);
/* Set the command header fields */ /* Set the command header fields */
iwm_mvm_phy_ctxt_cmd_hdr(sc, ctxt, &cmd, action, apply_time); iwm_phy_ctxt_cmd_hdr(sc, ctxt, &cmd, action, apply_time);
/* Set the command data */ /* Set the command data */
iwm_mvm_phy_ctxt_cmd_data(sc, &cmd, ctxt->channel, iwm_phy_ctxt_cmd_data(sc, &cmd, ctxt->channel,
chains_static, chains_dynamic); chains_static, chains_dynamic);
ret = iwm_mvm_send_cmd_pdu(sc, IWM_PHY_CONTEXT_CMD, IWM_CMD_SYNC, ret = iwm_send_cmd_pdu(sc, IWM_PHY_CONTEXT_CMD, IWM_CMD_SYNC,
sizeof(struct iwm_phy_context_cmd), &cmd); sizeof(struct iwm_phy_context_cmd), &cmd);
if (ret) { if (ret) {
device_printf(sc->sc_dev, device_printf(sc->sc_dev,
@@ -279,7 +279,7 @@ iwm_mvm_phy_ctxt_apply(struct iwm_softc *sc,
* Send a command to add a PHY context based on the current HW configuration. * Send a command to add a PHY context based on the current HW configuration.
*/ */
int int
iwm_mvm_phy_ctxt_add(struct iwm_softc *sc, struct iwm_mvm_phy_ctxt *ctxt, iwm_phy_ctxt_add(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt,
struct ieee80211_channel *chan, struct ieee80211_channel *chan,
uint8_t chains_static, uint8_t chains_dynamic) uint8_t chains_static, uint8_t chains_dynamic)
{ {
@@ -290,7 +290,7 @@ iwm_mvm_phy_ctxt_add(struct iwm_softc *sc, struct iwm_mvm_phy_ctxt *ctxt,
__func__, __func__,
ieee80211_chan2ieee(&sc->sc_ic, chan)); ieee80211_chan2ieee(&sc->sc_ic, chan));
return iwm_mvm_phy_ctxt_apply(sc, ctxt, return iwm_phy_ctxt_apply(sc, ctxt,
chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_ADD, 0); chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_ADD, 0);
} }
@@ -300,8 +300,8 @@ iwm_mvm_phy_ctxt_add(struct iwm_softc *sc, struct iwm_mvm_phy_ctxt *ctxt,
* changed. * changed.
*/ */
int int
iwm_mvm_phy_ctxt_changed(struct iwm_softc *sc, iwm_phy_ctxt_changed(struct iwm_softc *sc,
struct iwm_mvm_phy_ctxt *ctxt, struct ieee80211_channel *chan, struct iwm_phy_ctxt *ctxt, struct ieee80211_channel *chan,
uint8_t chains_static, uint8_t chains_dynamic) uint8_t chains_static, uint8_t chains_dynamic)
{ {
ctxt->channel = chan; ctxt->channel = chan;
@@ -311,7 +311,7 @@ iwm_mvm_phy_ctxt_changed(struct iwm_softc *sc,
__func__, __func__,
ieee80211_chan2ieee(&sc->sc_ic, chan)); ieee80211_chan2ieee(&sc->sc_ic, chan));
return iwm_mvm_phy_ctxt_apply(sc, ctxt, return iwm_phy_ctxt_apply(sc, ctxt,
chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_MODIFY, 0); chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_MODIFY, 0);
} }
@@ -1,5 +1,5 @@
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_phy_ctxt.h 286441 2015-08-08 06:06:48Z rpaulo $ */ /* $FreeBSD$ */
/* /*
* Copyright (c) 2014 genua mbh <info@genua.de> * Copyright (c) 2014 genua mbh <info@genua.de>
@@ -106,12 +106,12 @@
#ifndef __IF_IWM_PHY_CTXT_H__ #ifndef __IF_IWM_PHY_CTXT_H__
#define __IF_IWM_PHY_CTXT_H__ #define __IF_IWM_PHY_CTXT_H__
extern int iwm_mvm_phy_ctxt_add(struct iwm_softc *sc, extern int iwm_phy_ctxt_add(struct iwm_softc *sc,
struct iwm_mvm_phy_ctxt *ctxt, struct iwm_phy_ctxt *ctxt,
struct ieee80211_channel *chan, struct ieee80211_channel *chan,
uint8_t chains_static, uint8_t chains_dynamic); uint8_t chains_static, uint8_t chains_dynamic);
extern int iwm_mvm_phy_ctxt_changed(struct iwm_softc *sc, extern int iwm_phy_ctxt_changed(struct iwm_softc *sc,
struct iwm_mvm_phy_ctxt *ctxt, struct ieee80211_channel *chan, struct iwm_phy_ctxt *ctxt, struct ieee80211_channel *chan,
uint8_t chains_static, uint8_t chains_dynamic); uint8_t chains_static, uint8_t chains_dynamic);
#endif /* __IF_IWM_PHY_CTXT_H__ */ #endif /* __IF_IWM_PHY_CTXT_H__ */
@@ -103,7 +103,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_phy_db.c 319581 2017-06-04 21:13:13Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -203,7 +203,7 @@ enum iwm_phy_db_section_type {
struct iwm_phy_db_cmd { struct iwm_phy_db_cmd {
uint16_t type; uint16_t type;
uint16_t length; uint16_t length;
uint8_t data[0]; uint8_t data[];
} __packed; } __packed;
/* for parsing of tx power channel group data that comes from the firmware*/ /* for parsing of tx power channel group data that comes from the firmware*/
@@ -218,7 +218,7 @@ struct iwm_phy_db_chg_txp {
struct iwm_calib_res_notif_phy_db { struct iwm_calib_res_notif_phy_db {
uint16_t type; uint16_t type;
uint16_t length; uint16_t length;
uint8_t data[0]; uint8_t data[];
} __packed; } __packed;
struct iwm_phy_db * struct iwm_phy_db *
@@ -1,5 +1,5 @@
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_phy_db.h 313317 2017-02-06 05:09:42Z adrian $ */ /* $FreeBSD$ */
/* /*
* Copyright (c) 2014 genua mbh <info@genua.de> * Copyright (c) 2014 genua mbh <info@genua.de>
@@ -87,7 +87,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_power.c 318228 2017-05-12 06:31:57Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -153,12 +153,12 @@ TUNABLE_INT("hw.iwm.power_scheme", &iwm_power_scheme);
#define IWM_POWER_KEEP_ALIVE_PERIOD_SEC 25 #define IWM_POWER_KEEP_ALIVE_PERIOD_SEC 25
static int static int
iwm_mvm_beacon_filter_send_cmd(struct iwm_softc *sc, iwm_beacon_filter_send_cmd(struct iwm_softc *sc,
struct iwm_beacon_filter_cmd *cmd) struct iwm_beacon_filter_cmd *cmd)
{ {
int ret; int ret;
ret = iwm_mvm_send_cmd_pdu(sc, IWM_REPLY_BEACON_FILTERING_CMD, ret = iwm_send_cmd_pdu(sc, IWM_REPLY_BEACON_FILTERING_CMD,
0, sizeof(struct iwm_beacon_filter_cmd), cmd); 0, sizeof(struct iwm_beacon_filter_cmd), cmd);
if (!ret) { if (!ret) {
@@ -200,14 +200,14 @@ iwm_mvm_beacon_filter_send_cmd(struct iwm_softc *sc,
} }
static void static void
iwm_mvm_beacon_filter_set_cqm_params(struct iwm_softc *sc, iwm_beacon_filter_set_cqm_params(struct iwm_softc *sc,
struct iwm_vap *ivp, 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); cmd->ba_enable_beacon_abort = htole32(sc->sc_bf.ba_enabled);
} }
static void static void
iwm_mvm_power_log(struct iwm_softc *sc, struct iwm_mac_power_cmd *cmd) iwm_power_log(struct iwm_softc *sc, struct iwm_mac_power_cmd *cmd)
{ {
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD, IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
"Sending power table command on mac id 0x%X for " "Sending power table command on mac id 0x%X for "
@@ -232,7 +232,7 @@ iwm_mvm_power_log(struct iwm_softc *sc, struct iwm_mac_power_cmd *cmd)
} }
static boolean_t static boolean_t
iwm_mvm_power_is_radar(struct iwm_softc *sc) iwm_power_is_radar(struct iwm_softc *sc)
{ {
struct ieee80211com *ic = &sc->sc_ic; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_channel *chan; struct ieee80211_channel *chan;
@@ -248,7 +248,7 @@ iwm_mvm_power_is_radar(struct iwm_softc *sc)
} }
static void static void
iwm_mvm_power_config_skip_dtim(struct iwm_softc *sc, iwm_power_config_skip_dtim(struct iwm_softc *sc,
struct iwm_mac_power_cmd *cmd) struct iwm_mac_power_cmd *cmd)
{ {
struct ieee80211com *ic = &sc->sc_ic; struct ieee80211com *ic = &sc->sc_ic;
@@ -260,7 +260,7 @@ iwm_mvm_power_config_skip_dtim(struct iwm_softc *sc,
cmd->skip_dtim_periods = 0; cmd->skip_dtim_periods = 0;
cmd->flags &= ~htole16(IWM_POWER_FLAGS_SKIP_OVER_DTIM_MSK); cmd->flags &= ~htole16(IWM_POWER_FLAGS_SKIP_OVER_DTIM_MSK);
if (iwm_mvm_power_is_radar(sc)) if (iwm_power_is_radar(sc))
return; return;
if (dtimper >= 10) if (dtimper >= 10)
@@ -278,7 +278,7 @@ iwm_mvm_power_config_skip_dtim(struct iwm_softc *sc,
} }
static void static void
iwm_mvm_power_build_cmd(struct iwm_softc *sc, struct iwm_vap *ivp, iwm_power_build_cmd(struct iwm_softc *sc, struct iwm_vap *ivp,
struct iwm_mac_power_cmd *cmd) struct iwm_mac_power_cmd *cmd)
{ {
struct ieee80211vap *vap = &ivp->iv_vap; struct ieee80211vap *vap = &ivp->iv_vap;
@@ -317,34 +317,34 @@ iwm_mvm_power_build_cmd(struct iwm_softc *sc, struct iwm_vap *ivp,
cmd->flags |= htole16(IWM_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); cmd->flags |= htole16(IWM_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
iwm_mvm_power_config_skip_dtim(sc, cmd); iwm_power_config_skip_dtim(sc, cmd);
cmd->rx_data_timeout = cmd->rx_data_timeout =
htole32(IWM_MVM_DEFAULT_PS_RX_DATA_TIMEOUT); htole32(IWM_DEFAULT_PS_RX_DATA_TIMEOUT);
cmd->tx_data_timeout = cmd->tx_data_timeout =
htole32(IWM_MVM_DEFAULT_PS_TX_DATA_TIMEOUT); htole32(IWM_DEFAULT_PS_TX_DATA_TIMEOUT);
} }
static int static int
iwm_mvm_power_send_cmd(struct iwm_softc *sc, struct iwm_vap *ivp) iwm_power_send_cmd(struct iwm_softc *sc, struct iwm_vap *ivp)
{ {
struct iwm_mac_power_cmd cmd = {}; struct iwm_mac_power_cmd cmd = {};
iwm_mvm_power_build_cmd(sc, ivp, &cmd); iwm_power_build_cmd(sc, ivp, &cmd);
iwm_mvm_power_log(sc, &cmd); iwm_power_log(sc, &cmd);
return iwm_mvm_send_cmd_pdu(sc, IWM_MAC_PM_POWER_TABLE, 0, return iwm_send_cmd_pdu(sc, IWM_MAC_PM_POWER_TABLE, 0,
sizeof(cmd), &cmd); sizeof(cmd), &cmd);
} }
static int static int
_iwm_mvm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_vap *ivp, _iwm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_vap *ivp,
struct iwm_beacon_filter_cmd *cmd) struct iwm_beacon_filter_cmd *cmd)
{ {
int ret; int ret;
iwm_mvm_beacon_filter_set_cqm_params(sc, ivp, cmd); iwm_beacon_filter_set_cqm_params(sc, ivp, cmd);
ret = iwm_mvm_beacon_filter_send_cmd(sc, cmd); ret = iwm_beacon_filter_send_cmd(sc, cmd);
if (!ret) if (!ret)
sc->sc_bf.bf_enabled = 1; sc->sc_bf.bf_enabled = 1;
@@ -353,23 +353,23 @@ _iwm_mvm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_vap *ivp,
} }
int int
iwm_mvm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_vap *ivp) iwm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_vap *ivp)
{ {
struct iwm_beacon_filter_cmd cmd = { struct iwm_beacon_filter_cmd cmd = {
IWM_BF_CMD_CONFIG_DEFAULTS, IWM_BF_CMD_CONFIG_DEFAULTS,
.bf_enable_beacon_filter = htole32(1), .bf_enable_beacon_filter = htole32(1),
}; };
return _iwm_mvm_enable_beacon_filter(sc, ivp, &cmd); return _iwm_enable_beacon_filter(sc, ivp, &cmd);
} }
int int
iwm_mvm_disable_beacon_filter(struct iwm_softc *sc) iwm_disable_beacon_filter(struct iwm_softc *sc)
{ {
struct iwm_beacon_filter_cmd cmd = {}; struct iwm_beacon_filter_cmd cmd = {};
int ret; int ret;
ret = iwm_mvm_beacon_filter_send_cmd(sc, &cmd); ret = iwm_beacon_filter_send_cmd(sc, &cmd);
if (ret == 0) if (ret == 0)
sc->sc_bf.bf_enabled = 0; sc->sc_bf.bf_enabled = 0;
@@ -377,7 +377,7 @@ iwm_mvm_disable_beacon_filter(struct iwm_softc *sc)
} }
static int static int
iwm_mvm_power_set_ps(struct iwm_softc *sc) iwm_power_set_ps(struct iwm_softc *sc)
{ {
struct ieee80211vap *vap; struct ieee80211vap *vap;
boolean_t disable_ps; boolean_t disable_ps;
@@ -397,7 +397,7 @@ iwm_mvm_power_set_ps(struct iwm_softc *sc)
boolean_t old_ps_disabled = sc->sc_ps_disabled; boolean_t old_ps_disabled = sc->sc_ps_disabled;
sc->sc_ps_disabled = disable_ps; sc->sc_ps_disabled = disable_ps;
ret = iwm_mvm_power_update_device(sc); ret = iwm_power_update_device(sc);
if (ret) { if (ret) {
sc->sc_ps_disabled = old_ps_disabled; sc->sc_ps_disabled = old_ps_disabled;
return ret; return ret;
@@ -408,7 +408,7 @@ iwm_mvm_power_set_ps(struct iwm_softc *sc)
} }
static int static int
iwm_mvm_power_set_ba(struct iwm_softc *sc, struct iwm_vap *ivp) iwm_power_set_ba(struct iwm_softc *sc, struct iwm_vap *ivp)
{ {
struct iwm_beacon_filter_cmd cmd = { struct iwm_beacon_filter_cmd cmd = {
IWM_BF_CMD_CONFIG_DEFAULTS, IWM_BF_CMD_CONFIG_DEFAULTS,
@@ -427,49 +427,49 @@ iwm_mvm_power_set_ba(struct iwm_softc *sc, struct iwm_vap *ivp)
} }
sc->sc_bf.ba_enabled = !sc->sc_ps_disabled && bss_conf_ps; sc->sc_bf.ba_enabled = !sc->sc_ps_disabled && bss_conf_ps;
return _iwm_mvm_enable_beacon_filter(sc, ivp, &cmd); return _iwm_enable_beacon_filter(sc, ivp, &cmd);
} }
int int
iwm_mvm_power_update_ps(struct iwm_softc *sc) iwm_power_update_ps(struct iwm_softc *sc)
{ {
struct ieee80211vap *vap = TAILQ_FIRST(&sc->sc_ic.ic_vaps); struct ieee80211vap *vap = TAILQ_FIRST(&sc->sc_ic.ic_vaps);
int ret; int ret;
ret = iwm_mvm_power_set_ps(sc); ret = iwm_power_set_ps(sc);
if (ret) if (ret)
return ret; return ret;
if (vap != NULL) if (vap != NULL)
return iwm_mvm_power_set_ba(sc, IWM_VAP(vap)); return iwm_power_set_ba(sc, IWM_VAP(vap));
return 0; return 0;
} }
int int
iwm_mvm_power_update_mac(struct iwm_softc *sc) iwm_power_update_mac(struct iwm_softc *sc)
{ {
struct ieee80211vap *vap = TAILQ_FIRST(&sc->sc_ic.ic_vaps); struct ieee80211vap *vap = TAILQ_FIRST(&sc->sc_ic.ic_vaps);
int ret; int ret;
ret = iwm_mvm_power_set_ps(sc); ret = iwm_power_set_ps(sc);
if (ret) if (ret)
return ret; return ret;
if (vap != NULL) { if (vap != NULL) {
ret = iwm_mvm_power_send_cmd(sc, IWM_VAP(vap)); ret = iwm_power_send_cmd(sc, IWM_VAP(vap));
if (ret) if (ret)
return ret; return ret;
} }
if (vap != NULL) if (vap != NULL)
return iwm_mvm_power_set_ba(sc, IWM_VAP(vap)); return iwm_power_set_ba(sc, IWM_VAP(vap));
return 0; return 0;
} }
int int
iwm_mvm_power_update_device(struct iwm_softc *sc) iwm_power_update_device(struct iwm_softc *sc)
{ {
struct iwm_device_power_cmd cmd = { struct iwm_device_power_cmd cmd = {
.flags = 0, .flags = 0,
@@ -484,6 +484,6 @@ iwm_mvm_power_update_device(struct iwm_softc *sc)
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD, IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
"Sending device power command with flags = 0x%X\n", cmd.flags); "Sending device power command with flags = 0x%X\n", cmd.flags);
return iwm_mvm_send_cmd_pdu(sc, return iwm_send_cmd_pdu(sc,
IWM_POWER_TABLE_CMD, 0, sizeof(cmd), &cmd); IWM_POWER_TABLE_CMD, 0, sizeof(cmd), &cmd);
} }
@@ -1,5 +1,5 @@
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_power.h 318226 2017-05-12 06:30:06Z adrian $ */ /* $FreeBSD$ */
/* /*
* Copyright (c) 2014 genua mbh <info@genua.de> * Copyright (c) 2014 genua mbh <info@genua.de>
@@ -90,11 +90,11 @@
#ifndef __IF_IWM_POWER_H__ #ifndef __IF_IWM_POWER_H__
#define __IF_IWM_POWER_H__ #define __IF_IWM_POWER_H__
extern int iwm_mvm_power_update_device(struct iwm_softc *sc); extern int iwm_power_update_device(struct iwm_softc *sc);
extern int iwm_mvm_power_update_mac(struct iwm_softc *sc); extern int iwm_power_update_mac(struct iwm_softc *sc);
extern int iwm_mvm_power_update_ps(struct iwm_softc *sc); extern int iwm_power_update_ps(struct iwm_softc *sc);
extern int iwm_mvm_enable_beacon_filter(struct iwm_softc *sc, extern int iwm_enable_beacon_filter(struct iwm_softc *sc,
struct iwm_vap *ivp); struct iwm_vap *ivp);
extern int iwm_mvm_disable_beacon_filter(struct iwm_softc *sc); extern int iwm_disable_beacon_filter(struct iwm_softc *sc);
#endif /* __IF_IWM_POWER_H__ */ #endif /* __IF_IWM_POWER_H__ */
@@ -103,7 +103,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_scan.c 321507 2017-07-26 05:26:01Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -166,12 +166,12 @@ __FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_scan.c 321507 2017-07-26 05:2
#define IWM_SPARSE_EBS_SCAN_RATIO 1 #define IWM_SPARSE_EBS_SCAN_RATIO 1
static uint16_t static uint16_t
iwm_mvm_scan_rx_chain(struct iwm_softc *sc) iwm_scan_rx_chain(struct iwm_softc *sc)
{ {
uint16_t rx_chain; uint16_t rx_chain;
uint8_t rx_ant; uint8_t rx_ant;
rx_ant = iwm_mvm_get_valid_rx_ant(sc); rx_ant = iwm_get_valid_rx_ant(sc);
rx_chain = rx_ant << IWM_PHY_RX_CHAIN_VALID_POS; rx_chain = rx_ant << IWM_PHY_RX_CHAIN_VALID_POS;
rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_MIMO_SEL_POS; rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_SEL_POS; rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_SEL_POS;
@@ -180,7 +180,7 @@ iwm_mvm_scan_rx_chain(struct iwm_softc *sc)
} }
static uint32_t static uint32_t
iwm_mvm_scan_rxon_flags(struct ieee80211_channel *c) iwm_scan_rxon_flags(struct ieee80211_channel *c)
{ {
if (IEEE80211_IS_CHAN_2GHZ(c)) if (IEEE80211_IS_CHAN_2GHZ(c))
return htole32(IWM_PHY_BAND_24); return htole32(IWM_PHY_BAND_24);
@@ -189,7 +189,7 @@ iwm_mvm_scan_rxon_flags(struct ieee80211_channel *c)
} }
static uint32_t static uint32_t
iwm_mvm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck) iwm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck)
{ {
uint32_t tx_ant; uint32_t tx_ant;
int i, ind; int i, ind;
@@ -197,7 +197,7 @@ iwm_mvm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck)
for (i = 0, ind = sc->sc_scan_last_antenna; for (i = 0, ind = sc->sc_scan_last_antenna;
i < IWM_RATE_MCS_ANT_NUM; i++) { i < IWM_RATE_MCS_ANT_NUM; i++) {
ind = (ind + 1) % IWM_RATE_MCS_ANT_NUM; ind = (ind + 1) % IWM_RATE_MCS_ANT_NUM;
if (iwm_mvm_get_valid_tx_ant(sc) & (1 << ind)) { if (iwm_get_valid_tx_ant(sc) & (1 << ind)) {
sc->sc_scan_last_antenna = ind; sc->sc_scan_last_antenna = ind;
break; break;
} }
@@ -212,16 +212,15 @@ iwm_mvm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck)
} }
static inline boolean_t static inline boolean_t
iwm_mvm_rrm_scan_needed(struct iwm_softc *sc) iwm_rrm_scan_needed(struct iwm_softc *sc)
{ {
/* require rrm scan whenever the fw supports it */ /* require rrm scan whenever the fw supports it */
return fw_has_capa(&sc->sc_fw.ucode_capa, return iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT);
IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT);
} }
#ifdef IWM_DEBUG #ifdef IWM_DEBUG
static const char * static const char *
iwm_mvm_ebs_status_str(enum iwm_scan_ebs_status status) iwm_ebs_status_str(enum iwm_scan_ebs_status status)
{ {
switch (status) { switch (status) {
case IWM_SCAN_EBS_SUCCESS: case IWM_SCAN_EBS_SUCCESS:
@@ -236,14 +235,14 @@ iwm_mvm_ebs_status_str(enum iwm_scan_ebs_status status)
} }
static const char * static const char *
iwm_mvm_offload_status_str(enum iwm_scan_offload_complete_status status) iwm_offload_status_str(enum iwm_scan_offload_complete_status status)
{ {
return (status == IWM_SCAN_OFFLOAD_ABORTED) ? "aborted" : "completed"; return (status == IWM_SCAN_OFFLOAD_ABORTED) ? "aborted" : "completed";
} }
#endif #endif
void void
iwm_mvm_rx_lmac_scan_complete_notif(struct iwm_softc *sc, iwm_rx_lmac_scan_complete_notif(struct iwm_softc *sc,
struct iwm_rx_packet *pkt) struct iwm_rx_packet *pkt)
{ {
struct iwm_periodic_scan_complete *scan_notif = (void *)pkt->data; struct iwm_periodic_scan_complete *scan_notif = (void *)pkt->data;
@@ -251,7 +250,7 @@ iwm_mvm_rx_lmac_scan_complete_notif(struct iwm_softc *sc,
/* If this happens, the firmware has mistakenly sent an LMAC /* If this happens, the firmware has mistakenly sent an LMAC
* notification during UMAC scans -- warn and ignore it. * notification during UMAC scans -- warn and ignore it.
*/ */
if (fw_has_capa(&sc->sc_fw.ucode_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) { if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) {
device_printf(sc->sc_dev, device_printf(sc->sc_dev,
"%s: Mistakenly got LMAC notification during UMAC scan\n", "%s: Mistakenly got LMAC notification during UMAC scan\n",
__func__); __func__);
@@ -259,8 +258,8 @@ iwm_mvm_rx_lmac_scan_complete_notif(struct iwm_softc *sc,
} }
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Regular scan %s, EBS status %s (FW)\n", IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Regular scan %s, EBS status %s (FW)\n",
iwm_mvm_offload_status_str(scan_notif->status), iwm_offload_status_str(scan_notif->status),
iwm_mvm_ebs_status_str(scan_notif->ebs_status)); iwm_ebs_status_str(scan_notif->ebs_status));
sc->last_ebs_successful = sc->last_ebs_successful =
scan_notif->ebs_status == IWM_SCAN_EBS_SUCCESS || scan_notif->ebs_status == IWM_SCAN_EBS_SUCCESS ||
@@ -269,7 +268,7 @@ iwm_mvm_rx_lmac_scan_complete_notif(struct iwm_softc *sc,
} }
void void
iwm_mvm_rx_umac_scan_complete_notif(struct iwm_softc *sc, iwm_rx_umac_scan_complete_notif(struct iwm_softc *sc,
struct iwm_rx_packet *pkt) struct iwm_rx_packet *pkt)
{ {
struct iwm_umac_scan_complete *notif = (void *)pkt->data; struct iwm_umac_scan_complete *notif = (void *)pkt->data;
@@ -277,8 +276,8 @@ iwm_mvm_rx_umac_scan_complete_notif(struct iwm_softc *sc,
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
"Scan completed, uid %u, status %s, EBS status %s\n", "Scan completed, uid %u, status %s, EBS status %s\n",
le32toh(notif->uid), le32toh(notif->uid),
iwm_mvm_offload_status_str(notif->status), iwm_offload_status_str(notif->status),
iwm_mvm_ebs_status_str(notif->ebs_status)); iwm_ebs_status_str(notif->ebs_status));
if (notif->ebs_status != IWM_SCAN_EBS_SUCCESS && if (notif->ebs_status != IWM_SCAN_EBS_SUCCESS &&
notif->ebs_status != IWM_SCAN_EBS_INACTIVE) notif->ebs_status != IWM_SCAN_EBS_INACTIVE)
@@ -286,7 +285,7 @@ iwm_mvm_rx_umac_scan_complete_notif(struct iwm_softc *sc,
} }
static int static int
iwm_mvm_scan_skip_channel(struct ieee80211_channel *c) iwm_scan_skip_channel(struct ieee80211_channel *c)
{ {
if (IEEE80211_IS_CHAN_2GHZ(c) && IEEE80211_IS_CHAN_B(c)) if (IEEE80211_IS_CHAN_2GHZ(c) && IEEE80211_IS_CHAN_B(c))
return 0; return 0;
@@ -297,7 +296,7 @@ iwm_mvm_scan_skip_channel(struct ieee80211_channel *c)
} }
static uint8_t static uint8_t
iwm_mvm_lmac_scan_fill_channels(struct iwm_softc *sc, iwm_lmac_scan_fill_channels(struct iwm_softc *sc,
struct iwm_scan_channel_cfg_lmac *chan, int n_ssids) struct iwm_scan_channel_cfg_lmac *chan, int n_ssids)
{ {
struct ieee80211com *ic = &sc->sc_ic; struct ieee80211com *ic = &sc->sc_ic;
@@ -341,7 +340,7 @@ iwm_mvm_lmac_scan_fill_channels(struct iwm_softc *sc,
} }
static uint8_t static uint8_t
iwm_mvm_umac_scan_fill_channels(struct iwm_softc *sc, iwm_umac_scan_fill_channels(struct iwm_softc *sc,
struct iwm_scan_channel_cfg_umac *chan, int n_ssids) struct iwm_scan_channel_cfg_umac *chan, int n_ssids)
{ {
struct ieee80211com *ic = &sc->sc_ic; struct ieee80211com *ic = &sc->sc_ic;
@@ -380,7 +379,7 @@ iwm_mvm_umac_scan_fill_channels(struct iwm_softc *sc,
} }
static int static int
iwm_mvm_fill_probe_req(struct iwm_softc *sc, struct iwm_scan_probe_req *preq) iwm_fill_probe_req(struct iwm_softc *sc, struct iwm_scan_probe_req *preq)
{ {
struct ieee80211com *ic = &sc->sc_ic; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
@@ -432,7 +431,7 @@ iwm_mvm_fill_probe_req(struct iwm_softc *sc, struct iwm_scan_probe_req *preq)
preq->band_data[0].len = htole16(frm - pos); preq->band_data[0].len = htole16(frm - pos);
remain -= frm - pos; remain -= frm - pos;
if (iwm_mvm_rrm_scan_needed(sc)) { if (iwm_rrm_scan_needed(sc)) {
if (remain < 3) if (remain < 3)
return ENOBUFS; return ENOBUFS;
*frm++ = IEEE80211_ELEMID_DSPARMS; *frm++ = IEEE80211_ELEMID_DSPARMS;
@@ -476,7 +475,7 @@ iwm_mvm_fill_probe_req(struct iwm_softc *sc, struct iwm_scan_probe_req *preq)
} }
int int
iwm_mvm_config_umac_scan(struct iwm_softc *sc) iwm_config_umac_scan(struct iwm_softc *sc)
{ {
struct ieee80211com *ic = &sc->sc_ic; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
@@ -503,8 +502,8 @@ iwm_mvm_config_umac_scan(struct iwm_softc *sc)
if (scan_config == NULL) if (scan_config == NULL)
return ENOMEM; return ENOMEM;
scan_config->tx_chains = htole32(iwm_mvm_get_valid_tx_ant(sc)); scan_config->tx_chains = htole32(iwm_get_valid_tx_ant(sc));
scan_config->rx_chains = htole32(iwm_mvm_get_valid_rx_ant(sc)); scan_config->rx_chains = htole32(iwm_get_valid_rx_ant(sc));
scan_config->legacy_rates = htole32(rates | scan_config->legacy_rates = htole32(rates |
IWM_SCAN_CONFIG_SUPPORTED_RATE(rates)); IWM_SCAN_CONFIG_SUPPORTED_RATE(rates));
@@ -534,7 +533,7 @@ iwm_mvm_config_umac_scan(struct iwm_softc *sc)
* Catch other channels, in case we have 900MHz channels or * Catch other channels, in case we have 900MHz channels or
* something in the chanlist. * something in the chanlist.
*/ */
if (iwm_mvm_scan_skip_channel(c)) if (iwm_scan_skip_channel(c))
continue; continue;
scan_config->channel_array[nchan++] = scan_config->channel_array[nchan++] =
ieee80211_mhz2ieee(c->ic_freq, 0); ieee80211_mhz2ieee(c->ic_freq, 0);
@@ -567,7 +566,7 @@ iwm_mvm_config_umac_scan(struct iwm_softc *sc)
} }
static boolean_t static boolean_t
iwm_mvm_scan_use_ebs(struct iwm_softc *sc) iwm_scan_use_ebs(struct iwm_softc *sc)
{ {
const struct iwm_ucode_capabilities *capa = &sc->sc_fw.ucode_capa; const struct iwm_ucode_capabilities *capa = &sc->sc_fw.ucode_capa;
@@ -581,8 +580,31 @@ iwm_mvm_scan_use_ebs(struct iwm_softc *sc)
sc->last_ebs_successful); sc->last_ebs_successful);
} }
static int
iwm_scan_size(struct iwm_softc *sc)
{
int base_size;
if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) {
if (iwm_fw_has_api(sc, IWM_UCODE_TLV_API_ADAPTIVE_DWELL))
base_size = IWM_SCAN_REQ_UMAC_SIZE_V7;
else
base_size = IWM_SCAN_REQ_UMAC_SIZE_V1;
return base_size +
sizeof(struct iwm_scan_channel_cfg_umac) *
sc->sc_fw.ucode_capa.n_scan_channels +
sizeof(struct iwm_scan_req_umac_tail);
} else {
return sizeof(struct iwm_scan_req_lmac) +
sizeof(struct iwm_scan_channel_cfg_lmac) *
sc->sc_fw.ucode_capa.n_scan_channels +
sizeof(struct iwm_scan_probe_req);
}
}
int int
iwm_mvm_umac_scan(struct iwm_softc *sc) iwm_umac_scan(struct iwm_softc *sc)
{ {
struct iwm_host_cmd hcmd = { struct iwm_host_cmd hcmd = {
.id = iwm_cmd_id(IWM_SCAN_REQ_UMAC, IWM_ALWAYS_LONG_GROUP, 0), .id = iwm_cmd_id(IWM_SCAN_REQ_UMAC, IWM_ALWAYS_LONG_GROUP, 0),
@@ -594,13 +616,11 @@ iwm_mvm_umac_scan(struct iwm_softc *sc)
struct iwm_scan_req_umac *req; struct iwm_scan_req_umac *req;
struct iwm_scan_req_umac_tail *tail; struct iwm_scan_req_umac_tail *tail;
size_t req_len; size_t req_len;
uint8_t i, nssid; uint16_t general_flags;
uint8_t channel_flags, i, nssid;
int ret; int ret;
req_len = sizeof(struct iwm_scan_req_umac) + req_len = iwm_scan_size(sc);
(sizeof(struct iwm_scan_channel_cfg_umac) *
sc->sc_fw.ucode_capa.n_scan_channels) +
sizeof(struct iwm_scan_req_umac_tail);
if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE) if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
return ENOMEM; return ENOMEM;
req = malloc(req_len, M_DEVBUF, M_NOWAIT | M_ZERO); req = malloc(req_len, M_DEVBUF, M_NOWAIT | M_ZERO);
@@ -612,28 +632,58 @@ iwm_mvm_umac_scan(struct iwm_softc *sc)
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Handling ieee80211 scan request\n"); IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Handling ieee80211 scan request\n");
/* These timings correspond to iwlwifi's UNASSOC scan. */ nssid = MIN(ss->ss_nssid, IWM_PROBE_OPTION_MAX);
req->active_dwell = 10;
req->passive_dwell = 110;
req->fragmented_dwell = 44;
req->extended_dwell = 90;
req->max_out_time = 0;
req->suspend_time = 0;
req->scan_priority = htole32(IWM_SCAN_PRIORITY_HIGH); general_flags = IWM_UMAC_SCAN_GEN_FLAGS_PASS_ALL |
IWM_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE;
if (!iwm_fw_has_api(sc, IWM_UCODE_TLV_API_ADAPTIVE_DWELL))
general_flags |= IWM_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL;
if (iwm_rrm_scan_needed(sc))
general_flags |= IWM_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED;
if (nssid != 0)
general_flags |= IWM_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT;
else
general_flags |= IWM_UMAC_SCAN_GEN_FLAGS_PASSIVE;
channel_flags = 0;
if (iwm_scan_use_ebs(sc))
channel_flags = IWM_SCAN_CHANNEL_FLAG_EBS |
IWM_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
IWM_SCAN_CHANNEL_FLAG_CACHE_ADD;
req->general_flags = htole16(general_flags);
req->ooc_priority = htole32(IWM_SCAN_PRIORITY_HIGH); req->ooc_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
nssid = MIN(ss->ss_nssid, IWM_PROBE_OPTION_MAX); /* These timings correspond to iwlwifi's UNASSOC scan. */
req->n_channels = iwm_mvm_umac_scan_fill_channels(sc, if (iwm_fw_has_api(sc, IWM_UCODE_TLV_API_ADAPTIVE_DWELL)) {
(struct iwm_scan_channel_cfg_umac *)req->data, nssid); req->v7.active_dwell = 10;
req->v7.passive_dwell = 110;
req->v7.fragmented_dwell = 44;
req->v7.adwell_default_n_aps_social = 10;
req->v7.adwell_default_n_aps = 2;
req->v7.adwell_max_budget = htole16(300);
req->v7.scan_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
req->v7.channel.flags = channel_flags;
req->v7.channel.count = iwm_umac_scan_fill_channels(sc,
(struct iwm_scan_channel_cfg_umac *)req->v7.data, nssid);
req->general_flags = htole32(IWM_UMAC_SCAN_GEN_FLAGS_PASS_ALL | tail = (void *)((char *)&req->v7.data +
IWM_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE |
IWM_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL);
tail = (void *)((char *)&req->data +
sizeof(struct iwm_scan_channel_cfg_umac) * sizeof(struct iwm_scan_channel_cfg_umac) *
sc->sc_fw.ucode_capa.n_scan_channels); sc->sc_fw.ucode_capa.n_scan_channels);
} else {
req->v1.active_dwell = 10;
req->v1.passive_dwell = 110;
req->v1.fragmented_dwell = 44;
req->v1.extended_dwell = 90;
req->v1.scan_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
req->v1.channel.flags = channel_flags;
req->v1.channel.count = iwm_umac_scan_fill_channels(sc,
(struct iwm_scan_channel_cfg_umac *)req->v1.data, nssid);
tail = (void *)((char *)&req->v1.data +
sizeof(struct iwm_scan_channel_cfg_umac) *
sc->sc_fw.ucode_capa.n_scan_channels);
}
/* Check if we're doing an active directed scan. */ /* Check if we're doing an active directed scan. */
for (i = 0; i < nssid; i++) { for (i = 0; i < nssid; i++) {
@@ -644,22 +694,8 @@ iwm_mvm_umac_scan(struct iwm_softc *sc)
tail->direct_scan[i].len); tail->direct_scan[i].len);
/* XXX debug */ /* XXX debug */
} }
if (nssid != 0) {
req->general_flags |=
htole32(IWM_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT);
} else
req->general_flags |= htole32(IWM_UMAC_SCAN_GEN_FLAGS_PASSIVE);
if (iwm_mvm_scan_use_ebs(sc)) ret = iwm_fill_probe_req(sc, &tail->preq);
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);
ret = iwm_mvm_fill_probe_req(sc, &tail->preq);
if (ret) { if (ret) {
free(req, M_DEVBUF); free(req, M_DEVBUF);
return ret; return ret;
@@ -678,7 +714,7 @@ iwm_mvm_umac_scan(struct iwm_softc *sc)
} }
int int
iwm_mvm_lmac_scan(struct iwm_softc *sc) iwm_lmac_scan(struct iwm_softc *sc)
{ {
struct iwm_host_cmd hcmd = { struct iwm_host_cmd hcmd = {
.id = IWM_SCAN_OFFLOAD_REQUEST_CMD, .id = IWM_SCAN_OFFLOAD_REQUEST_CMD,
@@ -695,9 +731,7 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc)
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
"Handling ieee80211 scan request\n"); "Handling ieee80211 scan request\n");
req_len = sizeof(struct iwm_scan_req_lmac) + req_len = iwm_scan_size(sc);
(sizeof(struct iwm_scan_channel_cfg_lmac) *
sc->sc_fw.ucode_capa.n_scan_channels) + sizeof(struct iwm_scan_probe_req);
if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE) if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
return ENOMEM; return ENOMEM;
req = malloc(req_len, M_DEVBUF, M_NOWAIT | M_ZERO); req = malloc(req_len, M_DEVBUF, M_NOWAIT | M_ZERO);
@@ -716,17 +750,17 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc)
req->suspend_time = 0; req->suspend_time = 0;
req->scan_prio = htole32(IWM_SCAN_PRIORITY_HIGH); req->scan_prio = htole32(IWM_SCAN_PRIORITY_HIGH);
req->rx_chain_select = iwm_mvm_scan_rx_chain(sc); req->rx_chain_select = iwm_scan_rx_chain(sc);
req->iter_num = htole32(1); req->iter_num = htole32(1);
req->delay = 0; req->delay = 0;
req->scan_flags = htole32(IWM_MVM_LMAC_SCAN_FLAG_PASS_ALL | req->scan_flags = htole32(IWM_LMAC_SCAN_FLAG_PASS_ALL |
IWM_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE | IWM_LMAC_SCAN_FLAG_ITER_COMPLETE |
IWM_MVM_LMAC_SCAN_FLAG_EXTENDED_DWELL); IWM_LMAC_SCAN_FLAG_EXTENDED_DWELL);
if (iwm_mvm_rrm_scan_needed(sc)) if (iwm_rrm_scan_needed(sc))
req->scan_flags |= htole32(IWM_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); req->scan_flags |= htole32(IWM_LMAC_SCAN_FLAGS_RRM_ENABLED);
req->flags = iwm_mvm_scan_rxon_flags(sc->sc_ic.ic_scan->ss_chans[0]); req->flags = iwm_scan_rxon_flags(sc->sc_ic.ic_scan->ss_chans[0]);
req->filter_flags = req->filter_flags =
htole32(IWM_MAC_FILTER_ACCEPT_GRP | IWM_MAC_FILTER_IN_BEACON); htole32(IWM_MAC_FILTER_ACCEPT_GRP | IWM_MAC_FILTER_IN_BEACON);
@@ -735,14 +769,14 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc)
req->tx_cmd[0].tx_flags = htole32(IWM_TX_CMD_FLG_SEQ_CTL | req->tx_cmd[0].tx_flags = htole32(IWM_TX_CMD_FLG_SEQ_CTL |
IWM_TX_CMD_FLG_BT_DIS); IWM_TX_CMD_FLG_BT_DIS);
req->tx_cmd[0].rate_n_flags = req->tx_cmd[0].rate_n_flags =
iwm_mvm_scan_rate_n_flags(sc, IEEE80211_CHAN_2GHZ, 1/*XXX*/); iwm_scan_rate_n_flags(sc, IEEE80211_CHAN_2GHZ, 1/*XXX*/);
req->tx_cmd[0].sta_id = sc->sc_aux_sta.sta_id; req->tx_cmd[0].sta_id = sc->sc_aux_sta.sta_id;
/* Tx flags 5 GHz. */ /* Tx flags 5 GHz. */
req->tx_cmd[1].tx_flags = htole32(IWM_TX_CMD_FLG_SEQ_CTL | req->tx_cmd[1].tx_flags = htole32(IWM_TX_CMD_FLG_SEQ_CTL |
IWM_TX_CMD_FLG_BT_DIS); IWM_TX_CMD_FLG_BT_DIS);
req->tx_cmd[1].rate_n_flags = req->tx_cmd[1].rate_n_flags =
iwm_mvm_scan_rate_n_flags(sc, IEEE80211_CHAN_5GHZ, 1/*XXX*/); iwm_scan_rate_n_flags(sc, IEEE80211_CHAN_5GHZ, 1/*XXX*/);
req->tx_cmd[1].sta_id = sc->sc_aux_sta.sta_id; req->tx_cmd[1].sta_id = sc->sc_aux_sta.sta_id;
/* Check if we're doing an active directed scan. */ /* Check if we're doing an active directed scan. */
@@ -757,14 +791,14 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc)
} }
if (nssid != 0) { if (nssid != 0) {
req->scan_flags |= req->scan_flags |=
htole32(IWM_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION); htole32(IWM_LMAC_SCAN_FLAG_PRE_CONNECTION);
} else } else
req->scan_flags |= htole32(IWM_MVM_LMAC_SCAN_FLAG_PASSIVE); req->scan_flags |= htole32(IWM_LMAC_SCAN_FLAG_PASSIVE);
req->n_channels = iwm_mvm_lmac_scan_fill_channels(sc, req->n_channels = iwm_lmac_scan_fill_channels(sc,
(struct iwm_scan_channel_cfg_lmac *)req->data, nssid); (struct iwm_scan_channel_cfg_lmac *)req->data, nssid);
ret = iwm_mvm_fill_probe_req(sc, ret = iwm_fill_probe_req(sc,
(struct iwm_scan_probe_req *)(req->data + (struct iwm_scan_probe_req *)(req->data +
(sizeof(struct iwm_scan_channel_cfg_lmac) * (sizeof(struct iwm_scan_channel_cfg_lmac) *
sc->sc_fw.ucode_capa.n_scan_channels))); sc->sc_fw.ucode_capa.n_scan_channels)));
@@ -777,7 +811,7 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc)
req->schedule[0].iterations = 1; req->schedule[0].iterations = 1;
req->schedule[0].full_scan_mul = 1; req->schedule[0].full_scan_mul = 1;
if (iwm_mvm_scan_use_ebs(sc)) { if (iwm_scan_use_ebs(sc)) {
req->channel_opt[0].flags = req->channel_opt[0].flags =
htole16(IWM_SCAN_CHANNEL_FLAG_EBS | htole16(IWM_SCAN_CHANNEL_FLAG_EBS |
IWM_SCAN_CHANNEL_FLAG_EBS_ACCURATE | IWM_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
@@ -802,7 +836,7 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc)
} }
static int static int
iwm_mvm_lmac_scan_abort(struct iwm_softc *sc) iwm_lmac_scan_abort(struct iwm_softc *sc)
{ {
int ret; int ret;
struct iwm_host_cmd hcmd = { struct iwm_host_cmd hcmd = {
@@ -813,7 +847,7 @@ iwm_mvm_lmac_scan_abort(struct iwm_softc *sc)
}; };
uint32_t status; uint32_t status;
ret = iwm_mvm_send_cmd_status(sc, &hcmd, &status); ret = iwm_send_cmd_status(sc, &hcmd, &status);
if (ret) if (ret)
return ret; return ret;
@@ -834,7 +868,7 @@ iwm_mvm_lmac_scan_abort(struct iwm_softc *sc)
} }
static int static int
iwm_mvm_umac_scan_abort(struct iwm_softc *sc) iwm_umac_scan_abort(struct iwm_softc *sc)
{ {
struct iwm_umac_scan_abort cmd = {}; struct iwm_umac_scan_abort cmd = {};
int uid, ret; int uid, ret;
@@ -844,7 +878,7 @@ iwm_mvm_umac_scan_abort(struct iwm_softc *sc)
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Sending scan abort, uid %u\n", uid); IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Sending scan abort, uid %u\n", uid);
ret = iwm_mvm_send_cmd_pdu(sc, ret = iwm_send_cmd_pdu(sc,
iwm_cmd_id(IWM_SCAN_ABORT_UMAC, iwm_cmd_id(IWM_SCAN_ABORT_UMAC,
IWM_ALWAYS_LONG_GROUP, 0), IWM_ALWAYS_LONG_GROUP, 0),
0, sizeof(cmd), &cmd); 0, sizeof(cmd), &cmd);
@@ -853,7 +887,7 @@ iwm_mvm_umac_scan_abort(struct iwm_softc *sc)
} }
int int
iwm_mvm_scan_stop_wait(struct iwm_softc *sc) iwm_scan_stop_wait(struct iwm_softc *sc)
{ {
struct iwm_notification_wait wait_scan_done; struct iwm_notification_wait wait_scan_done;
static const uint16_t scan_done_notif[] = { IWM_SCAN_COMPLETE_UMAC, static const uint16_t scan_done_notif[] = { IWM_SCAN_COMPLETE_UMAC,
@@ -866,10 +900,10 @@ iwm_mvm_scan_stop_wait(struct iwm_softc *sc)
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Preparing to stop scan\n"); IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Preparing to stop scan\n");
if (fw_has_capa(&sc->sc_fw.ucode_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_UMAC_SCAN))
ret = iwm_mvm_umac_scan_abort(sc); ret = iwm_umac_scan_abort(sc);
else else
ret = iwm_mvm_lmac_scan_abort(sc); ret = iwm_lmac_scan_abort(sc);
if (ret) { if (ret) {
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "couldn't stop scan\n"); IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "couldn't stop scan\n");
@@ -1,5 +1,5 @@
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_scan.h 315925 2017-03-25 02:49:20Z adrian $ */ /* $FreeBSD$ */
/* /*
* Copyright (c) 2014 genua mbh <info@genua.de> * Copyright (c) 2014 genua mbh <info@genua.de>
@@ -106,13 +106,13 @@
#ifndef __IF_IWN_SCAN_H__ #ifndef __IF_IWN_SCAN_H__
#define __IF_IWN_SCAN_H__ #define __IF_IWN_SCAN_H__
extern int iwm_mvm_lmac_scan(struct iwm_softc *); extern int iwm_lmac_scan(struct iwm_softc *);
extern int iwm_mvm_config_umac_scan(struct iwm_softc *); extern int iwm_config_umac_scan(struct iwm_softc *);
extern int iwm_mvm_umac_scan(struct iwm_softc *); extern int iwm_umac_scan(struct iwm_softc *);
extern int iwm_mvm_scan_stop_wait(struct iwm_softc *); extern int iwm_scan_stop_wait(struct iwm_softc *);
extern void iwm_mvm_rx_lmac_scan_complete_notif(struct iwm_softc *, extern void iwm_rx_lmac_scan_complete_notif(struct iwm_softc *,
struct iwm_rx_packet *); struct iwm_rx_packet *);
extern void iwm_mvm_rx_umac_scan_complete_notif(struct iwm_softc *, extern void iwm_rx_umac_scan_complete_notif(struct iwm_softc *,
struct iwm_rx_packet *); struct iwm_rx_packet *);
#endif /* __IF_IWN_SCAN_H__ */ #endif /* __IF_IWN_SCAN_H__ */
@@ -88,7 +88,7 @@
*****************************************************************************/ *****************************************************************************/
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_sf.c 319580 2017-06-04 21:12:11Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -196,7 +196,7 @@ sf_full_timeout[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = {
}; };
static void static void
iwm_mvm_fill_sf_command(struct iwm_softc *sc, struct iwm_sf_cfg_cmd *sf_cmd, iwm_fill_sf_command(struct iwm_softc *sc, struct iwm_sf_cfg_cmd *sf_cmd,
struct ieee80211_node *ni) struct ieee80211_node *ni)
{ {
int i, j, watermark; int i, j, watermark;
@@ -244,7 +244,7 @@ iwm_mvm_fill_sf_command(struct iwm_softc *sc, struct iwm_sf_cfg_cmd *sf_cmd,
} }
static int static int
iwm_mvm_sf_config(struct iwm_softc *sc, struct ieee80211_node *ni, iwm_sf_config(struct iwm_softc *sc, struct ieee80211_node *ni,
enum iwm_sf_state new_state) enum iwm_sf_state new_state)
{ {
struct iwm_sf_cfg_cmd sf_cmd = { struct iwm_sf_cfg_cmd sf_cmd = {
@@ -266,13 +266,13 @@ iwm_mvm_sf_config(struct iwm_softc *sc, struct ieee80211_node *ni,
switch (new_state) { switch (new_state) {
case IWM_SF_UNINIT: case IWM_SF_UNINIT:
iwm_mvm_fill_sf_command(sc, &sf_cmd, NULL); iwm_fill_sf_command(sc, &sf_cmd, NULL);
break; break;
case IWM_SF_FULL_ON: case IWM_SF_FULL_ON:
iwm_mvm_fill_sf_command(sc, &sf_cmd, ni); iwm_fill_sf_command(sc, &sf_cmd, ni);
break; break;
case IWM_SF_INIT_OFF: case IWM_SF_INIT_OFF:
iwm_mvm_fill_sf_command(sc, &sf_cmd, NULL); iwm_fill_sf_command(sc, &sf_cmd, NULL);
break; break;
default: default:
device_printf(sc->sc_dev, device_printf(sc->sc_dev,
@@ -281,7 +281,7 @@ iwm_mvm_sf_config(struct iwm_softc *sc, struct ieee80211_node *ni,
return EINVAL; return EINVAL;
} }
ret = iwm_mvm_send_cmd_pdu(sc, IWM_REPLY_SF_CFG_CMD, IWM_CMD_ASYNC, ret = iwm_send_cmd_pdu(sc, IWM_REPLY_SF_CFG_CMD, IWM_CMD_ASYNC,
sizeof(sf_cmd), &sf_cmd); sizeof(sf_cmd), &sf_cmd);
if (!ret) if (!ret)
sc->sf_state = new_state; sc->sf_state = new_state;
@@ -295,7 +295,7 @@ iwm_mvm_sf_config(struct iwm_softc *sc, struct ieee80211_node *ni,
* and set new state accordingly. * and set new state accordingly.
*/ */
int int
iwm_mvm_sf_update(struct iwm_softc *sc, struct ieee80211vap *changed_vif, iwm_sf_update(struct iwm_softc *sc, struct ieee80211vap *changed_vif,
boolean_t remove_vif) boolean_t remove_vif)
{ {
enum iwm_sf_state new_state; enum iwm_sf_state new_state;
@@ -326,5 +326,5 @@ iwm_mvm_sf_update(struct iwm_softc *sc, struct ieee80211vap *changed_vif,
/* If there are multiple active macs - change to SF_UNINIT */ /* If there are multiple active macs - change to SF_UNINIT */
new_state = IWM_SF_UNINIT; new_state = IWM_SF_UNINIT;
} }
return iwm_mvm_sf_config(sc, ni, new_state); return iwm_sf_config(sc, ni, new_state);
} }
@@ -70,12 +70,12 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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 $ * $FreeBSD$
*/ */
#ifndef __IF_IWM_SF_H__ #ifndef __IF_IWM_SF_H__
#define __IF_IWM_SF_H__ #define __IF_IWM_SF_H__
extern int iwm_mvm_sf_update(struct iwm_softc *sc, extern int iwm_sf_update(struct iwm_softc *sc,
struct ieee80211vap *changed_vif, struct ieee80211vap *changed_vif,
boolean_t remove_vif); boolean_t remove_vif);
@@ -73,7 +73,7 @@
*****************************************************************************/ *****************************************************************************/
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_sta.c 321508 2017-07-26 05:29:08Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -136,24 +136,19 @@ __FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_sta.c 321508 2017-07-26 05:29
* support both API versions. * support both API versions.
*/ */
static inline int static inline int
iwm_mvm_add_sta_cmd_size(struct iwm_softc *sc) iwm_add_sta_cmd_size(struct iwm_softc *sc)
{ {
#ifdef notyet return sc->cfg->mqrx_supported ? sizeof(struct iwm_add_sta_cmd) :
return iwm_mvm_has_new_rx_api(mvm) ? sizeof(struct iwm_add_sta_cmd_v7);
sizeof(struct iwm_mvm_add_sta_cmd) :
sizeof(struct iwm_mvm_add_sta_cmd_v7);
#else
return sizeof(struct iwm_mvm_add_sta_cmd);
#endif
} }
/* send station add/update command to firmware */ /* send station add/update command to firmware */
int int
iwm_mvm_sta_send_to_fw(struct iwm_softc *sc, struct iwm_node *in, iwm_sta_send_to_fw(struct iwm_softc *sc, struct iwm_node *in,
boolean_t update) boolean_t update)
{ {
struct iwm_vap *ivp = IWM_VAP(in->in_ni.ni_vap); struct iwm_vap *ivp = IWM_VAP(in->in_ni.ni_vap);
struct iwm_mvm_add_sta_cmd add_sta_cmd = { struct iwm_add_sta_cmd add_sta_cmd = {
.sta_id = IWM_STATION_ID, .sta_id = IWM_STATION_ID,
.mac_id_n_color = .mac_id_n_color =
htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id, ivp->color)), htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id, ivp->color)),
@@ -170,7 +165,7 @@ iwm_mvm_sta_send_to_fw(struct iwm_softc *sc, struct iwm_node *in,
int ac; int ac;
for (ac = 0; ac < WME_NUM_AC; ac++) { for (ac = 0; ac < WME_NUM_AC; ac++) {
add_sta_cmd.tfd_queue_msk |= add_sta_cmd.tfd_queue_msk |=
htole32(1 << iwm_mvm_ac_to_tx_fifo[ac]); htole32(1 << iwm_ac_to_tx_fifo[ac]);
} }
IEEE80211_ADDR_COPY(&add_sta_cmd.addr, in->in_ni.ni_bssid); IEEE80211_ADDR_COPY(&add_sta_cmd.addr, in->in_ni.ni_bssid);
} }
@@ -181,8 +176,8 @@ iwm_mvm_sta_send_to_fw(struct iwm_softc *sc, struct iwm_node *in,
htole32(mpdu_dens << IWM_STA_FLG_AGG_MPDU_DENS_SHIFT); htole32(mpdu_dens << IWM_STA_FLG_AGG_MPDU_DENS_SHIFT);
status = IWM_ADD_STA_SUCCESS; status = IWM_ADD_STA_SUCCESS;
ret = iwm_mvm_send_cmd_pdu_status(sc, IWM_ADD_STA, ret = iwm_send_cmd_pdu_status(sc, IWM_ADD_STA,
iwm_mvm_add_sta_cmd_size(sc), iwm_add_sta_cmd_size(sc),
&add_sta_cmd, &status); &add_sta_cmd, &status);
if (ret) if (ret)
return ret; return ret;
@@ -201,21 +196,21 @@ iwm_mvm_sta_send_to_fw(struct iwm_softc *sc, struct iwm_node *in,
} }
int int
iwm_mvm_add_sta(struct iwm_softc *sc, struct iwm_node *in) iwm_add_sta(struct iwm_softc *sc, struct iwm_node *in)
{ {
return iwm_mvm_sta_send_to_fw(sc, in, FALSE); return iwm_sta_send_to_fw(sc, in, FALSE);
} }
int int
iwm_mvm_update_sta(struct iwm_softc *sc, struct iwm_node *in) iwm_update_sta(struct iwm_softc *sc, struct iwm_node *in)
{ {
return iwm_mvm_sta_send_to_fw(sc, in, TRUE); return iwm_sta_send_to_fw(sc, in, TRUE);
} }
int int
iwm_mvm_drain_sta(struct iwm_softc *sc, struct iwm_vap *ivp, boolean_t drain) iwm_drain_sta(struct iwm_softc *sc, struct iwm_vap *ivp, boolean_t drain)
{ {
struct iwm_mvm_add_sta_cmd cmd = {}; struct iwm_add_sta_cmd cmd = {};
int ret; int ret;
uint32_t status; uint32_t status;
@@ -227,8 +222,8 @@ iwm_mvm_drain_sta(struct iwm_softc *sc, struct iwm_vap *ivp, boolean_t drain)
cmd.station_flags_msk = htole32(IWM_STA_FLG_DRAIN_FLOW); cmd.station_flags_msk = htole32(IWM_STA_FLG_DRAIN_FLOW);
status = IWM_ADD_STA_SUCCESS; status = IWM_ADD_STA_SUCCESS;
ret = iwm_mvm_send_cmd_pdu_status(sc, IWM_ADD_STA, ret = iwm_send_cmd_pdu_status(sc, IWM_ADD_STA,
iwm_mvm_add_sta_cmd_size(sc), iwm_add_sta_cmd_size(sc),
&cmd, &status); &cmd, &status);
if (ret) if (ret)
return ret; return ret;
@@ -254,14 +249,14 @@ iwm_mvm_drain_sta(struct iwm_softc *sc, struct iwm_vap *ivp, boolean_t drain)
* only). * only).
*/ */
static int static int
iwm_mvm_rm_sta_common(struct iwm_softc *sc) iwm_rm_sta_common(struct iwm_softc *sc)
{ {
struct iwm_mvm_rm_sta_cmd rm_sta_cmd = { struct iwm_rm_sta_cmd rm_sta_cmd = {
.sta_id = IWM_STATION_ID, .sta_id = IWM_STATION_ID,
}; };
int ret; int ret;
ret = iwm_mvm_send_cmd_pdu(sc, IWM_REMOVE_STA, 0, ret = iwm_send_cmd_pdu(sc, IWM_REMOVE_STA, 0,
sizeof(rm_sta_cmd), &rm_sta_cmd); sizeof(rm_sta_cmd), &rm_sta_cmd);
if (ret) { if (ret) {
device_printf(sc->sc_dev, device_printf(sc->sc_dev,
@@ -273,20 +268,20 @@ iwm_mvm_rm_sta_common(struct iwm_softc *sc)
} }
int int
iwm_mvm_rm_sta(struct iwm_softc *sc, struct ieee80211vap *vap, iwm_rm_sta(struct iwm_softc *sc, struct ieee80211vap *vap,
boolean_t is_assoc) boolean_t is_assoc)
{ {
uint32_t tfd_queue_msk = 0; uint32_t tfd_queue_msk = 0;
int ret; int ret;
int ac; int ac;
ret = iwm_mvm_drain_sta(sc, IWM_VAP(vap), TRUE); ret = iwm_drain_sta(sc, IWM_VAP(vap), TRUE);
if (ret) if (ret)
return ret; return ret;
for (ac = 0; ac < WME_NUM_AC; ac++) { for (ac = 0; ac < WME_NUM_AC; ac++) {
tfd_queue_msk |= htole32(1 << iwm_mvm_ac_to_tx_fifo[ac]); tfd_queue_msk |= htole32(1 << iwm_ac_to_tx_fifo[ac]);
} }
ret = iwm_mvm_flush_tx_path(sc, tfd_queue_msk, IWM_CMD_SYNC); ret = iwm_flush_tx_path(sc, tfd_queue_msk, IWM_CMD_SYNC);
if (ret) if (ret)
return ret; return ret;
#ifdef notyet /* function not yet implemented */ #ifdef notyet /* function not yet implemented */
@@ -295,7 +290,7 @@ iwm_mvm_rm_sta(struct iwm_softc *sc, struct ieee80211vap *vap,
if (ret) if (ret)
return ret; return ret;
#endif #endif
ret = iwm_mvm_drain_sta(sc, IWM_VAP(vap), FALSE); ret = iwm_drain_sta(sc, IWM_VAP(vap), FALSE);
/* if we are associated - we can't remove the AP STA now */ /* if we are associated - we can't remove the AP STA now */
if (is_assoc) if (is_assoc)
@@ -303,30 +298,32 @@ iwm_mvm_rm_sta(struct iwm_softc *sc, struct ieee80211vap *vap,
/* XXX wait until STA is drained */ /* XXX wait until STA is drained */
ret = iwm_mvm_rm_sta_common(sc); ret = iwm_rm_sta_common(sc);
return ret; return ret;
} }
int int
iwm_mvm_rm_sta_id(struct iwm_softc *sc, struct ieee80211vap *vap) iwm_rm_sta_id(struct iwm_softc *sc, struct ieee80211vap *vap)
{ {
/* XXX wait until STA is drained */ /* XXX wait until STA is drained */
return iwm_mvm_rm_sta_common(sc); return iwm_rm_sta_common(sc);
} }
static int static int
iwm_mvm_add_int_sta_common(struct iwm_softc *sc, struct iwm_int_sta *sta, iwm_add_int_sta_common(struct iwm_softc *sc, struct iwm_int_sta *sta,
const uint8_t *addr, uint16_t mac_id, uint16_t color) const uint8_t *addr, uint16_t mac_id, uint16_t color)
{ {
struct iwm_mvm_add_sta_cmd cmd; struct iwm_add_sta_cmd cmd;
int ret; int ret;
uint32_t status; uint32_t status;
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
cmd.sta_id = sta->sta_id; cmd.sta_id = sta->sta_id;
cmd.mac_id_n_color = htole32(IWM_FW_CMD_ID_AND_COLOR(mac_id, color)); cmd.mac_id_n_color = htole32(IWM_FW_CMD_ID_AND_COLOR(mac_id, color));
if (sta->sta_id == IWM_AUX_STA_ID && sc->cfg->mqrx_supported)
cmd.station_type = IWM_STA_AUX_ACTIVITY;
cmd.tfd_queue_msk = htole32(sta->tfd_queue_msk); cmd.tfd_queue_msk = htole32(sta->tfd_queue_msk);
cmd.tid_disable_tx = htole16(0xffff); cmd.tid_disable_tx = htole16(0xffff);
@@ -334,8 +331,8 @@ iwm_mvm_add_int_sta_common(struct iwm_softc *sc, struct iwm_int_sta *sta,
if (addr) if (addr)
IEEE80211_ADDR_COPY(cmd.addr, addr); IEEE80211_ADDR_COPY(cmd.addr, addr);
ret = iwm_mvm_send_cmd_pdu_status(sc, IWM_ADD_STA, ret = iwm_send_cmd_pdu_status(sc, IWM_ADD_STA,
iwm_mvm_add_sta_cmd_size(sc), iwm_add_sta_cmd_size(sc),
&cmd, &status); &cmd, &status);
if (ret) if (ret)
return ret; return ret;
@@ -354,30 +351,31 @@ iwm_mvm_add_int_sta_common(struct iwm_softc *sc, struct iwm_int_sta *sta,
} }
int int
iwm_mvm_add_aux_sta(struct iwm_softc *sc) iwm_add_aux_sta(struct iwm_softc *sc)
{ {
int ret; int ret;
sc->sc_aux_sta.sta_id = IWM_AUX_STA_ID; sc->sc_aux_sta.sta_id = IWM_AUX_STA_ID;
sc->sc_aux_sta.tfd_queue_msk = (1 << IWM_MVM_AUX_QUEUE); sc->sc_aux_sta.tfd_queue_msk = (1 << IWM_AUX_QUEUE);
/* Map Aux queue to fifo - needs to happen before adding Aux station */ /* Map Aux queue to fifo - needs to happen before adding Aux station */
ret = iwm_enable_txq(sc, 0, IWM_MVM_AUX_QUEUE, IWM_MVM_TX_FIFO_MCAST); ret = iwm_enable_txq(sc, IWM_AUX_STA_ID, IWM_AUX_QUEUE,
IWM_TX_FIFO_MCAST);
if (ret) if (ret)
return ret; return ret;
ret = iwm_mvm_add_int_sta_common(sc, &sc->sc_aux_sta, NULL, ret = iwm_add_int_sta_common(sc, &sc->sc_aux_sta, NULL,
IWM_MAC_INDEX_AUX, 0); IWM_MAC_INDEX_AUX, 0);
if (ret) { if (ret) {
memset(&sc->sc_aux_sta, 0, sizeof(sc->sc_aux_sta)); memset(&sc->sc_aux_sta, 0, sizeof(sc->sc_aux_sta));
sc->sc_aux_sta.sta_id = IWM_MVM_STATION_COUNT; sc->sc_aux_sta.sta_id = IWM_STATION_COUNT;
} }
return ret; return ret;
} }
void iwm_mvm_del_aux_sta(struct iwm_softc *sc) void iwm_del_aux_sta(struct iwm_softc *sc)
{ {
memset(&sc->sc_aux_sta, 0, sizeof(sc->sc_aux_sta)); memset(&sc->sc_aux_sta, 0, sizeof(sc->sc_aux_sta));
sc->sc_aux_sta.sta_id = IWM_MVM_STATION_COUNT; sc->sc_aux_sta.sta_id = IWM_STATION_COUNT;
} }
@@ -73,7 +73,7 @@
* *
*****************************************************************************/ *****************************************************************************/
/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_sta.h 318229 2017-05-12 06:33:07Z adrian $ */ /* $FreeBSD$ */
#ifndef __IF_IWM_STA_H__ #ifndef __IF_IWM_STA_H__
#define __IF_IWM_STA_H__ #define __IF_IWM_STA_H__
@@ -88,14 +88,14 @@
* keeps the fw's station table up to date with the ADD_STA command. Stations * keeps the fw's station table up to date with the ADD_STA command. Stations
* can be removed by the REMOVE_STA command. * can be removed by the REMOVE_STA command.
* *
* All the data related to a station is held in the structure %iwl_mvm_sta * All the data related to a station is held in the structure %iwl_sta
* which is embed in the mac80211's %ieee80211_sta (in the drv_priv) area. * which is embed in the mac80211's %ieee80211_sta (in the drv_priv) area.
* This data includes the index of the station in the fw, per tid information * This data includes the index of the station in the fw, per tid information
* (sequence numbers, Block-ack state machine, etc...). The stations are * (sequence numbers, Block-ack state machine, etc...). The stations are
* created and deleted by the %sta_state callback from %ieee80211_ops. * created and deleted by the %sta_state callback from %ieee80211_ops.
* *
* The driver holds a map: %fw_id_to_mac_id that allows to fetch a * The driver holds a map: %fw_id_to_mac_id that allows to fetch a
* %ieee80211_sta (and the %iwl_mvm_sta embedded into it) based on a fw * %ieee80211_sta (and the %iwl_sta embedded into it) based on a fw
* station index. That way, the driver is able to get the tid related data in * station index. That way, the driver is able to get the tid related data in
* O(1) in time sensitive paths (Tx / Tx response / BA notification). These * O(1) in time sensitive paths (Tx / Tx response / BA notification). These
* paths are triggered by the fw, and the driver needs to get a pointer to the * paths are triggered by the fw, and the driver needs to get a pointer to the
@@ -133,8 +133,8 @@
* The FW needs a few internal stations that are not reflected in * The FW needs a few internal stations that are not reflected in
* mac80211, such as broadcast station in AP / GO mode, or AUX sta for * mac80211, such as broadcast station in AP / GO mode, or AUX sta for
* scanning and P2P device (during the GO negotiation). * scanning and P2P device (during the GO negotiation).
* For these kind of stations we have %iwl_mvm_int_sta struct which holds the * For these kind of stations we have %iwl_int_sta struct which holds the
* data relevant for them from both %iwl_mvm_sta and %ieee80211_sta. * data relevant for them from both %iwl_sta and %ieee80211_sta.
* Usually the data for these stations is static, so no locking is required, * Usually the data for these stations is static, so no locking is required,
* and no TID data as this is also not needed. * and no TID data as this is also not needed.
* One thing to note, is that these stations have an ID in the fw, but not * One thing to note, is that these stations have an ID in the fw, but not
@@ -150,7 +150,7 @@
/** /**
* DOC: station table - AP Station in STA mode * DOC: station table - AP Station in STA mode
* *
* %iwl_mvm_vif includes the index of the AP station in the fw's STA table: * %iwl_vif includes the index of the AP station in the fw's STA table:
* %ap_sta_id. To get the point to the corresponding %ieee80211_sta, * %ap_sta_id. To get the point to the corresponding %ieee80211_sta,
* &fw_id_to_mac_id can be used. Due to the way the fw works, we must not remove * &fw_id_to_mac_id can be used. Due to the way the fw works, we must not remove
* the AP station from the fw before setting the MAC context as unassociated. * the AP station from the fw before setting the MAC context as unassociated.
@@ -173,10 +173,10 @@
* the fw. In order to do so, we track the non-AMPDU packets for each station. * the fw. In order to do so, we track the non-AMPDU packets for each station.
* If mac80211 removes a STA and if it still has non-AMPDU packets pending in * If mac80211 removes a STA and if it still has non-AMPDU packets pending in
* the queues, we mark this station as %EBUSY in %fw_id_to_mac_id, and drop all * the queues, we mark this station as %EBUSY in %fw_id_to_mac_id, and drop all
* the frames for this STA (%iwl_mvm_rm_sta). When the last frame is dropped * the frames for this STA (%iwl_rm_sta). When the last frame is dropped
* (we know about it with its Tx response), we remove the station in fw and set * (we know about it with its Tx response), we remove the station in fw and set
* it as %NULL in %fw_id_to_mac_id: this is the purpose of * it as %NULL in %fw_id_to_mac_id: this is the purpose of
* %iwl_mvm_sta_drained_wk. * %iwl_sta_drained_wk.
*/ */
/** /**
@@ -186,14 +186,14 @@
* driver, we require mac80211 to reconfigure the driver. Since the private * driver, we require mac80211 to reconfigure the driver. Since the private
* data of the stations is embed in mac80211's %ieee80211_sta, that data will * data of the stations is embed in mac80211's %ieee80211_sta, that data will
* not be zeroed and needs to be reinitialized manually. * not be zeroed and needs to be reinitialized manually.
* %IWL_MVM_STATUS_IN_HW_RESTART is set during restart and that will hint us * %IWL_STATUS_IN_HW_RESTART is set during restart and that will hint us
* that we must not allocate a new sta_id but reuse the previous one. This * that we must not allocate a new sta_id but reuse the previous one. This
* means that the stations being re-added after the reset will have the same * means that the stations being re-added after the reset will have the same
* place in the fw as before the reset. We do need to zero the %fw_id_to_mac_id * place in the fw as before the reset. We do need to zero the %fw_id_to_mac_id
* map, since the stations aren't in the fw any more. Internal stations that * map, since the stations aren't in the fw any more. Internal stations that
* are not added by mac80211 will be re-added in the init flow that is called * are not added by mac80211 will be re-added in the init flow that is called
* after the restart: mac80211 call's %iwl_mvm_mac_start which calls to * after the restart: mac80211 call's %iwl_mac_start which calls to
* %iwl_mvm_up. * %iwl_up.
*/ */
/** /**
@@ -206,18 +206,18 @@
* @flags: if update==true, this marks what is being changed via ORs of values * @flags: if update==true, this marks what is being changed via ORs of values
* from enum iwm_sta_modify_flag. Otherwise, this is ignored. * from enum iwm_sta_modify_flag. Otherwise, this is ignored.
*/ */
extern int iwm_mvm_sta_send_to_fw(struct iwm_softc *sc, struct iwm_node *in, extern int iwm_sta_send_to_fw(struct iwm_softc *sc, struct iwm_node *in,
boolean_t update); boolean_t update);
extern int iwm_mvm_add_sta(struct iwm_softc *sc, struct iwm_node *in); extern int iwm_add_sta(struct iwm_softc *sc, struct iwm_node *in);
extern int iwm_mvm_update_sta(struct iwm_softc *sc, struct iwm_node *in); extern int iwm_update_sta(struct iwm_softc *sc, struct iwm_node *in);
extern int iwm_mvm_rm_sta(struct iwm_softc *sc, struct ieee80211vap *vap, extern int iwm_rm_sta(struct iwm_softc *sc, struct ieee80211vap *vap,
boolean_t is_assoc); boolean_t is_assoc);
extern int iwm_mvm_rm_sta_id(struct iwm_softc *sc, struct ieee80211vap *vap); extern int iwm_rm_sta_id(struct iwm_softc *sc, struct ieee80211vap *vap);
extern int iwm_mvm_add_aux_sta(struct iwm_softc *sc); extern int iwm_add_aux_sta(struct iwm_softc *sc);
extern void iwm_mvm_del_aux_sta(struct iwm_softc *sc); extern void iwm_del_aux_sta(struct iwm_softc *sc);
extern int iwm_mvm_drain_sta(struct iwm_softc *sc, struct iwm_vap *ivp, extern int iwm_drain_sta(struct iwm_softc *sc, struct iwm_vap *ivp,
boolean_t drain); boolean_t drain);
#endif /* __IF_IWM_STA_H__ */ #endif /* __IF_IWM_STA_H__ */
@@ -103,7 +103,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_time_event.c 318212 2017-05-12 05:19:08Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -162,7 +162,7 @@ __FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_time_event.c 318212 2017-05-1
#define TU_TO_HZ(tu) (((uint64_t)(tu) * 1024 * hz) / 1000000) #define TU_TO_HZ(tu) (((uint64_t)(tu) * 1024 * hz) / 1000000)
static void static void
iwm_mvm_te_clear_data(struct iwm_softc *sc) iwm_te_clear_data(struct iwm_softc *sc)
{ {
sc->sc_time_event_uid = 0; sc->sc_time_event_uid = 0;
sc->sc_time_event_duration = 0; sc->sc_time_event_duration = 0;
@@ -178,7 +178,7 @@ iwm_mvm_te_clear_data(struct iwm_softc *sc)
* @notif: the notification data corresponding the time event data. * @notif: the notification data corresponding the time event data.
*/ */
static void static void
iwm_mvm_te_handle_notif(struct iwm_softc *sc, iwm_te_handle_notif(struct iwm_softc *sc,
struct iwm_time_event_notif *notif) struct iwm_time_event_notif *notif)
{ {
IWM_DPRINTF(sc, IWM_DEBUG_TE, IWM_DPRINTF(sc, IWM_DEBUG_TE,
@@ -202,7 +202,7 @@ iwm_mvm_te_handle_notif(struct iwm_softc *sc,
"TE ended - current time %d, estimated end %d\n", "TE ended - current time %d, estimated end %d\n",
ticks, sc->sc_time_event_end_ticks); ticks, sc->sc_time_event_end_ticks);
iwm_mvm_te_clear_data(sc); iwm_te_clear_data(sc);
} else if (le32toh(notif->action) & IWM_TE_V2_NOTIF_HOST_EVENT_START) { } else if (le32toh(notif->action) & IWM_TE_V2_NOTIF_HOST_EVENT_START) {
sc->sc_time_event_end_ticks = sc->sc_time_event_end_ticks =
ticks + TU_TO_HZ(sc->sc_time_event_duration); ticks + TU_TO_HZ(sc->sc_time_event_duration);
@@ -215,7 +215,7 @@ iwm_mvm_te_handle_notif(struct iwm_softc *sc,
* The Rx handler for time event notifications * The Rx handler for time event notifications
*/ */
void void
iwm_mvm_rx_time_event_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt) iwm_rx_time_event_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt)
{ {
struct iwm_time_event_notif *notif = (void *)pkt->data; struct iwm_time_event_notif *notif = (void *)pkt->data;
@@ -224,11 +224,11 @@ iwm_mvm_rx_time_event_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt)
le32toh(notif->unique_id), le32toh(notif->unique_id),
le32toh(notif->action)); le32toh(notif->action));
iwm_mvm_te_handle_notif(sc, notif); iwm_te_handle_notif(sc, notif);
} }
static int static int
iwm_mvm_te_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt, iwm_te_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
void *data) void *data)
{ {
struct iwm_time_event_notif *resp; struct iwm_time_event_notif *resp;
@@ -259,7 +259,7 @@ iwm_mvm_te_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
} }
static int static int
iwm_mvm_time_event_response(struct iwm_softc *sc, struct iwm_rx_packet *pkt, iwm_time_event_response(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
void *data) void *data)
{ {
struct iwm_time_event_resp *resp; struct iwm_time_event_resp *resp;
@@ -292,7 +292,7 @@ iwm_mvm_time_event_response(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
/* XXX Use the te_data function argument properly, like in iwlwifi's code. */ /* XXX Use the te_data function argument properly, like in iwlwifi's code. */
static int static int
iwm_mvm_time_event_send_add(struct iwm_softc *sc, struct iwm_vap *ivp, iwm_time_event_send_add(struct iwm_softc *sc, struct iwm_vap *ivp,
void *te_data, struct iwm_time_event_cmd *te_cmd) void *te_data, struct iwm_time_event_cmd *te_cmd)
{ {
static const uint16_t time_event_response[] = { IWM_TIME_EVENT_CMD }; static const uint16_t time_event_response[] = { IWM_TIME_EVENT_CMD };
@@ -316,9 +316,9 @@ iwm_mvm_time_event_send_add(struct iwm_softc *sc, struct iwm_vap *ivp,
iwm_init_notification_wait(sc->sc_notif_wait, &wait_time_event, iwm_init_notification_wait(sc->sc_notif_wait, &wait_time_event,
time_event_response, time_event_response,
nitems(time_event_response), nitems(time_event_response),
iwm_mvm_time_event_response, /*te_data*/NULL); iwm_time_event_response, /*te_data*/NULL);
ret = iwm_mvm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, 0, sizeof(*te_cmd), ret = iwm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, 0, sizeof(*te_cmd),
te_cmd); te_cmd);
if (ret) { if (ret) {
IWM_DPRINTF(sc, IWM_DEBUG_TE, IWM_DPRINTF(sc, IWM_DEBUG_TE,
@@ -343,7 +343,7 @@ iwm_mvm_time_event_send_add(struct iwm_softc *sc, struct iwm_vap *ivp,
} }
void void
iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp, iwm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp,
uint32_t duration, uint32_t max_delay, boolean_t wait_for_notif) uint32_t duration, uint32_t max_delay, boolean_t wait_for_notif)
{ {
const uint16_t te_notif_response[] = { IWM_TIME_EVENT_NOTIFICATION }; const uint16_t te_notif_response[] = { IWM_TIME_EVENT_NOTIFICATION };
@@ -373,7 +373,7 @@ iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp,
IWM_T2_V2_START_IMMEDIATELY); IWM_T2_V2_START_IMMEDIATELY);
if (!wait_for_notif) { if (!wait_for_notif) {
iwm_mvm_time_event_send_add(sc, ivp, /*te_data*/NULL, &time_cmd); iwm_time_event_send_add(sc, ivp, /*te_data*/NULL, &time_cmd);
DELAY(100); DELAY(100);
sc->sc_flags |= IWM_FLAG_TE_ACTIVE; sc->sc_flags |= IWM_FLAG_TE_ACTIVE;
return; return;
@@ -385,10 +385,10 @@ iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp,
*/ */
iwm_init_notification_wait(sc->sc_notif_wait, &wait_te_notif, iwm_init_notification_wait(sc->sc_notif_wait, &wait_te_notif,
te_notif_response, nitems(te_notif_response), te_notif_response, nitems(te_notif_response),
iwm_mvm_te_notif, /*te_data*/NULL); iwm_te_notif, /*te_data*/NULL);
/* If TE was sent OK - wait for the notification that started */ /* If TE was sent OK - wait for the notification that started */
if (iwm_mvm_time_event_send_add(sc, ivp, /*te_data*/NULL, &time_cmd)) { if (iwm_time_event_send_add(sc, ivp, /*te_data*/NULL, &time_cmd)) {
IWM_DPRINTF(sc, IWM_DEBUG_TE, IWM_DPRINTF(sc, IWM_DEBUG_TE,
"%s: Failed to add TE to protect session\n", __func__); "%s: Failed to add TE to protect session\n", __func__);
iwm_remove_notification(sc->sc_notif_wait, &wait_te_notif); iwm_remove_notification(sc->sc_notif_wait, &wait_te_notif);
@@ -406,7 +406,7 @@ iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp,
} }
void void
iwm_mvm_stop_session_protection(struct iwm_softc *sc, struct iwm_vap *ivp) iwm_stop_session_protection(struct iwm_softc *sc, struct iwm_vap *ivp)
{ {
struct iwm_time_event_cmd time_cmd = {}; struct iwm_time_event_cmd time_cmd = {};
@@ -421,9 +421,9 @@ iwm_mvm_stop_session_protection(struct iwm_softc *sc, struct iwm_vap *ivp)
IWM_DPRINTF(sc, IWM_DEBUG_TE, IWM_DPRINTF(sc, IWM_DEBUG_TE,
"%s: Removing TE 0x%x\n", __func__, le32toh(time_cmd.id)); "%s: Removing TE 0x%x\n", __func__, le32toh(time_cmd.id));
if (iwm_mvm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, 0, sizeof(time_cmd), if (iwm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, 0, sizeof(time_cmd),
&time_cmd) == 0) &time_cmd) == 0)
iwm_mvm_te_clear_data(sc); iwm_te_clear_data(sc);
DELAY(100); DELAY(100);
} }
@@ -1,5 +1,5 @@
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_time_event.h 318212 2017-05-12 05:19:08Z adrian $ */ /* $FreeBSD$ */
/* /*
* Copyright (c) 2014 genua mbh <info@genua.de> * Copyright (c) 2014 genua mbh <info@genua.de>
@@ -107,11 +107,11 @@
#ifndef __IF_IWM_TIME_EVENT_H__ #ifndef __IF_IWM_TIME_EVENT_H__
#define __IF_IWM_TIME_EVENT_H__ #define __IF_IWM_TIME_EVENT_H__
extern void iwm_mvm_rx_time_event_notif(struct iwm_softc *sc, extern void iwm_rx_time_event_notif(struct iwm_softc *sc,
struct iwm_rx_packet *pkt); struct iwm_rx_packet *pkt);
extern void iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp, extern void iwm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp,
uint32_t duration, uint32_t max_delay, boolean_t wait_for_notif); uint32_t duration, uint32_t max_delay, boolean_t wait_for_notif);
extern void iwm_mvm_stop_session_protection(struct iwm_softc *sc, extern void iwm_stop_session_protection(struct iwm_softc *sc,
struct iwm_vap *ivp); struct iwm_vap *ivp);
#endif /* __IF_IWM_TIME_EVENT_H__ */ #endif /* __IF_IWM_TIME_EVENT_H__ */
@@ -103,7 +103,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_util.c 321510 2017-07-26 05:51:31Z adrian $"); __FBSDID("$FreeBSD$");
#include "opt_wlan.h" #include "opt_wlan.h"
#include "opt_iwm.h" #include "opt_iwm.h"
@@ -169,7 +169,7 @@ __FBSDID("$FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_util.c 321510 2017-07-26 05:5
int int
iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd) iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
{ {
struct iwm_tx_ring *ring = &sc->txq[IWM_MVM_CMD_QUEUE]; struct iwm_tx_ring *ring = &sc->txq[IWM_CMD_QUEUE];
struct iwm_tfd *desc; struct iwm_tfd *desc;
struct iwm_tx_data *txdata = NULL; struct iwm_tx_data *txdata = NULL;
struct iwm_device_cmd *cmd; struct iwm_device_cmd *cmd;
@@ -225,12 +225,11 @@ iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
} }
if (paylen > datasz) { if (paylen > datasz) {
size_t totlen;
IWM_DPRINTF(sc, IWM_DEBUG_CMD, IWM_DPRINTF(sc, IWM_DEBUG_CMD,
"large command paylen=%u len0=%u\n", "large command paylen=%u len0=%u\n",
paylen, hcmd->len[0]); paylen, hcmd->len[0]);
/* Command is too large */ /* Command is too large */
totlen = hdrlen + paylen; size_t totlen = hdrlen + paylen;
if (paylen > IWM_MAX_CMD_PAYLOAD_SIZE) { if (paylen > IWM_MAX_CMD_PAYLOAD_SIZE) {
device_printf(sc->sc_dev, device_printf(sc->sc_dev,
"firmware command too long (%zd bytes)\n", "firmware command too long (%zd bytes)\n",
@@ -347,7 +346,7 @@ iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
/* iwlwifi: mvm/utils.c */ /* iwlwifi: mvm/utils.c */
int int
iwm_mvm_send_cmd_pdu(struct iwm_softc *sc, uint32_t id, iwm_send_cmd_pdu(struct iwm_softc *sc, uint32_t id,
uint32_t flags, uint16_t len, const void *data) uint32_t flags, uint16_t len, const void *data)
{ {
struct iwm_host_cmd cmd = { struct iwm_host_cmd cmd = {
@@ -362,7 +361,7 @@ iwm_mvm_send_cmd_pdu(struct iwm_softc *sc, uint32_t id,
/* iwlwifi: mvm/utils.c */ /* iwlwifi: mvm/utils.c */
int int
iwm_mvm_send_cmd_status(struct iwm_softc *sc, iwm_send_cmd_status(struct iwm_softc *sc,
struct iwm_host_cmd *cmd, uint32_t *status) struct iwm_host_cmd *cmd, uint32_t *status)
{ {
struct iwm_rx_packet *pkt; struct iwm_rx_packet *pkt;
@@ -403,7 +402,7 @@ iwm_mvm_send_cmd_status(struct iwm_softc *sc,
/* iwlwifi/mvm/utils.c */ /* iwlwifi/mvm/utils.c */
int int
iwm_mvm_send_cmd_pdu_status(struct iwm_softc *sc, uint32_t id, iwm_send_cmd_pdu_status(struct iwm_softc *sc, uint32_t id,
uint16_t len, const void *data, uint32_t *status) uint16_t len, const void *data, uint32_t *status)
{ {
struct iwm_host_cmd cmd = { struct iwm_host_cmd cmd = {
@@ -412,7 +411,7 @@ iwm_mvm_send_cmd_pdu_status(struct iwm_softc *sc, uint32_t id,
.data = { data, }, .data = { data, },
}; };
return iwm_mvm_send_cmd_status(sc, &cmd, status); return iwm_send_cmd_status(sc, &cmd, status);
} }
void void
@@ -491,7 +490,7 @@ iwm_dma_contig_free(struct iwm_dma_info *dma)
} }
/** /**
* iwm_mvm_send_lq_cmd() - Send link quality command * iwm_send_lq_cmd() - Send link quality command
* @init: This command is sent as part of station initialization right * @init: This command is sent as part of station initialization right
* after station has been added. * after station has been added.
* *
@@ -501,7 +500,7 @@ iwm_dma_contig_free(struct iwm_dma_info *dma)
* progress. * progress.
*/ */
int int
iwm_mvm_send_lq_cmd(struct iwm_softc *sc, struct iwm_lq_cmd *lq, boolean_t init) iwm_send_lq_cmd(struct iwm_softc *sc, struct iwm_lq_cmd *lq, boolean_t init)
{ {
struct iwm_host_cmd cmd = { struct iwm_host_cmd cmd = {
.id = IWM_LQ_CMD, .id = IWM_LQ_CMD,
@@ -510,16 +509,16 @@ iwm_mvm_send_lq_cmd(struct iwm_softc *sc, struct iwm_lq_cmd *lq, boolean_t init)
.data = { lq, }, .data = { lq, },
}; };
if (lq->sta_id == IWM_MVM_STATION_COUNT) if (lq->sta_id == IWM_STATION_COUNT)
return EINVAL; return EINVAL;
return iwm_send_cmd(sc, &cmd); return iwm_send_cmd(sc, &cmd);
} }
boolean_t boolean_t
iwm_mvm_rx_diversity_allowed(struct iwm_softc *sc) iwm_rx_diversity_allowed(struct iwm_softc *sc)
{ {
if (num_of_ant(iwm_mvm_get_valid_rx_ant(sc)) == 1) if (num_of_ant(iwm_get_valid_rx_ant(sc)) == 1)
return FALSE; return FALSE;
/* /*
@@ -1,5 +1,5 @@
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */ /* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwm_util.h 321510 2017-07-26 05:51:31Z adrian $ */ /* $FreeBSD$ */
/* /*
* Copyright (c) 2014 genua mbh <info@genua.de> * Copyright (c) 2014 genua mbh <info@genua.de>
@@ -107,12 +107,12 @@
#define __IF_IWM_UTIL_H__ #define __IF_IWM_UTIL_H__
extern int iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd); extern int iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd);
extern int iwm_mvm_send_cmd_pdu(struct iwm_softc *sc, uint32_t id, extern int iwm_send_cmd_pdu(struct iwm_softc *sc, uint32_t id,
uint32_t flags, uint16_t len, const void *data); uint32_t flags, uint16_t len, const void *data);
extern int iwm_mvm_send_cmd_status(struct iwm_softc *sc, extern int iwm_send_cmd_status(struct iwm_softc *sc,
struct iwm_host_cmd *cmd, uint32_t *status); struct iwm_host_cmd *cmd, uint32_t *status);
extern int iwm_mvm_send_cmd_pdu_status(struct iwm_softc *sc, uint32_t id, extern int iwm_send_cmd_pdu_status(struct iwm_softc *sc, uint32_t id,
uint16_t len, const void *data, uint32_t *status); uint16_t len, const void *data, uint32_t *status);
extern void iwm_free_resp(struct iwm_softc *sc, struct iwm_host_cmd *hcmd); extern void iwm_free_resp(struct iwm_softc *sc, struct iwm_host_cmd *hcmd);
@@ -120,18 +120,18 @@ extern int iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
bus_size_t size, bus_size_t alignment); bus_size_t size, bus_size_t alignment);
extern void iwm_dma_contig_free(struct iwm_dma_info *); extern void iwm_dma_contig_free(struct iwm_dma_info *);
extern int iwm_mvm_send_lq_cmd(struct iwm_softc *sc, struct iwm_lq_cmd *lq, extern int iwm_send_lq_cmd(struct iwm_softc *sc, struct iwm_lq_cmd *lq,
boolean_t init); boolean_t init);
extern boolean_t iwm_mvm_rx_diversity_allowed(struct iwm_softc *sc); extern boolean_t iwm_rx_diversity_allowed(struct iwm_softc *sc);
extern uint8_t iwm_ridx2rate(struct ieee80211_rateset *rs, int ridx); extern uint8_t iwm_ridx2rate(struct ieee80211_rateset *rs, int ridx);
extern int iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo); extern int iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo);
extern int iwm_mvm_flush_tx_path(struct iwm_softc *sc, uint32_t tfd_msk, extern int iwm_flush_tx_path(struct iwm_softc *sc, uint32_t tfd_msk,
uint32_t flags); uint32_t flags);
static inline uint8_t static inline uint8_t
iwm_mvm_get_valid_tx_ant(struct iwm_softc *sc) iwm_get_valid_tx_ant(struct iwm_softc *sc)
{ {
return sc->nvm_data && sc->nvm_data->valid_tx_ant ? return sc->nvm_data && sc->nvm_data->valid_tx_ant ?
sc->sc_fw.valid_tx_ant & sc->nvm_data->valid_tx_ant : sc->sc_fw.valid_tx_ant & sc->nvm_data->valid_tx_ant :
@@ -139,7 +139,7 @@ iwm_mvm_get_valid_tx_ant(struct iwm_softc *sc)
} }
static inline uint8_t static inline uint8_t
iwm_mvm_get_valid_rx_ant(struct iwm_softc *sc) iwm_get_valid_rx_ant(struct iwm_softc *sc)
{ {
return sc->nvm_data && sc->nvm_data->valid_rx_ant ? return sc->nvm_data && sc->nvm_data->valid_rx_ant ?
sc->sc_fw.valid_rx_ant & sc->nvm_data->valid_rx_ant : sc->sc_fw.valid_rx_ant & sc->nvm_data->valid_rx_ant :
@@ -147,12 +147,12 @@ iwm_mvm_get_valid_rx_ant(struct iwm_softc *sc)
} }
static inline uint32_t static inline uint32_t
iwm_mvm_get_phy_config(struct iwm_softc *sc) iwm_get_phy_config(struct iwm_softc *sc)
{ {
uint32_t phy_config = ~(IWM_FW_PHY_CFG_TX_CHAIN | uint32_t phy_config = ~(IWM_FW_PHY_CFG_TX_CHAIN |
IWM_FW_PHY_CFG_RX_CHAIN); IWM_FW_PHY_CFG_RX_CHAIN);
uint32_t valid_rx_ant = iwm_mvm_get_valid_rx_ant(sc); uint32_t valid_rx_ant = iwm_get_valid_rx_ant(sc);
uint32_t valid_tx_ant = iwm_mvm_get_valid_tx_ant(sc); uint32_t valid_tx_ant = iwm_get_valid_tx_ant(sc);
phy_config |= valid_tx_ant << IWM_FW_PHY_CFG_TX_CHAIN_POS | phy_config |= valid_tx_ant << IWM_FW_PHY_CFG_TX_CHAIN_POS |
valid_rx_ant << IWM_FW_PHY_CFG_RX_CHAIN_POS; valid_rx_ant << IWM_FW_PHY_CFG_RX_CHAIN_POS;
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,5 @@
/* $OpenBSD: if_iwmvar.h,v 1.7 2015/03/02 13:51:10 jsg Exp $ */ /* $OpenBSD: if_iwmvar.h,v 1.7 2015/03/02 13:51:10 jsg Exp $ */
/* $FreeBSD: releng/12.0/sys/dev/iwm/if_iwmvar.h 321509 2017-07-26 05:40:52Z adrian $ */ /* $FreeBSD$ */
/* /*
* Copyright (c) 2014 genua mbh <info@genua.de> * Copyright (c) 2014 genua mbh <info@genua.de>
@@ -113,7 +113,7 @@ struct iwm_rx_radiotap_header {
uint16_t wr_chan_flags; uint16_t wr_chan_flags;
int8_t wr_dbm_antsignal; int8_t wr_dbm_antsignal;
int8_t wr_dbm_antnoise; int8_t wr_dbm_antnoise;
} __packed; } __packed __aligned(8);
#define IWM_RX_RADIOTAP_PRESENT \ #define IWM_RX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_TSFT) | \ ((1 << IEEE80211_RADIOTAP_TSFT) | \
@@ -165,20 +165,6 @@ struct iwm_ucode_capabilities {
uint8_t enabled_capa[howmany(IWM_NUM_UCODE_TLV_CAPA, NBBY)]; uint8_t enabled_capa[howmany(IWM_NUM_UCODE_TLV_CAPA, NBBY)];
}; };
static inline int
fw_has_api(const struct iwm_ucode_capabilities *capabilities,
unsigned int api)
{
return isset(capabilities->enabled_api, api);
}
static inline int
fw_has_capa(const struct iwm_ucode_capabilities *capabilities,
unsigned int capa)
{
return isset(capabilities->enabled_capa, capa);
}
/* one for each uCode image (inst/data, init/runtime/wowlan) */ /* one for each uCode image (inst/data, init/runtime/wowlan) */
struct iwm_fw_desc { struct iwm_fw_desc {
const void *data; /* vmalloc'ed data */ const void *data; /* vmalloc'ed data */
@@ -299,8 +285,9 @@ struct iwm_tx_ring {
int cur; int cur;
}; };
#define IWM_RX_RING_COUNT 256 #define IWM_RX_LEGACY_RING_COUNT 256
/* Linux driver optionally uses 8k buffer */ #define IWM_RX_MQ_RING_COUNT 512
#define IWM_RBUF_SIZE 4096 #define IWM_RBUF_SIZE 4096
#define IWM_MAX_SCATTER 20 #define IWM_MAX_SCATTER 20
@@ -311,12 +298,13 @@ struct iwm_rx_data {
}; };
struct iwm_rx_ring { struct iwm_rx_ring {
struct iwm_dma_info desc_dma; struct iwm_dma_info free_desc_dma;
struct iwm_dma_info used_desc_dma;
struct iwm_dma_info stat_dma; struct iwm_dma_info stat_dma;
struct iwm_dma_info buf_dma; struct iwm_dma_info buf_dma;
uint32_t *desc; void *desc;
struct iwm_rb_status *stat; struct iwm_rb_status *stat;
struct iwm_rx_data data[IWM_RX_RING_COUNT]; struct iwm_rx_data data[512];
bus_dmamap_t spare_map; /* for iwm_rx_addbuf() */ bus_dmamap_t spare_map; /* for iwm_rx_addbuf() */
bus_dma_tag_t data_dmat; bus_dma_tag_t data_dmat;
int cur; int cur;
@@ -324,8 +312,8 @@ struct iwm_rx_ring {
#define IWM_CMD_RESP_MAX PAGE_SIZE #define IWM_CMD_RESP_MAX PAGE_SIZE
#define IWM_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS 500 #define IWM_TE_SESSION_PROTECTION_MAX_TIME_MS 500
#define IWM_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS 400 #define IWM_TE_SESSION_PROTECTION_MIN_TIME_MS 400
/* /*
* Command headers are in iwl-trans.h, which is full of all * Command headers are in iwl-trans.h, which is full of all
@@ -348,7 +336,7 @@ struct iwm_int_sta {
uint32_t tfd_queue_msk; uint32_t tfd_queue_msk;
}; };
struct iwm_mvm_phy_ctxt { struct iwm_phy_ctxt {
uint16_t id; uint16_t id;
uint16_t color; uint16_t color;
uint32_t ref; uint32_t ref;
@@ -370,7 +358,7 @@ struct iwm_vap {
int (*iv_newstate)(struct ieee80211vap *, int (*iv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int); enum ieee80211_state, int);
struct iwm_mvm_phy_ctxt *phy_ctxt; struct iwm_phy_ctxt *phy_ctxt;
uint16_t id; uint16_t id;
uint16_t color; uint16_t color;
@@ -455,12 +443,10 @@ struct iwm_softc {
uint32_t scd_base_addr; uint32_t scd_base_addr;
/* TX/RX rings. */ /* TX/RX rings. */
struct iwm_tx_ring txq[IWM_MVM_MAX_QUEUES]; struct iwm_tx_ring txq[IWM_MAX_QUEUES];
struct iwm_rx_ring rxq; struct iwm_rx_ring rxq;
int qfullmsk; int qfullmsk;
int sc_sf_state;
/* ICT table. */ /* ICT table. */
struct iwm_dma_info ict_dma; struct iwm_dma_info ict_dma;
int ict_cur; int ict_cur;
@@ -521,13 +507,11 @@ struct iwm_softc {
struct iwm_int_sta sc_aux_sta; struct iwm_int_sta sc_aux_sta;
/* phy contexts. we only use the first one */ /* phy contexts. we only use the first one */
struct iwm_mvm_phy_ctxt sc_phyctxt[IWM_NUM_PHY_CTX]; struct iwm_phy_ctxt sc_phyctxt[IWM_NUM_PHY_CTX];
struct iwm_notif_statistics_v10 sc_stats; struct iwm_notif_statistics_v10 sc_stats;
int sc_noise; int sc_noise;
caddr_t sc_drvbpf;
struct iwm_rx_radiotap_header sc_rxtap; struct iwm_rx_radiotap_header sc_rxtap;
struct iwm_tx_radiotap_header sc_txtap; struct iwm_tx_radiotap_header sc_txtap;
@@ -585,3 +569,15 @@ struct iwm_softc {
#define IWM_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) #define IWM_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define IWM_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) #define IWM_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define IWM_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) #define IWM_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
static inline bool
iwm_fw_has_api(struct iwm_softc *sc, unsigned int api)
{
return isset(sc->sc_fw.ucode_capa.enabled_api, api);
}
static inline bool
iwm_fw_has_capa(struct iwm_softc *sc, unsigned int capa)
{
return isset(sc->sc_fw.ucode_capa.enabled_capa, capa);
}
@@ -34,6 +34,8 @@ HAIKU_FIRMWARE_NAME_MAP({
{"iwm7265Dfw", "iwm-7265D-22.ucode"}, {"iwm7265Dfw", "iwm-7265D-22.ucode"},
{"iwm8000Cfw", "iwm-8000C-22.ucode"}, {"iwm8000Cfw", "iwm-8000C-22.ucode"},
{"iwm8265fw", "iwm-8265-22.ucode"}, {"iwm8265fw", "iwm-8265-22.ucode"},
{"iwm9000fw", "iwm-9000-34.ucode"},
{"iwm9260fw", "iwm-9260-34.ucode"},
}); });