idualwifi7260: Delete FreeBSD driver, import OpenBSD driver.
Again not wired into the build, nor yet modified in any way.
This commit is contained in:
parent
04171cfc5c
commit
d87dd30a38
File diff suppressed because it is too large
Load Diff
|
@ -1,138 +0,0 @@
|
|||
/*-
|
||||
* 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) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 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) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_wlan.h"
|
||||
#include "opt_iwm.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "if_iwm_config.h"
|
||||
|
||||
#define IWM7260_FW "iwm7260fw"
|
||||
#define IWM3160_FW "iwm3160fw"
|
||||
#define IWM3168_FW "iwm3168fw"
|
||||
#define IWM7265_FW "iwm7265fw"
|
||||
#define IWM7265D_FW "iwm7265Dfw"
|
||||
|
||||
#define IWM_NVM_HW_SECTION_NUM_FAMILY_7000 0
|
||||
|
||||
#define IWM_DEVICE_7000_COMMON \
|
||||
.device_family = IWM_DEVICE_FAMILY_7000, \
|
||||
.eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000, \
|
||||
.nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000, \
|
||||
.apmg_wake_up_wa = 1
|
||||
|
||||
const struct iwm_cfg iwm7260_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 7260",
|
||||
.fw_name = IWM7260_FW,
|
||||
IWM_DEVICE_7000_COMMON,
|
||||
.host_interrupt_operation_mode = 1,
|
||||
};
|
||||
|
||||
const struct iwm_cfg iwm3160_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 3160",
|
||||
.fw_name = IWM3160_FW,
|
||||
IWM_DEVICE_7000_COMMON,
|
||||
.host_interrupt_operation_mode = 1,
|
||||
};
|
||||
|
||||
const struct iwm_cfg iwm3165_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 3165",
|
||||
.fw_name = IWM7265D_FW,
|
||||
IWM_DEVICE_7000_COMMON,
|
||||
.host_interrupt_operation_mode = 0,
|
||||
};
|
||||
|
||||
const struct iwm_cfg iwm3168_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 3168",
|
||||
.fw_name = IWM3168_FW,
|
||||
IWM_DEVICE_7000_COMMON,
|
||||
.host_interrupt_operation_mode = 0,
|
||||
.nvm_type = IWM_NVM_SDP,
|
||||
};
|
||||
|
||||
const struct iwm_cfg iwm7265_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 7265",
|
||||
.fw_name = IWM7265_FW,
|
||||
IWM_DEVICE_7000_COMMON,
|
||||
.host_interrupt_operation_mode = 0,
|
||||
};
|
||||
|
||||
const struct iwm_cfg iwm7265d_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 7265",
|
||||
.fw_name = IWM7265D_FW,
|
||||
IWM_DEVICE_7000_COMMON,
|
||||
.host_interrupt_operation_mode = 0,
|
||||
};
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
/*-
|
||||
* 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 IWM8000_FW "iwm8000Cfw"
|
||||
#define IWM8265_FW "iwm8265fw"
|
||||
|
||||
#define IWM_NVM_HW_SECTION_NUM_FAMILY_8000 10
|
||||
|
||||
#define IWM_DEVICE_8000_COMMON \
|
||||
.device_family = IWM_DEVICE_FAMILY_8000, \
|
||||
.eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000, \
|
||||
.nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_8000
|
||||
|
||||
const struct iwm_cfg iwm8260_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 8260",
|
||||
.fw_name = IWM8000_FW,
|
||||
IWM_DEVICE_8000_COMMON,
|
||||
.host_interrupt_operation_mode = 0,
|
||||
};
|
||||
|
||||
const struct iwm_cfg iwm8265_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 8265",
|
||||
.fw_name = IWM8265_FW,
|
||||
IWM_DEVICE_8000_COMMON,
|
||||
.host_interrupt_operation_mode = 0,
|
||||
};
|
|
@ -1,97 +0,0 @@
|
|||
/*-
|
||||
* 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,
|
||||
};
|
|
@ -1,96 +0,0 @@
|
|||
/*-
|
||||
* 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,
|
||||
};
|
|
@ -1,254 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* 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 <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/endian.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_regdomain.h>
|
||||
#include <net80211/ieee80211_ratectl.h>
|
||||
#include <net80211/ieee80211_radiotap.h>
|
||||
|
||||
#include <dev/iwm/if_iwmreg.h>
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_util.h>
|
||||
#include <dev/iwm/if_iwm_binding.h>
|
||||
#include <dev/iwm/if_iwm_sf.h>
|
||||
|
||||
/*
|
||||
* BEGIN iwlwifi/mvm/binding.c
|
||||
*/
|
||||
|
||||
struct iwm_iface_iterator_data {
|
||||
int idx;
|
||||
|
||||
struct iwm_phy_ctxt *phyctxt;
|
||||
|
||||
uint16_t ids[IWM_MAX_MACS_IN_BINDING];
|
||||
int16_t colors[IWM_MAX_MACS_IN_BINDING];
|
||||
};
|
||||
|
||||
static int
|
||||
iwm_binding_cmd(struct iwm_softc *sc, uint32_t action,
|
||||
struct iwm_iface_iterator_data *data)
|
||||
{
|
||||
struct iwm_binding_cmd cmd;
|
||||
struct iwm_phy_ctxt *phyctxt = data->phyctxt;
|
||||
int i, ret;
|
||||
uint32_t status;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.id_and_color
|
||||
= htole32(IWM_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));
|
||||
cmd.action = htole32(action);
|
||||
cmd.phy = htole32(IWM_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));
|
||||
|
||||
for (i = 0; i < IWM_MAX_MACS_IN_BINDING; i++)
|
||||
cmd.macs[i] = htole32(IWM_FW_CTXT_INVALID);
|
||||
for (i = 0; i < data->idx; i++)
|
||||
cmd.macs[i] = htole32(IWM_FW_CMD_ID_AND_COLOR(data->ids[i],
|
||||
data->colors[i]));
|
||||
|
||||
status = 0;
|
||||
ret = iwm_send_cmd_pdu_status(sc, IWM_BINDING_CONTEXT_CMD,
|
||||
sizeof(cmd), &cmd, &status);
|
||||
if (ret) {
|
||||
device_printf(sc->sc_dev,
|
||||
"Failed to send binding (action:%d): %d\n", action, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (status) {
|
||||
device_printf(sc->sc_dev,
|
||||
"Binding command failed: %u\n", status);
|
||||
ret = EIO;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_binding_update(struct iwm_softc *sc, struct iwm_vap *ivp,
|
||||
struct iwm_phy_ctxt *phyctxt, boolean_t add)
|
||||
{
|
||||
struct iwm_iface_iterator_data data = {
|
||||
.phyctxt = phyctxt,
|
||||
};
|
||||
uint32_t action;
|
||||
|
||||
if (add)
|
||||
action = IWM_FW_CTXT_ACTION_ADD;
|
||||
else
|
||||
action = IWM_FW_CTXT_ACTION_REMOVE;
|
||||
|
||||
if (add) {
|
||||
data.ids[0] = ivp->id;
|
||||
data.colors[0] = ivp->color;
|
||||
data.idx++;
|
||||
}
|
||||
|
||||
return iwm_binding_cmd(sc, action, &data);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_binding_add_vif(struct iwm_softc *sc, struct iwm_vap *ivp)
|
||||
{
|
||||
if (!ivp->phy_ctxt)
|
||||
return EINVAL;
|
||||
|
||||
/*
|
||||
* Update SF - Disable if needed. if this fails, SF might still be on
|
||||
* while many macs are bound, which is forbidden - so fail the binding.
|
||||
*/
|
||||
if (iwm_sf_update(sc, &ivp->iv_vap, FALSE))
|
||||
return EINVAL;
|
||||
|
||||
return iwm_binding_update(sc, ivp, ivp->phy_ctxt, TRUE);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_binding_remove_vif(struct iwm_softc *sc, struct iwm_vap *ivp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!ivp->phy_ctxt)
|
||||
return EINVAL;
|
||||
|
||||
ret = iwm_binding_update(sc, ivp, ivp->phy_ctxt, FALSE);
|
||||
|
||||
if (!ret) {
|
||||
if (iwm_sf_update(sc, &ivp->iv_vap, TRUE))
|
||||
device_printf(sc->sc_dev,
|
||||
"Failed to update SF state\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef __IF_IWM_BINDING_H__
|
||||
#define __IF_IWM_BINDING_H__
|
||||
|
||||
extern int iwm_binding_add_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__ */
|
|
@ -1,159 +0,0 @@
|
|||
/*-
|
||||
* 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) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* 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) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2016 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef __IWM_CONFIG_H__
|
||||
#define __IWM_CONFIG_H__
|
||||
|
||||
enum iwm_device_family {
|
||||
IWM_DEVICE_FAMILY_UNDEFINED,
|
||||
IWM_DEVICE_FAMILY_7000,
|
||||
IWM_DEVICE_FAMILY_8000,
|
||||
IWM_DEVICE_FAMILY_9000,
|
||||
};
|
||||
|
||||
#define IWM_DEFAULT_MAX_TX_POWER 22
|
||||
|
||||
/* Antenna presence definitions */
|
||||
#define IWM_ANT_NONE 0x0
|
||||
#define IWM_ANT_A (1 << 0)
|
||||
#define IWM_ANT_B (1 << 1)
|
||||
#define IWM_ANT_C (1 << 2)
|
||||
#define IWM_ANT_AB (IWM_ANT_A | IWM_ANT_B)
|
||||
#define IWM_ANT_AC (IWM_ANT_A | IWM_ANT_C)
|
||||
#define IWM_ANT_BC (IWM_ANT_B | IWM_ANT_C)
|
||||
#define IWM_ANT_ABC (IWM_ANT_A | IWM_ANT_B | IWM_ANT_C)
|
||||
|
||||
static inline uint8_t num_of_ant(uint8_t mask)
|
||||
{
|
||||
return !!((mask) & IWM_ANT_A) +
|
||||
!!((mask) & IWM_ANT_B) +
|
||||
!!((mask) & IWM_ANT_C);
|
||||
}
|
||||
|
||||
/* lower blocks contain EEPROM image and calibration data */
|
||||
#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000 (16 * 512 * sizeof(uint16_t)) /* 16 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
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @name: Official name of the device
|
||||
* @fw_name: Firmware filename.
|
||||
* @host_interrupt_operation_mode: device needs host interrupt operation
|
||||
* mode set
|
||||
* @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
|
||||
* 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 {
|
||||
const char *name;
|
||||
const char *fw_name;
|
||||
uint16_t eeprom_size;
|
||||
enum iwm_device_family device_family;
|
||||
int host_interrupt_operation_mode;
|
||||
int mqrx_supported;
|
||||
int integrated;
|
||||
uint8_t nvm_hw_section_num;
|
||||
int apmg_wake_up_wa;
|
||||
enum iwm_nvm_type nvm_type;
|
||||
};
|
||||
|
||||
/*
|
||||
* This list declares the config structures for all devices.
|
||||
*/
|
||||
extern const struct iwm_cfg iwm7260_cfg;
|
||||
extern const struct iwm_cfg iwm3160_cfg;
|
||||
extern const struct iwm_cfg iwm3165_cfg;
|
||||
extern const struct iwm_cfg iwm3168_cfg;
|
||||
extern const struct iwm_cfg iwm7265_cfg;
|
||||
extern const struct iwm_cfg iwm7265d_cfg;
|
||||
extern const struct iwm_cfg iwm8260_cfg;
|
||||
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__ */
|
|
@ -1,154 +0,0 @@
|
|||
/*-
|
||||
* 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) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 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) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#ifndef __IF_IWM_CONSTANTS_H
|
||||
#define __IF_IWM_CONSTANTS_H
|
||||
|
||||
/* <netproto/802_11/ieee80211_var.h> */
|
||||
|
||||
#define IWM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * 1000)
|
||||
#define IWM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * 1000)
|
||||
#define IWM_WOWLAN_PS_TX_DATA_TIMEOUT (10 * 1000)
|
||||
#define IWM_WOWLAN_PS_RX_DATA_TIMEOUT (10 * 1000)
|
||||
#define IWM_SHORT_PS_TX_DATA_TIMEOUT (2 * 1024) /* defined in TU */
|
||||
#define IWM_SHORT_PS_RX_DATA_TIMEOUT (40 * 1024) /* defined in TU */
|
||||
#define IWM_P2P_LOWLATENCY_PS_ENABLE 0
|
||||
#define IWM_UAPSD_RX_DATA_TIMEOUT (50 * 1000)
|
||||
#define IWM_UAPSD_TX_DATA_TIMEOUT (50 * 1000)
|
||||
#ifdef notyet
|
||||
/* XXX Find corresponding values from net80211 */
|
||||
#define IWM_UAPSD_QUEUES (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\
|
||||
IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\
|
||||
IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\
|
||||
IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
|
||||
#endif
|
||||
#define IWM_PS_HEAVY_TX_THLD_PACKETS 20
|
||||
#define IWM_PS_HEAVY_RX_THLD_PACKETS 8
|
||||
#define IWM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30
|
||||
#define IWM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS 20
|
||||
#define IWM_PS_HEAVY_TX_THLD_PERCENT 50
|
||||
#define IWM_PS_HEAVY_RX_THLD_PERCENT 50
|
||||
#define IWM_PS_SNOOZE_INTERVAL 25
|
||||
#define IWM_PS_SNOOZE_WINDOW 50
|
||||
#define IWM_WOWLAN_PS_SNOOZE_WINDOW 25
|
||||
#define IWM_LOWLAT_QUOTA_MIN_PERCENT 64
|
||||
#define IWM_BT_COEX_EN_RED_TXP_THRESH 62
|
||||
#define IWM_BT_COEX_DIS_RED_TXP_THRESH 65
|
||||
#define IWM_BT_COEX_SYNC2SCO 1
|
||||
#define IWM_BT_COEX_CORUNNING 0
|
||||
#define IWM_BT_COEX_MPLUT 1
|
||||
#define IWM_BT_COEX_RRC 1
|
||||
#define IWM_BT_COEX_TTC 1
|
||||
#define IWM_BT_COEX_MPLUT_REG0 0x22002200
|
||||
#define IWM_BT_COEX_MPLUT_REG1 0x11118451
|
||||
#define IWM_BT_COEX_ANTENNA_COUPLING_THRS 30
|
||||
#define IWM_FW_MCAST_FILTER_PASS_ALL 0
|
||||
#define IWM_FW_BCAST_FILTER_PASS_ALL 0
|
||||
#define IWM_QUOTA_THRESHOLD 4
|
||||
#define IWM_RS_RSSI_BASED_INIT_RATE 0
|
||||
#define IWM_RS_80_20_FAR_RANGE_TWEAK 1
|
||||
#define IWM_TOF_IS_RESPONDER 0
|
||||
#define IWM_SW_TX_CSUM_OFFLOAD 0
|
||||
#define IWM_HW_CSUM_DISABLE 0
|
||||
#define IWM_COLLECT_FW_ERR_DUMP 1
|
||||
#define IWM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1
|
||||
#define IWM_RS_HT_VHT_RETRIES_PER_RATE 2
|
||||
#define IWM_RS_HT_VHT_RETRIES_PER_RATE_TW 1
|
||||
#define IWM_RS_INITIAL_MIMO_NUM_RATES 3
|
||||
#define IWM_RS_INITIAL_SISO_NUM_RATES 3
|
||||
#define IWM_RS_INITIAL_LEGACY_NUM_RATES 2
|
||||
#define IWM_RS_INITIAL_LEGACY_RETRIES 2
|
||||
#define IWM_RS_SECONDARY_LEGACY_RETRIES 1
|
||||
#define IWM_RS_SECONDARY_LEGACY_NUM_RATES 16
|
||||
#define IWM_RS_SECONDARY_SISO_NUM_RATES 3
|
||||
#define IWM_RS_SECONDARY_SISO_RETRIES 1
|
||||
#define IWM_RS_RATE_MIN_FAILURE_TH 3
|
||||
#define IWM_RS_RATE_MIN_SUCCESS_TH 8
|
||||
#define IWM_RS_STAY_IN_COLUMN_TIMEOUT 5 /* Seconds */
|
||||
#define IWM_RS_IDLE_TIMEOUT 5 /* Seconds */
|
||||
#define IWM_RS_MISSED_RATE_MAX 15
|
||||
#define IWM_RS_LEGACY_FAILURE_LIMIT 160
|
||||
#define IWM_RS_LEGACY_SUCCESS_LIMIT 480
|
||||
#define IWM_RS_LEGACY_TABLE_COUNT 160
|
||||
#define IWM_RS_NON_LEGACY_FAILURE_LIMIT 400
|
||||
#define IWM_RS_NON_LEGACY_SUCCESS_LIMIT 4500
|
||||
#define IWM_RS_NON_LEGACY_TABLE_COUNT 1500
|
||||
#define IWM_RS_SR_FORCE_DECREASE 15 /* percent */
|
||||
#define IWM_RS_SR_NO_DECREASE 85 /* percent */
|
||||
#define IWM_RS_AGG_TIME_LIMIT 4000 /* 4 msecs. valid 100-8000 */
|
||||
#define IWM_RS_AGG_DISABLE_START 3
|
||||
#define IWM_RS_TPC_SR_FORCE_INCREASE 75 /* percent */
|
||||
#define IWM_RS_TPC_SR_NO_INCREASE 85 /* percent */
|
||||
#define IWM_RS_TPC_TX_POWER_STEP 3
|
||||
|
||||
#endif /* __IF_IWM_CONSTANTS_H */
|
|
@ -1,62 +0,0 @@
|
|||
/*-
|
||||
* Copyright (c) 2015 Adrian Chadd <adrian@FreeBSD.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef __IF_IWM_DEBUG_H__
|
||||
#define __IF_IWM_DEBUG_H__
|
||||
|
||||
#ifdef IWM_DEBUG
|
||||
enum {
|
||||
IWM_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
|
||||
IWM_DEBUG_RECV = 0x00000002, /* basic recv operation */
|
||||
IWM_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */
|
||||
IWM_DEBUG_TXPOW = 0x00000008, /* tx power processing */
|
||||
IWM_DEBUG_RESET = 0x00000010, /* reset processing */
|
||||
IWM_DEBUG_OPS = 0x00000020, /* iwm_ops processing */
|
||||
IWM_DEBUG_BEACON = 0x00000040, /* beacon handling */
|
||||
IWM_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */
|
||||
IWM_DEBUG_INTR = 0x00000100, /* ISR */
|
||||
IWM_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */
|
||||
IWM_DEBUG_NODE = 0x00000400, /* node management */
|
||||
IWM_DEBUG_LED = 0x00000800, /* led management */
|
||||
IWM_DEBUG_CMD = 0x00001000, /* cmd submission */
|
||||
IWM_DEBUG_TXRATE = 0x00002000, /* TX rate debugging */
|
||||
IWM_DEBUG_PWRSAVE = 0x00004000, /* Power save operations */
|
||||
IWM_DEBUG_SCAN = 0x00008000, /* Scan related operations */
|
||||
IWM_DEBUG_STATS = 0x00010000, /* Statistics updates */
|
||||
IWM_DEBUG_FIRMWARE_TLV = 0x00020000, /* Firmware TLV parsing */
|
||||
IWM_DEBUG_TRANS = 0x00040000, /* Transport layer (eg PCIe) */
|
||||
IWM_DEBUG_EEPROM = 0x00080000, /* EEPROM/channel information */
|
||||
IWM_DEBUG_TEMP = 0x00100000, /* Thermal Sensor handling */
|
||||
IWM_DEBUG_FW = 0x00200000, /* Firmware management */
|
||||
IWM_DEBUG_LAR = 0x00400000, /* Location Aware Regulatory */
|
||||
IWM_DEBUG_TE = 0x00800000, /* Time Event handling */
|
||||
IWM_DEBUG_REGISTER = 0x20000000, /* print chipset register */
|
||||
IWM_DEBUG_TRACE = 0x40000000, /* Print begin and start driver function */
|
||||
IWM_DEBUG_FATAL = 0x80000000, /* fatal errors */
|
||||
IWM_DEBUG_ANY = 0xffffffff
|
||||
};
|
||||
|
||||
#define IWM_DPRINTF(sc, m, fmt, ...) do { \
|
||||
if (sc->sc_debug & (m)) \
|
||||
device_printf(sc->sc_dev, fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define IWM_DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
|
||||
#endif
|
||||
|
||||
#endif /* __IF_IWM_DEBUG_H__ */
|
|
@ -1,342 +0,0 @@
|
|||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 4.7.3 (tag id d7f6728f57e3ecbb7ef34eb7d9f564d514775d75)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 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) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 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 <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/endian.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_regdomain.h>
|
||||
#include <net80211/ieee80211_ratectl.h>
|
||||
#include <net80211/ieee80211_radiotap.h>
|
||||
|
||||
#include <dev/iwm/if_iwmreg.h>
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_util.h>
|
||||
#include <dev/iwm/if_iwm_fw.h>
|
||||
|
||||
void
|
||||
iwm_free_fw_paging(struct iwm_softc *sc)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (sc->fw_paging_db[0].fw_paging_block.vaddr == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < IWM_NUM_OF_FW_PAGING_BLOCKS; i++) {
|
||||
iwm_dma_contig_free(&sc->fw_paging_db[i].fw_paging_block);
|
||||
}
|
||||
|
||||
memset(sc->fw_paging_db, 0, sizeof(sc->fw_paging_db));
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_fill_paging_mem(struct iwm_softc *sc, const struct iwm_fw_img *image)
|
||||
{
|
||||
int sec_idx, idx;
|
||||
uint32_t offset = 0;
|
||||
|
||||
/*
|
||||
* find where is the paging image start point:
|
||||
* if CPU2 exist and it's in paging format, then the image looks like:
|
||||
* CPU1 sections (2 or more)
|
||||
* CPU1_CPU2_SEPARATOR_SECTION delimiter - separate between CPU1 to CPU2
|
||||
* CPU2 sections (not paged)
|
||||
* PAGING_SEPARATOR_SECTION delimiter - separate between CPU2
|
||||
* non paged to CPU2 paging sec
|
||||
* CPU2 paging CSS
|
||||
* CPU2 paging image (including instruction and data)
|
||||
*/
|
||||
for (sec_idx = 0; sec_idx < IWM_UCODE_SECTION_MAX; sec_idx++) {
|
||||
if (image->sec[sec_idx].offset == IWM_PAGING_SEPARATOR_SECTION) {
|
||||
sec_idx++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If paging is enabled there should be at least 2 more sections left
|
||||
* (one for CSS and one for Paging data)
|
||||
*/
|
||||
if (sec_idx >= nitems(image->sec) - 1) {
|
||||
device_printf(sc->sc_dev,
|
||||
"Paging: Missing CSS and/or paging sections\n");
|
||||
iwm_free_fw_paging(sc);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* copy the CSS block to the dram */
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_FW,
|
||||
"Paging: load paging CSS to FW, sec = %d\n",
|
||||
sec_idx);
|
||||
|
||||
memcpy(sc->fw_paging_db[0].fw_paging_block.vaddr,
|
||||
image->sec[sec_idx].data,
|
||||
sc->fw_paging_db[0].fw_paging_size);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_FW,
|
||||
"Paging: copied %d CSS bytes to first block\n",
|
||||
sc->fw_paging_db[0].fw_paging_size);
|
||||
|
||||
sec_idx++;
|
||||
|
||||
/*
|
||||
* copy the paging blocks to the dram
|
||||
* loop index start from 1 since that CSS block already copied to dram
|
||||
* and CSS index is 0.
|
||||
* loop stop at num_of_paging_blk since that last block is not full.
|
||||
*/
|
||||
for (idx = 1; idx < sc->num_of_paging_blk; idx++) {
|
||||
memcpy(sc->fw_paging_db[idx].fw_paging_block.vaddr,
|
||||
(const char *)image->sec[sec_idx].data + offset,
|
||||
sc->fw_paging_db[idx].fw_paging_size);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_FW,
|
||||
"Paging: copied %d paging bytes to block %d\n",
|
||||
sc->fw_paging_db[idx].fw_paging_size,
|
||||
idx);
|
||||
|
||||
offset += sc->fw_paging_db[idx].fw_paging_size;
|
||||
}
|
||||
|
||||
/* copy the last paging block */
|
||||
if (sc->num_of_pages_in_last_blk > 0) {
|
||||
memcpy(sc->fw_paging_db[idx].fw_paging_block.vaddr,
|
||||
(const char *)image->sec[sec_idx].data + offset,
|
||||
IWM_FW_PAGING_SIZE * sc->num_of_pages_in_last_blk);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_FW,
|
||||
"Paging: copied %d pages in the last block %d\n",
|
||||
sc->num_of_pages_in_last_blk, idx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_alloc_fw_paging_mem(struct iwm_softc *sc, const struct iwm_fw_img *image)
|
||||
{
|
||||
int blk_idx = 0;
|
||||
int error, num_of_pages;
|
||||
|
||||
if (sc->fw_paging_db[0].fw_paging_block.vaddr != NULL) {
|
||||
int i;
|
||||
/* Device got reset, and we setup firmware paging again */
|
||||
for (i = 0; i < sc->num_of_paging_blk + 1; i++) {
|
||||
bus_dmamap_sync(sc->sc_dmat,
|
||||
sc->fw_paging_db[i].fw_paging_block.map,
|
||||
BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ensure IWM_BLOCK_2_EXP_SIZE is power of 2 of IWM_PAGING_BLOCK_SIZE */
|
||||
_Static_assert((1 << IWM_BLOCK_2_EXP_SIZE) == IWM_PAGING_BLOCK_SIZE,
|
||||
"IWM_BLOCK_2_EXP_SIZE must be power of 2 of IWM_PAGING_BLOCK_SIZE");
|
||||
|
||||
num_of_pages = image->paging_mem_size / IWM_FW_PAGING_SIZE;
|
||||
sc->num_of_paging_blk = ((num_of_pages - 1) /
|
||||
IWM_NUM_OF_PAGE_PER_GROUP) + 1;
|
||||
|
||||
sc->num_of_pages_in_last_blk =
|
||||
num_of_pages -
|
||||
IWM_NUM_OF_PAGE_PER_GROUP * (sc->num_of_paging_blk - 1);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_FW,
|
||||
"Paging: allocating mem for %d paging blocks, each block holds 8 pages, last block holds %d pages\n",
|
||||
sc->num_of_paging_blk,
|
||||
sc->num_of_pages_in_last_blk);
|
||||
|
||||
/* allocate block of 4Kbytes for paging CSS */
|
||||
error = iwm_dma_contig_alloc(sc->sc_dmat,
|
||||
&sc->fw_paging_db[blk_idx].fw_paging_block, IWM_FW_PAGING_SIZE,
|
||||
4096);
|
||||
if (error) {
|
||||
/* free all the previous pages since we failed */
|
||||
iwm_free_fw_paging(sc);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
sc->fw_paging_db[blk_idx].fw_paging_size = IWM_FW_PAGING_SIZE;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_FW,
|
||||
"Paging: allocated 4K(CSS) bytes for firmware paging.\n");
|
||||
|
||||
/*
|
||||
* allocate blocks in dram.
|
||||
* since that CSS allocated in fw_paging_db[0] loop start from index 1
|
||||
*/
|
||||
for (blk_idx = 1; blk_idx < sc->num_of_paging_blk + 1; blk_idx++) {
|
||||
/* allocate block of IWM_PAGING_BLOCK_SIZE (32K) */
|
||||
/* XXX Use iwm_dma_contig_alloc for allocating */
|
||||
error = iwm_dma_contig_alloc(sc->sc_dmat,
|
||||
&sc->fw_paging_db[blk_idx].fw_paging_block,
|
||||
IWM_PAGING_BLOCK_SIZE, 4096);
|
||||
if (error) {
|
||||
/* free all the previous pages since we failed */
|
||||
iwm_free_fw_paging(sc);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
sc->fw_paging_db[blk_idx].fw_paging_size = IWM_PAGING_BLOCK_SIZE;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_FW,
|
||||
"Paging: allocated 32K bytes for firmware paging.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_save_fw_paging(struct iwm_softc *sc, const struct iwm_fw_img *fw)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iwm_alloc_fw_paging_mem(sc, fw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return iwm_fill_paging_mem(sc, fw);
|
||||
}
|
||||
|
||||
/* send paging cmd to FW in case CPU2 has paging image */
|
||||
int
|
||||
iwm_send_paging_cmd(struct iwm_softc *sc, const struct iwm_fw_img *fw)
|
||||
{
|
||||
int blk_idx;
|
||||
uint32_t dev_phy_addr;
|
||||
struct iwm_fw_paging_cmd fw_paging_cmd = {
|
||||
.flags =
|
||||
htole32(IWM_PAGING_CMD_IS_SECURED |
|
||||
IWM_PAGING_CMD_IS_ENABLED |
|
||||
(sc->num_of_pages_in_last_blk <<
|
||||
IWM_PAGING_CMD_NUM_OF_PAGES_IN_LAST_GRP_POS)),
|
||||
.block_size = htole32(IWM_BLOCK_2_EXP_SIZE),
|
||||
.block_num = htole32(sc->num_of_paging_blk),
|
||||
};
|
||||
|
||||
/* loop for for all paging blocks + CSS block */
|
||||
for (blk_idx = 0; blk_idx < sc->num_of_paging_blk + 1; blk_idx++) {
|
||||
dev_phy_addr = htole32(
|
||||
sc->fw_paging_db[blk_idx].fw_paging_block.paddr >>
|
||||
IWM_PAGE_2_EXP_SIZE);
|
||||
fw_paging_cmd.device_phy_addr[blk_idx] = dev_phy_addr;
|
||||
bus_dmamap_sync(sc->sc_dmat,
|
||||
sc->fw_paging_db[blk_idx].fw_paging_block.map,
|
||||
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
||||
}
|
||||
|
||||
return iwm_send_cmd_pdu(sc, iwm_cmd_id(IWM_FW_PAGING_BLOCK_CMD,
|
||||
IWM_ALWAYS_LONG_GROUP, 0),
|
||||
0, sizeof(fw_paging_cmd), &fw_paging_cmd);
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 4.7.3 (tag id d7f6728f57e3ecbb7ef34eb7d9f564d514775d75)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 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) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef __IF_IWM_FW_H__
|
||||
#define __IF_IWM_FW_H__
|
||||
|
||||
/*
|
||||
* Block paging calculations
|
||||
*/
|
||||
#define IWM_PAGE_2_EXP_SIZE 12 /* 4K == 2^12 */
|
||||
#define IWM_FW_PAGING_SIZE (1 << IWM_PAGE_2_EXP_SIZE) /* page size is 4KB */
|
||||
#define IWM_PAGE_PER_GROUP_2_EXP_SIZE 3
|
||||
/* 8 pages per group */
|
||||
#define IWM_NUM_OF_PAGE_PER_GROUP (1 << IWM_PAGE_PER_GROUP_2_EXP_SIZE)
|
||||
/* don't change, support only 32KB size */
|
||||
#define IWM_PAGING_BLOCK_SIZE (IWM_NUM_OF_PAGE_PER_GROUP * IWM_FW_PAGING_SIZE)
|
||||
/* 32K == 2^15 */
|
||||
#define IWM_BLOCK_2_EXP_SIZE (IWM_PAGE_2_EXP_SIZE + IWM_PAGE_PER_GROUP_2_EXP_SIZE)
|
||||
|
||||
/*
|
||||
* Image paging calculations
|
||||
*/
|
||||
#define IWM_BLOCK_PER_IMAGE_2_EXP_SIZE 5
|
||||
/* 2^5 == 32 blocks per image */
|
||||
#define IWM_NUM_OF_BLOCK_PER_IMAGE (1 << IWM_BLOCK_PER_IMAGE_2_EXP_SIZE)
|
||||
/* maximum image size 1024KB */
|
||||
#define IWM_MAX_PAGING_IMAGE_SIZE (IWM_NUM_OF_BLOCK_PER_IMAGE * IWM_PAGING_BLOCK_SIZE)
|
||||
|
||||
/* Virtual address signature */
|
||||
#define IWM_PAGING_ADDR_SIG 0xAA000000
|
||||
|
||||
#define IWM_PAGING_CMD_IS_SECURED (1 << 9)
|
||||
#define IWM_PAGING_CMD_IS_ENABLED (1 << 8)
|
||||
#define IWM_PAGING_CMD_NUM_OF_PAGES_IN_LAST_GRP_POS 0
|
||||
#define IWM_PAGING_TLV_SECURE_MASK 1
|
||||
|
||||
extern void iwm_free_fw_paging(struct iwm_softc *);
|
||||
extern int iwm_save_fw_paging(struct iwm_softc *, const struct iwm_fw_img *);
|
||||
extern int iwm_send_paging_cmd(struct iwm_softc *, const struct iwm_fw_img *);
|
||||
|
||||
#endif /* __IF_IWM_FW_H__ */
|
|
@ -1,188 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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 <sys/bus.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/endian.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_regdomain.h>
|
||||
#include <net80211/ieee80211_ratectl.h>
|
||||
#include <net80211/ieee80211_radiotap.h>
|
||||
|
||||
#include <dev/iwm/if_iwmreg.h>
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_util.h>
|
||||
#include <dev/iwm/if_iwm_led.h>
|
||||
|
||||
/* Set led register on */
|
||||
void
|
||||
iwm_led_enable(struct iwm_softc *sc)
|
||||
{
|
||||
IWM_WRITE(sc, IWM_CSR_LED_REG, IWM_CSR_LED_REG_TURN_ON);
|
||||
}
|
||||
|
||||
/* Set led register off */
|
||||
void
|
||||
iwm_led_disable(struct iwm_softc *sc)
|
||||
{
|
||||
IWM_WRITE(sc, IWM_CSR_LED_REG, IWM_CSR_LED_REG_TURN_OFF);
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_led_is_enabled(struct iwm_softc *sc)
|
||||
{
|
||||
return (IWM_READ(sc, IWM_CSR_LED_REG) == IWM_CSR_LED_REG_TURN_ON);
|
||||
}
|
||||
|
||||
static void
|
||||
iwm_led_blink_timeout(void *arg)
|
||||
{
|
||||
struct iwm_softc *sc = arg;
|
||||
|
||||
if (sc->sc_attached == 0)
|
||||
return;
|
||||
|
||||
if (iwm_led_is_enabled(sc))
|
||||
iwm_led_disable(sc);
|
||||
else
|
||||
iwm_led_enable(sc);
|
||||
|
||||
callout_reset(&sc->sc_led_blink_to, (200 * hz) / 1000,
|
||||
iwm_led_blink_timeout, sc);
|
||||
}
|
||||
|
||||
void
|
||||
iwm_led_blink_start(struct iwm_softc *sc)
|
||||
{
|
||||
callout_reset(&sc->sc_led_blink_to, 0, iwm_led_blink_timeout, sc);
|
||||
}
|
||||
|
||||
void
|
||||
iwm_led_blink_stop(struct iwm_softc *sc)
|
||||
{
|
||||
callout_stop(&sc->sc_led_blink_to);
|
||||
iwm_led_disable(sc);
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef __IF_IWM_LED_H__
|
||||
#define __IF_IWM_LED_H__
|
||||
|
||||
extern void iwm_led_enable(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_stop(struct iwm_softc *);
|
||||
|
||||
#endif /* __IF_IWM_LED_H__ */
|
|
@ -1,561 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_wlan.h"
|
||||
#include "opt_iwm.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/endian.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_regdomain.h>
|
||||
#include <net80211/ieee80211_ratectl.h>
|
||||
#include <net80211/ieee80211_radiotap.h>
|
||||
|
||||
#include <dev/iwm/if_iwmreg.h>
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_util.h>
|
||||
#include <dev/iwm/if_iwm_mac_ctxt.h>
|
||||
|
||||
/*
|
||||
* BEGIN mvm/mac-ctxt.c
|
||||
*/
|
||||
|
||||
const uint8_t iwm_ac_to_tx_fifo[] = {
|
||||
IWM_TX_FIFO_BE,
|
||||
IWM_TX_FIFO_BK,
|
||||
IWM_TX_FIFO_VI,
|
||||
IWM_TX_FIFO_VO,
|
||||
};
|
||||
|
||||
static void
|
||||
iwm_ack_rates(struct iwm_softc *sc, int is2ghz,
|
||||
int *cck_rates, int *ofdm_rates, struct iwm_node *in)
|
||||
{
|
||||
int lowest_present_ofdm = 100;
|
||||
int lowest_present_cck = 100;
|
||||
uint8_t cck = 0;
|
||||
uint8_t ofdm = 0;
|
||||
int i;
|
||||
struct ieee80211_rateset *rs = &in->in_ni.ni_rates;
|
||||
|
||||
if (is2ghz) {
|
||||
for (i = IWM_FIRST_CCK_RATE; i <= IWM_LAST_CCK_RATE; i++) {
|
||||
if ((iwm_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0)
|
||||
continue;
|
||||
cck |= (1 << i);
|
||||
if (lowest_present_cck > i)
|
||||
lowest_present_cck = i;
|
||||
}
|
||||
}
|
||||
for (i = IWM_FIRST_OFDM_RATE; i <= IWM_LAST_NON_HT_RATE; i++) {
|
||||
if ((iwm_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0)
|
||||
continue;
|
||||
ofdm |= (1 << (i - IWM_FIRST_OFDM_RATE));
|
||||
if (lowest_present_ofdm > i)
|
||||
lowest_present_ofdm = i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we've got the basic rates as bitmaps in the ofdm and cck
|
||||
* variables. This isn't sufficient though, as there might not
|
||||
* be all the right rates in the bitmap. E.g. if the only basic
|
||||
* rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps
|
||||
* and 6 Mbps because the 802.11-2007 standard says in 9.6:
|
||||
*
|
||||
* [...] a STA responding to a received frame shall transmit
|
||||
* its Control Response frame [...] at the highest rate in the
|
||||
* BSSBasicRateSet parameter that is less than or equal to the
|
||||
* rate of the immediately previous frame in the frame exchange
|
||||
* sequence ([...]) and that is of the same modulation class
|
||||
* ([...]) as the received frame. If no rate contained in the
|
||||
* BSSBasicRateSet parameter meets these conditions, then the
|
||||
* control frame sent in response to a received frame shall be
|
||||
* transmitted at the highest mandatory rate of the PHY that is
|
||||
* less than or equal to the rate of the received frame, and
|
||||
* that is of the same modulation class as the received frame.
|
||||
*
|
||||
* As a consequence, we need to add all mandatory rates that are
|
||||
* lower than all of the basic rates to these bitmaps.
|
||||
*/
|
||||
|
||||
if (IWM_RATE_24M_INDEX < lowest_present_ofdm)
|
||||
ofdm |= IWM_RATE_BIT_MSK(24) >> IWM_FIRST_OFDM_RATE;
|
||||
if (IWM_RATE_12M_INDEX < lowest_present_ofdm)
|
||||
ofdm |= IWM_RATE_BIT_MSK(12) >> IWM_FIRST_OFDM_RATE;
|
||||
/* 6M already there or needed so always add */
|
||||
ofdm |= IWM_RATE_BIT_MSK(6) >> IWM_FIRST_OFDM_RATE;
|
||||
|
||||
/*
|
||||
* CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP.
|
||||
* Note, however:
|
||||
* - if no CCK rates are basic, it must be ERP since there must
|
||||
* be some basic rates at all, so they're OFDM => ERP PHY
|
||||
* (or we're in 5 GHz, and the cck bitmap will never be used)
|
||||
* - if 11M is a basic rate, it must be ERP as well, so add 5.5M
|
||||
* - if 5.5M is basic, 1M and 2M are mandatory
|
||||
* - if 2M is basic, 1M is mandatory
|
||||
* - if 1M is basic, that's the only valid ACK rate.
|
||||
* As a consequence, it's not as complicated as it sounds, just add
|
||||
* any lower rates to the ACK rate bitmap.
|
||||
*/
|
||||
if (IWM_RATE_11M_INDEX < lowest_present_cck)
|
||||
cck |= IWM_RATE_BIT_MSK(11) >> IWM_FIRST_CCK_RATE;
|
||||
if (IWM_RATE_5M_INDEX < lowest_present_cck)
|
||||
cck |= IWM_RATE_BIT_MSK(5) >> IWM_FIRST_CCK_RATE;
|
||||
if (IWM_RATE_2M_INDEX < lowest_present_cck)
|
||||
cck |= IWM_RATE_BIT_MSK(2) >> IWM_FIRST_CCK_RATE;
|
||||
/* 1M already there or needed so always add */
|
||||
cck |= IWM_RATE_BIT_MSK(1) >> IWM_FIRST_CCK_RATE;
|
||||
|
||||
*cck_rates = cck;
|
||||
*ofdm_rates = ofdm;
|
||||
}
|
||||
|
||||
static void
|
||||
iwm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in,
|
||||
struct iwm_mac_ctx_cmd *cmd, uint32_t action)
|
||||
{
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
|
||||
struct ieee80211_node *ni = vap->iv_bss;
|
||||
struct iwm_vap *ivp = IWM_VAP(vap);
|
||||
int cck_ack_rates, ofdm_ack_rates;
|
||||
int i;
|
||||
int is2ghz;
|
||||
|
||||
/*
|
||||
* id is the MAC address ID - something to do with MAC filtering.
|
||||
* color - not sure.
|
||||
*
|
||||
* These are both functions of the vap, not of the node.
|
||||
* So, for now, hard-code both to 0 (default).
|
||||
*/
|
||||
cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id,
|
||||
ivp->color));
|
||||
cmd->action = htole32(action);
|
||||
|
||||
cmd->mac_type = htole32(IWM_FW_MAC_TYPE_BSS_STA);
|
||||
|
||||
/*
|
||||
* The TSF ID is one of four TSF tracking resources in the firmware.
|
||||
* Read the iwlwifi/mvm code for more details.
|
||||
*
|
||||
* For now, just hard-code it to TSF tracking ID 0; we only support
|
||||
* a single STA mode VAP.
|
||||
*
|
||||
* It's per-vap, not per-node.
|
||||
*/
|
||||
cmd->tsf_id = htole32(IWM_DEFAULT_TSFID);
|
||||
|
||||
IEEE80211_ADDR_COPY(cmd->node_addr, vap->iv_myaddr);
|
||||
|
||||
/*
|
||||
* XXX should we error out if in_assoc is 1 and ni == NULL?
|
||||
*/
|
||||
#if 0
|
||||
if (in->in_assoc) {
|
||||
IEEE80211_ADDR_COPY(cmd->bssid_addr, ni->ni_bssid);
|
||||
} else {
|
||||
/* eth broadcast address */
|
||||
IEEE80211_ADDR_COPY(cmd->bssid_addr, ieee80211broadcastaddr);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* XXX This workaround makes the firmware behave more correctly once
|
||||
* we are associated, regularly giving us statistics notifications,
|
||||
* as well as signaling missed beacons to us.
|
||||
* Since we only call iwm_mac_ctxt_add() and
|
||||
* iwm_mac_ctxt_changed() when already authenticating or
|
||||
* associating, ni->ni_bssid should always make sense here.
|
||||
*/
|
||||
if (ivp->iv_auth) {
|
||||
IEEE80211_ADDR_COPY(cmd->bssid_addr, ni->ni_bssid);
|
||||
} else {
|
||||
/* XXX Or maybe all zeroes address? */
|
||||
IEEE80211_ADDR_COPY(cmd->bssid_addr, ieee80211broadcastaddr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default to 2ghz if no node information is given.
|
||||
*/
|
||||
if (in && in->in_ni.ni_chan != IEEE80211_CHAN_ANYC) {
|
||||
is2ghz = !! IEEE80211_IS_CHAN_2GHZ(in->in_ni.ni_chan);
|
||||
} else {
|
||||
is2ghz = 1;
|
||||
}
|
||||
iwm_ack_rates(sc, is2ghz, &cck_ack_rates, &ofdm_ack_rates, in);
|
||||
cmd->cck_rates = htole32(cck_ack_rates);
|
||||
cmd->ofdm_rates = htole32(ofdm_ack_rates);
|
||||
|
||||
cmd->cck_short_preamble
|
||||
= htole32((ic->ic_flags & IEEE80211_F_SHPREAMBLE)
|
||||
? IWM_MAC_FLG_SHORT_PREAMBLE : 0);
|
||||
cmd->short_slot
|
||||
= htole32((ic->ic_flags & IEEE80211_F_SHSLOT)
|
||||
? IWM_MAC_FLG_SHORT_SLOT : 0);
|
||||
|
||||
/*
|
||||
* XXX TODO: if we're doing QOS..
|
||||
* cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA)
|
||||
*/
|
||||
|
||||
for (i = 0; i < WME_NUM_AC; 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_max = htole16(ivp->queue_params[i].cw_max);
|
||||
cmd->ac[txf].edca_txop =
|
||||
htole16(ivp->queue_params[i].edca_txop);
|
||||
cmd->ac[txf].aifsn = ivp->queue_params[i].aifsn;
|
||||
cmd->ac[txf].fifos_mask = (1 << txf);
|
||||
}
|
||||
|
||||
if (ivp->have_wme)
|
||||
cmd->qos_flags |= htole32(IWM_MAC_QOS_FLG_UPDATE_EDCA);
|
||||
|
||||
if (ic->ic_flags & IEEE80211_F_USEPROT)
|
||||
cmd->protection_flags |= htole32(IWM_MAC_PROT_FLG_TGG_PROTECT);
|
||||
|
||||
cmd->filter_flags = htole32(IWM_MAC_FILTER_ACCEPT_GRP);
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_mac_ctxt_send_cmd(struct iwm_softc *sc, struct iwm_mac_ctx_cmd *cmd)
|
||||
{
|
||||
int ret = iwm_send_cmd_pdu(sc, IWM_MAC_CONTEXT_CMD, IWM_CMD_SYNC,
|
||||
sizeof(*cmd), cmd);
|
||||
if (ret)
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: Failed to send MAC context (action:%d): %d\n",
|
||||
__func__, le32toh(cmd->action), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill the specific data for mac context of type station or p2p client
|
||||
*/
|
||||
static void
|
||||
iwm_mac_ctxt_cmd_fill_sta(struct iwm_softc *sc, struct iwm_node *in,
|
||||
struct iwm_mac_data_sta *ctxt_sta, int force_assoc_off)
|
||||
{
|
||||
struct ieee80211_node *ni = &in->in_ni;
|
||||
unsigned dtim_period, dtim_count;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
|
||||
|
||||
/* will this work? */
|
||||
dtim_period = vap->iv_dtim_period;
|
||||
dtim_count = vap->iv_dtim_count;
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_BEACON | IWM_DEBUG_CMD,
|
||||
"%s: force_assoc_off=%d\n", __func__, force_assoc_off);
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_BEACON | IWM_DEBUG_CMD,
|
||||
"DTIM: period=%d count=%d\n", dtim_period, dtim_count);
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_BEACON | IWM_DEBUG_CMD,
|
||||
"BEACON: tsf: %llu, ni_intval=%d\n",
|
||||
(unsigned long long) le64toh(ni->ni_tstamp.tsf),
|
||||
ni->ni_intval);
|
||||
|
||||
/* We need the dtim_period to set the MAC as associated */
|
||||
if (in->in_assoc && dtim_period && !force_assoc_off) {
|
||||
uint64_t tsf;
|
||||
uint32_t dtim_offs;
|
||||
|
||||
/*
|
||||
* The DTIM count counts down, so when it is N that means N
|
||||
* more beacon intervals happen until the DTIM TBTT. Therefore
|
||||
* add this to the current time. If that ends up being in the
|
||||
* future, the firmware will handle it.
|
||||
*
|
||||
* Also note that the system_timestamp (which we get here as
|
||||
* "sync_device_ts") and TSF timestamp aren't at exactly the
|
||||
* same offset in the frame -- the TSF is at the first symbol
|
||||
* of the TSF, the system timestamp is at signal acquisition
|
||||
* time. This means there's an offset between them of at most
|
||||
* a few hundred microseconds (24 * 8 bits + PLCP time gives
|
||||
* 384us in the longest case), this is currently not relevant
|
||||
* as the firmware wakes up around 2ms before the TBTT.
|
||||
*/
|
||||
dtim_offs = dtim_count * ni->ni_intval;
|
||||
/* convert TU to usecs */
|
||||
dtim_offs *= 1024;
|
||||
|
||||
/*
|
||||
* net80211: TSF is in 802.11 order, so convert up to local
|
||||
* ordering before we manipulate things.
|
||||
*/
|
||||
tsf = le64toh(ni->ni_tstamp.tsf);
|
||||
|
||||
ctxt_sta->dtim_tsf = htole64(tsf + dtim_offs);
|
||||
ctxt_sta->dtim_time = htole32(tsf + dtim_offs);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_BEACON | IWM_DEBUG_CMD,
|
||||
"DTIM TBTT is 0x%llx/0x%x, offset %d\n",
|
||||
(long long)le64toh(ctxt_sta->dtim_tsf),
|
||||
le32toh(ctxt_sta->dtim_time), dtim_offs);
|
||||
|
||||
ctxt_sta->is_assoc = htole32(1);
|
||||
} else {
|
||||
ctxt_sta->is_assoc = htole32(0);
|
||||
}
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_CMD | IWM_DEBUG_BEACON,
|
||||
"%s: ni_intval: %d, bi_reciprocal: %d, dtim_interval: %d, dtim_reciprocal: %d\n",
|
||||
__func__,
|
||||
ni->ni_intval,
|
||||
iwm_reciprocal(ni->ni_intval),
|
||||
ni->ni_intval * dtim_period,
|
||||
iwm_reciprocal(ni->ni_intval * dtim_period));
|
||||
|
||||
ctxt_sta->bi = htole32(ni->ni_intval);
|
||||
ctxt_sta->bi_reciprocal = htole32(iwm_reciprocal(ni->ni_intval));
|
||||
ctxt_sta->dtim_interval = htole32(ni->ni_intval * dtim_period);
|
||||
ctxt_sta->dtim_reciprocal =
|
||||
htole32(iwm_reciprocal(ni->ni_intval * dtim_period));
|
||||
|
||||
/* 10 = CONN_MAX_LISTEN_INTERVAL */
|
||||
ctxt_sta->listen_interval = htole32(10);
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_CMD | IWM_DEBUG_BEACON,
|
||||
"%s: associd=%d\n", __func__, IEEE80211_AID(ni->ni_associd));
|
||||
ctxt_sta->assoc_id = htole32(IEEE80211_AID(ni->ni_associd));
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_mac_ctxt_cmd_station(struct iwm_softc *sc, struct ieee80211vap *vap,
|
||||
uint32_t action)
|
||||
{
|
||||
struct ieee80211_node *ni = vap->iv_bss;
|
||||
struct iwm_node *in = IWM_NODE(ni);
|
||||
struct iwm_mac_ctx_cmd cmd = {};
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET,
|
||||
"%s: called; action=%d\n", __func__, action);
|
||||
|
||||
/* Fill the common data for all mac context types */
|
||||
iwm_mac_ctxt_cmd_common(sc, in, &cmd, action);
|
||||
|
||||
/* Allow beacons to pass through as long as we are not associated,or we
|
||||
* do not have dtim period information */
|
||||
if (!in->in_assoc || !vap->iv_dtim_period)
|
||||
cmd.filter_flags |= htole32(IWM_MAC_FILTER_IN_BEACON);
|
||||
else
|
||||
cmd.filter_flags &= ~htole32(IWM_MAC_FILTER_IN_BEACON);
|
||||
|
||||
/* Fill the data specific for station mode */
|
||||
iwm_mac_ctxt_cmd_fill_sta(sc, in,
|
||||
&cmd.sta, action == IWM_FW_CTXT_ACTION_ADD);
|
||||
|
||||
return iwm_mac_ctxt_send_cmd(sc, &cmd);
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_mac_ctx_send(struct iwm_softc *sc, struct ieee80211vap *vap,
|
||||
uint32_t action)
|
||||
{
|
||||
return iwm_mac_ctxt_cmd_station(sc, vap, action);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_mac_ctxt_add(struct iwm_softc *sc, struct ieee80211vap *vap)
|
||||
{
|
||||
struct iwm_vap *iv = IWM_VAP(vap);
|
||||
int ret;
|
||||
|
||||
if (iv->is_uploaded != 0) {
|
||||
device_printf(sc->sc_dev, "%s: called; uploaded != 0\n",
|
||||
__func__);
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
ret = iwm_mac_ctx_send(sc, vap, IWM_FW_CTXT_ACTION_ADD);
|
||||
if (ret)
|
||||
return (ret);
|
||||
iv->is_uploaded = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_mac_ctxt_changed(struct iwm_softc *sc, struct ieee80211vap *vap)
|
||||
{
|
||||
struct iwm_vap *iv = IWM_VAP(vap);
|
||||
|
||||
if (iv->is_uploaded == 0) {
|
||||
device_printf(sc->sc_dev, "%s: called; uploaded = 0\n",
|
||||
__func__);
|
||||
return (EIO);
|
||||
}
|
||||
return iwm_mac_ctx_send(sc, vap, IWM_FW_CTXT_ACTION_MODIFY);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int
|
||||
iwm_mac_ctxt_remove(struct iwm_softc *sc, struct iwm_node *in)
|
||||
{
|
||||
struct iwm_mac_ctx_cmd cmd;
|
||||
int ret;
|
||||
|
||||
if (!in->in_uploaded) {
|
||||
device_printf(sc->sc_dev,
|
||||
"attempt to remove !uploaded node %p", in);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(IWM_DEFAULT_MACID,
|
||||
IWM_DEFAULT_COLOR));
|
||||
cmd.action = htole32(IWM_FW_CTXT_ACTION_REMOVE);
|
||||
|
||||
ret = iwm_send_cmd_pdu(sc,
|
||||
IWM_MAC_CONTEXT_CMD, IWM_CMD_SYNC, sizeof(cmd), &cmd);
|
||||
if (ret) {
|
||||
device_printf(sc->sc_dev,
|
||||
"Failed to remove MAC context: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
in->in_uploaded = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -1,115 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef __IF_IWM_MAC_CTXT_H__
|
||||
#define __IF_IWM_MAC_CTXT_H__
|
||||
|
||||
extern const uint8_t iwm_ac_to_tx_fifo[];
|
||||
|
||||
extern int iwm_mac_ctxt_add(struct iwm_softc *sc, struct ieee80211vap *vap);
|
||||
extern int iwm_mac_ctxt_changed(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__ */
|
|
@ -1,221 +0,0 @@
|
|||
/*-
|
||||
* 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) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 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) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* 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 <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <dev/iwm/if_iwm_notif_wait.h>
|
||||
|
||||
#define IWM_WAIT_LOCK_INIT(_n, _s) \
|
||||
mtx_init(&(_n)->lk_mtx, (_s), "iwm wait_notif", MTX_DEF);
|
||||
#define IWM_WAIT_LOCK(_n) mtx_lock(&(_n)->lk_mtx)
|
||||
#define IWM_WAIT_UNLOCK(_n) mtx_unlock(&(_n)->lk_mtx)
|
||||
#define IWM_WAIT_LOCK_DESTROY(_n) mtx_destroy(&(_n)->lk_mtx)
|
||||
|
||||
struct iwm_notif_wait_data {
|
||||
struct mtx lk_mtx;
|
||||
char lk_buf[32];
|
||||
STAILQ_HEAD(, iwm_notification_wait) list;
|
||||
struct iwm_softc *sc;
|
||||
};
|
||||
|
||||
struct iwm_notif_wait_data *
|
||||
iwm_notification_wait_init(struct iwm_softc *sc)
|
||||
{
|
||||
struct iwm_notif_wait_data *data;
|
||||
|
||||
data = malloc(sizeof(*data), M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (data != NULL) {
|
||||
snprintf(data->lk_buf, 32, "iwm wait_notif");
|
||||
IWM_WAIT_LOCK_INIT(data, data->lk_buf);
|
||||
STAILQ_INIT(&data->list);
|
||||
data->sc = sc;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
iwm_notification_wait_free(struct iwm_notif_wait_data *notif_data)
|
||||
{
|
||||
KASSERT(STAILQ_EMPTY(¬if_data->list), ("notif list isn't empty"));
|
||||
IWM_WAIT_LOCK_DESTROY(notif_data);
|
||||
free(notif_data, M_DEVBUF);
|
||||
}
|
||||
|
||||
/* XXX Get rid of separate cmd argument, like in iwlwifi's code */
|
||||
void
|
||||
iwm_notification_wait_notify(struct iwm_notif_wait_data *notif_data,
|
||||
uint16_t cmd, struct iwm_rx_packet *pkt)
|
||||
{
|
||||
struct iwm_notification_wait *wait_entry;
|
||||
|
||||
IWM_WAIT_LOCK(notif_data);
|
||||
STAILQ_FOREACH(wait_entry, ¬if_data->list, entry) {
|
||||
int found = FALSE;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* If it already finished (triggered) or has been
|
||||
* aborted then don't evaluate it again to avoid races,
|
||||
* Otherwise the function could be called again even
|
||||
* though it returned true before
|
||||
*/
|
||||
if (wait_entry->triggered || wait_entry->aborted)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < wait_entry->n_cmds; i++) {
|
||||
if (cmd == wait_entry->cmds[i]) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
|
||||
if (!wait_entry->fn ||
|
||||
wait_entry->fn(notif_data->sc, pkt, wait_entry->fn_data)) {
|
||||
wait_entry->triggered = 1;
|
||||
wakeup(wait_entry);
|
||||
}
|
||||
}
|
||||
IWM_WAIT_UNLOCK(notif_data);
|
||||
}
|
||||
|
||||
void
|
||||
iwm_abort_notification_waits(struct iwm_notif_wait_data *notif_data)
|
||||
{
|
||||
struct iwm_notification_wait *wait_entry;
|
||||
|
||||
IWM_WAIT_LOCK(notif_data);
|
||||
STAILQ_FOREACH(wait_entry, ¬if_data->list, entry) {
|
||||
wait_entry->aborted = 1;
|
||||
wakeup(wait_entry);
|
||||
}
|
||||
IWM_WAIT_UNLOCK(notif_data);
|
||||
}
|
||||
|
||||
void
|
||||
iwm_init_notification_wait(struct iwm_notif_wait_data *notif_data,
|
||||
struct iwm_notification_wait *wait_entry, const uint16_t *cmds, int n_cmds,
|
||||
int (*fn)(struct iwm_softc *sc, struct iwm_rx_packet *pkt, void *data),
|
||||
void *fn_data)
|
||||
{
|
||||
KASSERT(n_cmds <= IWM_MAX_NOTIF_CMDS,
|
||||
("n_cmds %d is too large", n_cmds));
|
||||
wait_entry->fn = fn;
|
||||
wait_entry->fn_data = fn_data;
|
||||
wait_entry->n_cmds = n_cmds;
|
||||
memcpy(wait_entry->cmds, cmds, n_cmds * sizeof(uint16_t));
|
||||
wait_entry->triggered = 0;
|
||||
wait_entry->aborted = 0;
|
||||
|
||||
IWM_WAIT_LOCK(notif_data);
|
||||
STAILQ_INSERT_TAIL(¬if_data->list, wait_entry, entry);
|
||||
IWM_WAIT_UNLOCK(notif_data);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_wait_notification(struct iwm_notif_wait_data *notif_data,
|
||||
struct iwm_notification_wait *wait_entry, int timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
IWM_WAIT_LOCK(notif_data);
|
||||
if (!wait_entry->triggered && !wait_entry->aborted) {
|
||||
ret = msleep(wait_entry, ¬if_data->lk_mtx, 0, "iwm_notif",
|
||||
timeout);
|
||||
}
|
||||
STAILQ_REMOVE(¬if_data->list, wait_entry, iwm_notification_wait,
|
||||
entry);
|
||||
IWM_WAIT_UNLOCK(notif_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
iwm_remove_notification(struct iwm_notif_wait_data *notif_data,
|
||||
struct iwm_notification_wait *wait_entry)
|
||||
{
|
||||
IWM_WAIT_LOCK(notif_data);
|
||||
STAILQ_REMOVE(¬if_data->list, wait_entry, iwm_notification_wait,
|
||||
entry);
|
||||
IWM_WAIT_UNLOCK(notif_data);
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
/*-
|
||||
* 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) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 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) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#ifndef __IF_IWN_NOTIF_WAIT_H__
|
||||
#define __IF_IWN_NOTIF_WAIT_H__
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
#define IWM_MAX_NOTIF_CMDS 5
|
||||
|
||||
struct iwm_rx_packet;
|
||||
struct iwm_softc;
|
||||
|
||||
/**
|
||||
* struct iwm_notification_wait - notification wait entry
|
||||
* @entry: link for global list
|
||||
* @fn: Function called with the notification. If the function
|
||||
* returns true, the wait is over, if it returns false then
|
||||
* the waiter stays blocked. If no function is given, any
|
||||
* of the listed commands will unblock the waiter.
|
||||
* @cmds: command IDs
|
||||
* @n_cmds: number of command IDs
|
||||
* @triggered: waiter should be woken up
|
||||
* @aborted: wait was aborted
|
||||
*
|
||||
* This structure is not used directly, to wait for a
|
||||
* notification declare it on the stack, and call
|
||||
* iwm_init_notification_wait() with appropriate
|
||||
* parameters. Then do whatever will cause the ucode
|
||||
* to notify the driver, and to wait for that then
|
||||
* call iwm_wait_notification().
|
||||
*
|
||||
* Each notification is one-shot. If at some point we
|
||||
* need to support multi-shot notifications (which
|
||||
* can't be allocated on the stack) we need to modify
|
||||
* the code for them.
|
||||
*/
|
||||
struct iwm_notification_wait {
|
||||
STAILQ_ENTRY(iwm_notification_wait) entry;
|
||||
|
||||
int (*fn)(struct iwm_softc *sc, struct iwm_rx_packet *pkt, void *data);
|
||||
void *fn_data;
|
||||
|
||||
uint16_t cmds[IWM_MAX_NOTIF_CMDS];
|
||||
uint8_t n_cmds;
|
||||
int triggered, aborted;
|
||||
};
|
||||
|
||||
/* caller functions */
|
||||
extern struct iwm_notif_wait_data *iwm_notification_wait_init(
|
||||
struct iwm_softc *sc);
|
||||
extern void iwm_notification_wait_free(struct iwm_notif_wait_data *notif_data);
|
||||
extern void iwm_notification_wait_notify(
|
||||
struct iwm_notif_wait_data *notif_data, uint16_t cmd,
|
||||
struct iwm_rx_packet *pkt);
|
||||
extern void iwm_abort_notification_waits(
|
||||
struct iwm_notif_wait_data *notif_data);
|
||||
|
||||
/* user functions */
|
||||
extern void iwm_init_notification_wait(struct iwm_notif_wait_data *notif_data,
|
||||
struct iwm_notification_wait *wait_entry,
|
||||
const uint16_t *cmds, int n_cmds,
|
||||
int (*fn)(struct iwm_softc *sc,
|
||||
struct iwm_rx_packet *pkt, void *data),
|
||||
void *fn_data);
|
||||
extern int iwm_wait_notification(struct iwm_notif_wait_data *notif_data,
|
||||
struct iwm_notification_wait *wait_entry, int timeout);
|
||||
extern void iwm_remove_notification(struct iwm_notif_wait_data *notif_data,
|
||||
struct iwm_notification_wait *wait_entry);
|
||||
|
||||
#endif /* __IF_IWN_NOTIF_WAIT_H__ */
|
|
@ -1,733 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_wlan.h"
|
||||
#include "opt_iwm.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/endian.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_regdomain.h>
|
||||
#include <net80211/ieee80211_ratectl.h>
|
||||
#include <net80211/ieee80211_radiotap.h>
|
||||
|
||||
#include <dev/iwm/if_iwmreg.h>
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_config.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_pcie_trans.h>
|
||||
|
||||
/*
|
||||
* This is a subset of what's in linux iwlwifi/pcie/trans.c.
|
||||
* The rest can be migrated out into here once they're no longer in
|
||||
* if_iwm.c.
|
||||
*/
|
||||
|
||||
/*
|
||||
* basic device access
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
iwm_read_prph(struct iwm_softc *sc, uint32_t addr)
|
||||
{
|
||||
IWM_WRITE(sc,
|
||||
IWM_HBUS_TARG_PRPH_RADDR, ((addr & 0x000fffff) | (3 << 24)));
|
||||
IWM_BARRIER_READ_WRITE(sc);
|
||||
return IWM_READ(sc, IWM_HBUS_TARG_PRPH_RDAT);
|
||||
}
|
||||
|
||||
void
|
||||
iwm_write_prph(struct iwm_softc *sc, uint32_t addr, uint32_t val)
|
||||
{
|
||||
IWM_WRITE(sc,
|
||||
IWM_HBUS_TARG_PRPH_WADDR, ((addr & 0x000fffff) | (3 << 24)));
|
||||
IWM_BARRIER_WRITE(sc);
|
||||
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
|
||||
/* iwlwifi: pcie/trans.c */
|
||||
int
|
||||
iwm_read_mem(struct iwm_softc *sc, uint32_t addr, void *buf, int dwords)
|
||||
{
|
||||
int offs, ret = 0;
|
||||
uint32_t *vals = buf;
|
||||
|
||||
if (iwm_nic_lock(sc)) {
|
||||
IWM_WRITE(sc, IWM_HBUS_TARG_MEM_RADDR, addr);
|
||||
for (offs = 0; offs < dwords; offs++)
|
||||
vals[offs] = IWM_READ(sc, IWM_HBUS_TARG_MEM_RDAT);
|
||||
iwm_nic_unlock(sc);
|
||||
} else {
|
||||
ret = EBUSY;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* iwlwifi: pcie/trans.c */
|
||||
int
|
||||
iwm_write_mem(struct iwm_softc *sc, uint32_t addr, const void *buf, int dwords)
|
||||
{
|
||||
int offs;
|
||||
const uint32_t *vals = buf;
|
||||
|
||||
if (iwm_nic_lock(sc)) {
|
||||
IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WADDR, addr);
|
||||
/* WADDR auto-increments */
|
||||
for (offs = 0; offs < dwords; offs++) {
|
||||
uint32_t val = vals ? vals[offs] : 0;
|
||||
IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WDAT, val);
|
||||
}
|
||||
iwm_nic_unlock(sc);
|
||||
} else {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TRANS,
|
||||
"%s: write_mem failed\n", __func__);
|
||||
return EBUSY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_write_mem32(struct iwm_softc *sc, uint32_t addr, uint32_t val)
|
||||
{
|
||||
return iwm_write_mem(sc, addr, &val, 1);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_poll_bit(struct iwm_softc *sc, int reg,
|
||||
uint32_t bits, uint32_t mask, int timo)
|
||||
{
|
||||
for (;;) {
|
||||
if ((IWM_READ(sc, reg) & mask) == (bits & mask)) {
|
||||
return 1;
|
||||
}
|
||||
if (timo < 10) {
|
||||
return 0;
|
||||
}
|
||||
timo -= 10;
|
||||
DELAY(10);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
iwm_nic_lock(struct iwm_softc *sc)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if (sc->cmd_hold_nic_awake)
|
||||
return 1;
|
||||
|
||||
IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
|
||||
if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000)
|
||||
DELAY(2);
|
||||
|
||||
if (iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
|
||||
| IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP, 15000)) {
|
||||
rv = 1;
|
||||
} else {
|
||||
/* jolt */
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET,
|
||||
"%s: resetting device via NMI\n", __func__);
|
||||
IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_FORCE_NMI);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
iwm_nic_unlock(struct iwm_softc *sc)
|
||||
{
|
||||
if (sc->cmd_hold_nic_awake)
|
||||
return;
|
||||
|
||||
IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
}
|
||||
|
||||
void
|
||||
iwm_set_bits_mask_prph(struct iwm_softc *sc,
|
||||
uint32_t reg, uint32_t bits, uint32_t mask)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
/* XXX: no error path? */
|
||||
if (iwm_nic_lock(sc)) {
|
||||
val = iwm_read_prph(sc, reg) & mask;
|
||||
val |= bits;
|
||||
iwm_write_prph(sc, reg, val);
|
||||
iwm_nic_unlock(sc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
iwm_set_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits)
|
||||
{
|
||||
iwm_set_bits_mask_prph(sc, reg, bits, ~0);
|
||||
}
|
||||
|
||||
void
|
||||
iwm_clear_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits)
|
||||
{
|
||||
iwm_set_bits_mask_prph(sc, reg, 0, ~bits);
|
||||
}
|
||||
|
||||
/*
|
||||
* High-level hardware frobbing routines
|
||||
*/
|
||||
|
||||
void
|
||||
iwm_enable_rfkill_int(struct iwm_softc *sc)
|
||||
{
|
||||
sc->sc_intmask = IWM_CSR_INT_BIT_RF_KILL;
|
||||
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
|
||||
iwm_check_rfkill(struct iwm_softc *sc)
|
||||
{
|
||||
uint32_t v;
|
||||
int rv;
|
||||
|
||||
/*
|
||||
* "documentation" is not really helpful here:
|
||||
* 27: HW_RF_KILL_SW
|
||||
* Indicates state of (platform's) hardware RF-Kill switch
|
||||
*
|
||||
* But apparently when it's off, it's on ...
|
||||
*/
|
||||
v = IWM_READ(sc, IWM_CSR_GP_CNTRL);
|
||||
rv = (v & IWM_CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) == 0;
|
||||
if (rv) {
|
||||
sc->sc_flags |= IWM_FLAG_RFKILL;
|
||||
} else {
|
||||
sc->sc_flags &= ~IWM_FLAG_RFKILL;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
#define IWM_HW_READY_TIMEOUT 50
|
||||
int
|
||||
iwm_set_hw_ready(struct iwm_softc *sc)
|
||||
{
|
||||
int ready;
|
||||
|
||||
IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
|
||||
IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
|
||||
|
||||
ready = iwm_poll_bit(sc, IWM_CSR_HW_IF_CONFIG_REG,
|
||||
IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
|
||||
IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
|
||||
IWM_HW_READY_TIMEOUT);
|
||||
if (ready) {
|
||||
IWM_SETBITS(sc, IWM_CSR_MBOX_SET_REG,
|
||||
IWM_CSR_MBOX_SET_REG_OS_ALIVE);
|
||||
}
|
||||
return ready;
|
||||
}
|
||||
#undef IWM_HW_READY_TIMEOUT
|
||||
|
||||
int
|
||||
iwm_prepare_card_hw(struct iwm_softc *sc)
|
||||
{
|
||||
int rv = 0;
|
||||
int t = 0;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET, "->%s\n", __func__);
|
||||
if (iwm_set_hw_ready(sc))
|
||||
goto out;
|
||||
|
||||
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 */
|
||||
IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
|
||||
IWM_CSR_HW_IF_CONFIG_REG_PREPARE);
|
||||
|
||||
do {
|
||||
if (iwm_set_hw_ready(sc))
|
||||
goto out;
|
||||
DELAY(200);
|
||||
t += 200;
|
||||
} while (t < 150000);
|
||||
|
||||
rv = ETIMEDOUT;
|
||||
|
||||
out:
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET, "<-%s\n", __func__);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
iwm_apm_config(struct iwm_softc *sc)
|
||||
{
|
||||
uint16_t lctl, cap;
|
||||
int pcie_ptr;
|
||||
|
||||
/*
|
||||
* HW bug W/A for instability in PCIe bus L0S->L1 transition.
|
||||
* Check if BIOS (or OS) enabled L1-ASPM on this device.
|
||||
* If so (likely), disable L0S, so device moves directly L0->L1;
|
||||
* costs negligible amount of power savings.
|
||||
* If not (unlikely), enable L0S, so there is at least some
|
||||
* power savings, even without L1.
|
||||
*/
|
||||
int error;
|
||||
|
||||
error = pci_find_cap(sc->sc_dev, PCIY_EXPRESS, &pcie_ptr);
|
||||
if (error != 0)
|
||||
return;
|
||||
lctl = pci_read_config(sc->sc_dev, pcie_ptr + PCIER_LINK_CTL,
|
||||
sizeof(lctl));
|
||||
if (lctl & PCIEM_LINK_CTL_ASPMC_L1) {
|
||||
IWM_SETBITS(sc, IWM_CSR_GIO_REG,
|
||||
IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
|
||||
} else {
|
||||
IWM_CLRBITS(sc, IWM_CSR_GIO_REG,
|
||||
IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
|
||||
}
|
||||
|
||||
cap = pci_read_config(sc->sc_dev, pcie_ptr + PCIER_DEVICE_CTL2,
|
||||
sizeof(cap));
|
||||
sc->sc_ltr_enabled = (cap & PCIEM_CTL2_LTR_ENABLE) ? 1 : 0;
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_PWRSAVE,
|
||||
"L1 %sabled - LTR %sabled\n",
|
||||
(lctl & PCIEM_LINK_CTL_ASPMC_L1) ? "En" : "Dis",
|
||||
sc->sc_ltr_enabled ? "En" : "Dis");
|
||||
}
|
||||
|
||||
/*
|
||||
* Start up NIC's basic functionality after it has been reset
|
||||
* (e.g. after platform boot, or shutdown via iwm_pcie_apm_stop())
|
||||
* NOTE: This does not load uCode nor start the embedded processor
|
||||
*/
|
||||
int
|
||||
iwm_apm_init(struct iwm_softc *sc)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET, "iwm apm start\n");
|
||||
|
||||
/* Disable L0S exit timer (platform NMI Work/Around) */
|
||||
if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) {
|
||||
IWM_SETBITS(sc, IWM_CSR_GIO_CHICKEN_BITS,
|
||||
IWM_CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable L0s without affecting L1;
|
||||
* don't wait for ICH L0s (ICH bug W/A)
|
||||
*/
|
||||
IWM_SETBITS(sc, IWM_CSR_GIO_CHICKEN_BITS,
|
||||
IWM_CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
|
||||
|
||||
/* Set FH wait threshold to maximum (HW error during stress W/A) */
|
||||
IWM_SETBITS(sc, IWM_CSR_DBG_HPET_MEM_REG, IWM_CSR_DBG_HPET_MEM_REG_VAL);
|
||||
|
||||
/*
|
||||
* Enable HAP INTA (interrupt from management bus) to
|
||||
* wake device's PCI Express link L1a -> L0s
|
||||
*/
|
||||
IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
|
||||
IWM_CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
|
||||
|
||||
iwm_apm_config(sc);
|
||||
|
||||
#if 0 /* not for 7k/8k */
|
||||
/* Configure analog phase-lock-loop before activating to D0A */
|
||||
if (trans->cfg->base_params->pll_cfg_val)
|
||||
IWM_SETBITS(trans, IWM_CSR_ANA_PLL_CFG,
|
||||
trans->cfg->base_params->pll_cfg_val);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set "initialization complete" bit to move adapter from
|
||||
* D0U* --> D0A* (powered-up active) state.
|
||||
*/
|
||||
IWM_SETBITS(sc, IWM_CSR_GP_CNTRL, IWM_CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
|
||||
|
||||
/*
|
||||
* Wait for clock stabilization; once stabilized, access to
|
||||
* device-internal resources is supported, e.g. iwm_write_prph()
|
||||
* and accesses to uCode SRAM.
|
||||
*/
|
||||
if (!iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000)) {
|
||||
device_printf(sc->sc_dev,
|
||||
"timeout waiting for clock stabilization\n");
|
||||
error = ETIMEDOUT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sc->cfg->host_interrupt_operation_mode) {
|
||||
/*
|
||||
* This is a bit of an abuse - This is needed for 7260 / 3160
|
||||
* only check host_interrupt_operation_mode even if this is
|
||||
* not related to host_interrupt_operation_mode.
|
||||
*
|
||||
* Enable the oscillator to count wake up time for L1 exit. This
|
||||
* consumes slightly more power (100uA) - but allows to be sure
|
||||
* that we wake up from L1 on time.
|
||||
*
|
||||
* This looks weird: read twice the same register, discard the
|
||||
* value, set a bit, and yet again, read that same register
|
||||
* just to discard the value. But that's the way the hardware
|
||||
* seems to like it.
|
||||
*/
|
||||
if (iwm_nic_lock(sc)) {
|
||||
iwm_read_prph(sc, IWM_OSC_CLK);
|
||||
iwm_read_prph(sc, IWM_OSC_CLK);
|
||||
iwm_nic_unlock(sc);
|
||||
}
|
||||
iwm_set_bits_prph(sc, IWM_OSC_CLK, IWM_OSC_CLK_FORCE_CONTROL);
|
||||
if (iwm_nic_lock(sc)) {
|
||||
iwm_read_prph(sc, IWM_OSC_CLK);
|
||||
iwm_read_prph(sc, IWM_OSC_CLK);
|
||||
iwm_nic_unlock(sc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable DMA clock and wait for it to stabilize.
|
||||
*
|
||||
* Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
|
||||
* do not disable clocks. This preserves any hardware bits already
|
||||
* set by default in "CLK_CTRL_REG" after reset.
|
||||
*/
|
||||
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_7000) {
|
||||
if (iwm_nic_lock(sc)) {
|
||||
iwm_write_prph(sc, IWM_APMG_CLK_EN_REG,
|
||||
IWM_APMG_CLK_VAL_DMA_CLK_RQT);
|
||||
iwm_nic_unlock(sc);
|
||||
}
|
||||
DELAY(20);
|
||||
|
||||
/* Disable L1-Active */
|
||||
iwm_set_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
|
||||
IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
|
||||
|
||||
/* Clear the interrupt in APMG if the NIC is in RFKILL */
|
||||
if (iwm_nic_lock(sc)) {
|
||||
iwm_write_prph(sc, IWM_APMG_RTC_INT_STT_REG,
|
||||
IWM_APMG_RTC_INT_STT_RFKILL);
|
||||
iwm_nic_unlock(sc);
|
||||
}
|
||||
}
|
||||
out:
|
||||
if (error)
|
||||
device_printf(sc->sc_dev, "apm init error %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* iwlwifi/pcie/trans.c */
|
||||
void
|
||||
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 */
|
||||
IWM_SETBITS(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_STOP_MASTER);
|
||||
|
||||
if (!iwm_poll_bit(sc, IWM_CSR_RESET,
|
||||
IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED,
|
||||
IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED, 100))
|
||||
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__);
|
||||
}
|
||||
|
||||
/* iwlwifi pcie/trans.c */
|
||||
int
|
||||
iwm_start_hw(struct iwm_softc *sc)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((error = iwm_prepare_card_hw(sc)) != 0)
|
||||
return error;
|
||||
|
||||
/* Reset the entire device */
|
||||
IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_SW_RESET);
|
||||
DELAY(5000);
|
||||
|
||||
if ((error = iwm_apm_init(sc)) != 0)
|
||||
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_check_rfkill(sc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* iwlwifi pcie/trans.c (always main power) */
|
||||
void
|
||||
iwm_set_pwr(struct iwm_softc *sc)
|
||||
{
|
||||
iwm_set_bits_mask_prph(sc, IWM_APMG_PS_CTRL_REG,
|
||||
IWM_APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, ~IWM_APMG_PS_CTRL_MSK_PWR_SRC);
|
||||
}
|
||||
|
||||
/* iwlwifi pcie/rx.c */
|
||||
int
|
||||
iwm_pcie_rx_stop(struct iwm_softc *sc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = 0;
|
||||
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);
|
||||
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,
|
||||
1000);
|
||||
}
|
||||
iwm_nic_unlock(sc);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
iwm_pcie_clear_cmd_in_flight(struct iwm_softc *sc)
|
||||
{
|
||||
if (!sc->cfg->apmg_wake_up_wa)
|
||||
return;
|
||||
|
||||
if (!sc->cmd_hold_nic_awake) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: cmd_hold_nic_awake not set\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
sc->cmd_hold_nic_awake = 0;
|
||||
IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_pcie_set_cmd_in_flight(struct iwm_softc *sc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* wake up the NIC to make sure that the firmware will see the host
|
||||
* command - we will let the NIC sleep once all the host commands
|
||||
* returned. This needs to be done only on NICs that have
|
||||
* apmg_wake_up_wa set.
|
||||
*/
|
||||
if (sc->cfg->apmg_wake_up_wa &&
|
||||
!sc->cmd_hold_nic_awake) {
|
||||
|
||||
IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
|
||||
ret = iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
|
||||
(IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
|
||||
15000);
|
||||
if (ret == 0) {
|
||||
IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: Failed to wake NIC for hcmd\n", __func__);
|
||||
return EIO;
|
||||
}
|
||||
sc->cmd_hold_nic_awake = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
/* $FreeBSD$ */
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef __IWM_PCIE_TRANS_H__
|
||||
#define __IWM_PCIE_TRANS_H__
|
||||
|
||||
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_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_write_mem(struct iwm_softc *sc, uint32_t addr, const void *buf,
|
||||
int dwords);
|
||||
extern int iwm_write_mem32(struct iwm_softc *sc, uint32_t addr, uint32_t val);
|
||||
extern int iwm_poll_bit(struct iwm_softc *sc, int reg,
|
||||
uint32_t bits, uint32_t mask, int timo);
|
||||
extern int iwm_nic_lock(struct iwm_softc *sc);
|
||||
extern void iwm_nic_unlock(struct iwm_softc *sc);
|
||||
extern void iwm_set_bits_mask_prph(struct iwm_softc *sc,
|
||||
uint32_t reg, uint32_t bits, uint32_t mask);
|
||||
extern void iwm_set_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits);
|
||||
extern void iwm_clear_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits);
|
||||
extern void iwm_enable_rfkill_int(struct iwm_softc *sc);
|
||||
extern int iwm_check_rfkill(struct iwm_softc *sc);
|
||||
extern int iwm_set_hw_ready(struct iwm_softc *sc);
|
||||
extern int iwm_prepare_card_hw(struct iwm_softc *sc);
|
||||
extern void iwm_apm_config(struct iwm_softc *sc);
|
||||
extern int iwm_apm_init(struct iwm_softc *sc);
|
||||
extern void iwm_apm_stop(struct iwm_softc *sc);
|
||||
extern int iwm_start_hw(struct iwm_softc *sc);
|
||||
extern void iwm_set_pwr(struct iwm_softc *sc);
|
||||
extern int iwm_pcie_rx_stop(struct iwm_softc *sc);
|
||||
|
||||
extern int iwm_pcie_set_cmd_in_flight(struct iwm_softc *sc);
|
||||
extern void iwm_pcie_clear_cmd_in_flight(struct iwm_softc *sc);
|
||||
|
||||
#endif
|
|
@ -1,320 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_wlan.h"
|
||||
#include "opt_iwm.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/endian.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_regdomain.h>
|
||||
#include <net80211/ieee80211_ratectl.h>
|
||||
#include <net80211/ieee80211_radiotap.h>
|
||||
|
||||
#include <dev/iwm/if_iwmreg.h>
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_util.h>
|
||||
#include <dev/iwm/if_iwm_phy_ctxt.h>
|
||||
|
||||
/*
|
||||
* BEGIN iwlwifi/mvm/phy-ctxt.c
|
||||
*/
|
||||
|
||||
/*
|
||||
* Construct the generic fields of the PHY context command
|
||||
*/
|
||||
static void
|
||||
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)
|
||||
{
|
||||
memset(cmd, 0, sizeof(struct iwm_phy_context_cmd));
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_CMD,
|
||||
"%s: id=%d, colour=%d, action=%d, apply_time=%d\n",
|
||||
__func__,
|
||||
ctxt->id,
|
||||
ctxt->color,
|
||||
action,
|
||||
apply_time);
|
||||
|
||||
cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(ctxt->id,
|
||||
ctxt->color));
|
||||
cmd->action = htole32(action);
|
||||
cmd->apply_time = htole32(apply_time);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the phy configuration to the PHY context command
|
||||
*/
|
||||
static void
|
||||
iwm_phy_ctxt_cmd_data(struct iwm_softc *sc,
|
||||
struct iwm_phy_context_cmd *cmd, struct ieee80211_channel *chan,
|
||||
uint8_t chains_static, uint8_t chains_dynamic)
|
||||
{
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
uint8_t active_cnt, idle_cnt;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_CMD,
|
||||
"%s: 2ghz=%d, channel=%d, chains static=0x%x, dynamic=0x%x, "
|
||||
"rx_ant=0x%x, tx_ant=0x%x\n",
|
||||
__func__,
|
||||
!! IEEE80211_IS_CHAN_2GHZ(chan),
|
||||
ieee80211_chan2ieee(ic, chan),
|
||||
chains_static,
|
||||
chains_dynamic,
|
||||
iwm_get_valid_rx_ant(sc),
|
||||
iwm_get_valid_tx_ant(sc));
|
||||
|
||||
|
||||
cmd->ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
|
||||
IWM_PHY_BAND_24 : IWM_PHY_BAND_5;
|
||||
|
||||
cmd->ci.channel = ieee80211_chan2ieee(ic, chan);
|
||||
cmd->ci.width = IWM_PHY_VHT_CHANNEL_MODE20;
|
||||
cmd->ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_BELOW;
|
||||
|
||||
/* Set rx the chains */
|
||||
idle_cnt = chains_static;
|
||||
active_cnt = chains_dynamic;
|
||||
|
||||
/* In scenarios where we only ever use a single-stream rates,
|
||||
* i.e. legacy 11b/g/a associations, single-stream APs or even
|
||||
* static SMPS, enable both chains to get diversity, improving
|
||||
* the case where we're far enough from the AP that attenuation
|
||||
* between the two antennas is sufficiently different to impact
|
||||
* performance.
|
||||
*/
|
||||
if (active_cnt == 1 && iwm_rx_diversity_allowed(sc)) {
|
||||
idle_cnt = 2;
|
||||
active_cnt = 2;
|
||||
}
|
||||
|
||||
cmd->rxchain_info = htole32(iwm_get_valid_rx_ant(sc) <<
|
||||
IWM_PHY_RX_CHAIN_VALID_POS);
|
||||
cmd->rxchain_info |= htole32(idle_cnt << IWM_PHY_RX_CHAIN_CNT_POS);
|
||||
cmd->rxchain_info |= htole32(active_cnt <<
|
||||
IWM_PHY_RX_CHAIN_MIMO_CNT_POS);
|
||||
|
||||
cmd->txchain_info = htole32(iwm_get_valid_tx_ant(sc));
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a command
|
||||
* only if something in the configuration changed: in case that this is the
|
||||
* first time that the phy configuration is applied or in case that the phy
|
||||
* configuration changed from the previous apply.
|
||||
*/
|
||||
static int
|
||||
iwm_phy_ctxt_apply(struct iwm_softc *sc,
|
||||
struct iwm_phy_ctxt *ctxt,
|
||||
uint8_t chains_static, uint8_t chains_dynamic,
|
||||
uint32_t action, uint32_t apply_time)
|
||||
{
|
||||
struct iwm_phy_context_cmd cmd;
|
||||
int ret;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_CMD,
|
||||
"%s: called; channel=%p\n",
|
||||
__func__,
|
||||
ctxt->channel);
|
||||
|
||||
/* Set the command header fields */
|
||||
iwm_phy_ctxt_cmd_hdr(sc, ctxt, &cmd, action, apply_time);
|
||||
|
||||
/* Set the command data */
|
||||
iwm_phy_ctxt_cmd_data(sc, &cmd, ctxt->channel,
|
||||
chains_static, chains_dynamic);
|
||||
|
||||
ret = iwm_send_cmd_pdu(sc, IWM_PHY_CONTEXT_CMD, IWM_CMD_SYNC,
|
||||
sizeof(struct iwm_phy_context_cmd), &cmd);
|
||||
if (ret) {
|
||||
device_printf(sc->sc_dev,
|
||||
"PHY ctxt cmd error. ret=%d\n", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a command to add a PHY context based on the current HW configuration.
|
||||
*/
|
||||
int
|
||||
iwm_phy_ctxt_add(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt,
|
||||
struct ieee80211_channel *chan,
|
||||
uint8_t chains_static, uint8_t chains_dynamic)
|
||||
{
|
||||
ctxt->channel = chan;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_CMD,
|
||||
"%s: called; channel=%d\n",
|
||||
__func__,
|
||||
ieee80211_chan2ieee(&sc->sc_ic, chan));
|
||||
|
||||
return iwm_phy_ctxt_apply(sc, ctxt,
|
||||
chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_ADD, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a command to modify the PHY context based on the current HW
|
||||
* configuration. Note that the function does not check that the configuration
|
||||
* changed.
|
||||
*/
|
||||
int
|
||||
iwm_phy_ctxt_changed(struct iwm_softc *sc,
|
||||
struct iwm_phy_ctxt *ctxt, struct ieee80211_channel *chan,
|
||||
uint8_t chains_static, uint8_t chains_dynamic)
|
||||
{
|
||||
ctxt->channel = chan;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_CMD,
|
||||
"%s: called; channel=%d\n",
|
||||
__func__,
|
||||
ieee80211_chan2ieee(&sc->sc_ic, chan));
|
||||
|
||||
return iwm_phy_ctxt_apply(sc, ctxt,
|
||||
chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_MODIFY, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* END iwlwifi/mvm/phy-ctxt.c
|
||||
*/
|
|
@ -1,117 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef __IF_IWM_PHY_CTXT_H__
|
||||
#define __IF_IWM_PHY_CTXT_H__
|
||||
|
||||
extern int iwm_phy_ctxt_add(struct iwm_softc *sc,
|
||||
struct iwm_phy_ctxt *ctxt,
|
||||
struct ieee80211_channel *chan,
|
||||
uint8_t chains_static, uint8_t chains_dynamic);
|
||||
extern int iwm_phy_ctxt_changed(struct iwm_softc *sc,
|
||||
struct iwm_phy_ctxt *ctxt, struct ieee80211_channel *chan,
|
||||
uint8_t chains_static, uint8_t chains_dynamic);
|
||||
|
||||
#endif /* __IF_IWM_PHY_CTXT_H__ */
|
|
@ -1,612 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_wlan.h"
|
||||
#include "opt_iwm.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/endian.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_regdomain.h>
|
||||
#include <net80211/ieee80211_ratectl.h>
|
||||
#include <net80211/ieee80211_radiotap.h>
|
||||
|
||||
#include "if_iwmreg.h"
|
||||
#include "if_iwmvar.h"
|
||||
#include "if_iwm_debug.h"
|
||||
#include "if_iwm_util.h"
|
||||
#include "if_iwm_phy_db.h"
|
||||
|
||||
#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */
|
||||
|
||||
struct iwm_phy_db_entry {
|
||||
uint16_t size;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwm_phy_db - stores phy configuration and calibration data.
|
||||
*
|
||||
* @cfg: phy configuration.
|
||||
* @calib_nch: non channel specific calibration data.
|
||||
* @calib_ch: channel specific calibration data.
|
||||
* @n_group_papd: number of entries in papd channel group.
|
||||
* @calib_ch_group_papd: calibration data related to papd channel group.
|
||||
* @n_group_txp: number of entries in tx power channel group.
|
||||
* @calib_ch_group_txp: calibration data related to tx power chanel group.
|
||||
*/
|
||||
struct iwm_phy_db {
|
||||
struct iwm_phy_db_entry cfg;
|
||||
struct iwm_phy_db_entry calib_nch;
|
||||
int n_group_papd;
|
||||
struct iwm_phy_db_entry *calib_ch_group_papd;
|
||||
int n_group_txp;
|
||||
struct iwm_phy_db_entry *calib_ch_group_txp;
|
||||
|
||||
struct iwm_softc *sc;
|
||||
};
|
||||
|
||||
enum iwm_phy_db_section_type {
|
||||
IWM_PHY_DB_CFG = 1,
|
||||
IWM_PHY_DB_CALIB_NCH,
|
||||
IWM_PHY_DB_UNUSED,
|
||||
IWM_PHY_DB_CALIB_CHG_PAPD,
|
||||
IWM_PHY_DB_CALIB_CHG_TXP,
|
||||
IWM_PHY_DB_MAX
|
||||
};
|
||||
|
||||
#define PHY_DB_CMD 0x6c
|
||||
|
||||
/*
|
||||
* phy db - configure operational ucode
|
||||
*/
|
||||
struct iwm_phy_db_cmd {
|
||||
uint16_t type;
|
||||
uint16_t length;
|
||||
uint8_t data[0];
|
||||
} __packed;
|
||||
|
||||
/* for parsing of tx power channel group data that comes from the firmware*/
|
||||
struct iwm_phy_db_chg_txp {
|
||||
uint32_t space;
|
||||
uint16_t max_channel_idx;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* phy db - Receive phy db chunk after calibrations
|
||||
*/
|
||||
struct iwm_calib_res_notif_phy_db {
|
||||
uint16_t type;
|
||||
uint16_t length;
|
||||
uint8_t data[0];
|
||||
} __packed;
|
||||
|
||||
struct iwm_phy_db *
|
||||
iwm_phy_db_init(struct iwm_softc *sc)
|
||||
{
|
||||
struct iwm_phy_db *phy_db = malloc(sizeof(struct iwm_phy_db),
|
||||
M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
|
||||
if (!phy_db)
|
||||
return phy_db;
|
||||
|
||||
phy_db->sc = sc;
|
||||
|
||||
phy_db->n_group_txp = -1;
|
||||
phy_db->n_group_papd = -1;
|
||||
|
||||
/* TODO: add default values of the phy db. */
|
||||
return phy_db;
|
||||
}
|
||||
|
||||
/*
|
||||
* get phy db section: returns a pointer to a phy db section specified by
|
||||
* type and channel group id.
|
||||
*/
|
||||
static struct iwm_phy_db_entry *
|
||||
iwm_phy_db_get_section(struct iwm_phy_db *phy_db,
|
||||
enum iwm_phy_db_section_type type,
|
||||
uint16_t chg_id)
|
||||
{
|
||||
if (!phy_db || type >= IWM_PHY_DB_MAX)
|
||||
return NULL;
|
||||
|
||||
switch (type) {
|
||||
case IWM_PHY_DB_CFG:
|
||||
return &phy_db->cfg;
|
||||
case IWM_PHY_DB_CALIB_NCH:
|
||||
return &phy_db->calib_nch;
|
||||
case IWM_PHY_DB_CALIB_CHG_PAPD:
|
||||
if (chg_id >= phy_db->n_group_papd)
|
||||
return NULL;
|
||||
return &phy_db->calib_ch_group_papd[chg_id];
|
||||
case IWM_PHY_DB_CALIB_CHG_TXP:
|
||||
if (chg_id >= phy_db->n_group_txp)
|
||||
return NULL;
|
||||
return &phy_db->calib_ch_group_txp[chg_id];
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
iwm_phy_db_free_section(struct iwm_phy_db *phy_db,
|
||||
enum iwm_phy_db_section_type type, uint16_t chg_id)
|
||||
{
|
||||
struct iwm_phy_db_entry *entry =
|
||||
iwm_phy_db_get_section(phy_db, type, chg_id);
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
if (entry->data != NULL)
|
||||
free(entry->data, M_DEVBUF);
|
||||
entry->data = NULL;
|
||||
entry->size = 0;
|
||||
}
|
||||
|
||||
void
|
||||
iwm_phy_db_free(struct iwm_phy_db *phy_db)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!phy_db)
|
||||
return;
|
||||
|
||||
iwm_phy_db_free_section(phy_db, IWM_PHY_DB_CFG, 0);
|
||||
iwm_phy_db_free_section(phy_db, IWM_PHY_DB_CALIB_NCH, 0);
|
||||
|
||||
for (i = 0; i < phy_db->n_group_papd; i++)
|
||||
iwm_phy_db_free_section(phy_db, IWM_PHY_DB_CALIB_CHG_PAPD, i);
|
||||
if (phy_db->calib_ch_group_papd != NULL)
|
||||
free(phy_db->calib_ch_group_papd, M_DEVBUF);
|
||||
|
||||
for (i = 0; i < phy_db->n_group_txp; i++)
|
||||
iwm_phy_db_free_section(phy_db, IWM_PHY_DB_CALIB_CHG_TXP, i);
|
||||
if (phy_db->calib_ch_group_txp != NULL)
|
||||
free(phy_db->calib_ch_group_txp, M_DEVBUF);
|
||||
|
||||
free(phy_db, M_DEVBUF);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_phy_db_set_section(struct iwm_phy_db *phy_db,
|
||||
struct iwm_rx_packet *pkt)
|
||||
{
|
||||
struct iwm_calib_res_notif_phy_db *phy_db_notif =
|
||||
(struct iwm_calib_res_notif_phy_db *)pkt->data;
|
||||
enum iwm_phy_db_section_type type = le16toh(phy_db_notif->type);
|
||||
uint16_t size = le16toh(phy_db_notif->length);
|
||||
struct iwm_phy_db_entry *entry;
|
||||
uint16_t chg_id = 0;
|
||||
|
||||
if (!phy_db)
|
||||
return EINVAL;
|
||||
|
||||
if (type == IWM_PHY_DB_CALIB_CHG_PAPD) {
|
||||
chg_id = le16toh(*(uint16_t *)phy_db_notif->data);
|
||||
if (phy_db && !phy_db->calib_ch_group_papd) {
|
||||
/*
|
||||
* Firmware sends the largest index first, so we can use
|
||||
* it to know how much we should allocate.
|
||||
*/
|
||||
phy_db->calib_ch_group_papd = malloc(
|
||||
(chg_id + 1) * sizeof(struct iwm_phy_db_entry),
|
||||
M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (!phy_db->calib_ch_group_papd)
|
||||
return ENOMEM;
|
||||
phy_db->n_group_papd = chg_id + 1;
|
||||
}
|
||||
} else if (type == IWM_PHY_DB_CALIB_CHG_TXP) {
|
||||
chg_id = le16toh(*(uint16_t *)phy_db_notif->data);
|
||||
if (phy_db && !phy_db->calib_ch_group_txp) {
|
||||
/*
|
||||
* Firmware sends the largest index first, so we can use
|
||||
* it to know how much we should allocate.
|
||||
*/
|
||||
phy_db->calib_ch_group_txp = malloc(
|
||||
(chg_id + 1) * sizeof(struct iwm_phy_db_entry),
|
||||
M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (!phy_db->calib_ch_group_txp)
|
||||
return ENOMEM;
|
||||
phy_db->n_group_txp = chg_id + 1;
|
||||
}
|
||||
}
|
||||
|
||||
entry = iwm_phy_db_get_section(phy_db, type, chg_id);
|
||||
if (!entry)
|
||||
return EINVAL;
|
||||
|
||||
if (entry->data != NULL)
|
||||
free(entry->data, M_DEVBUF);
|
||||
entry->data = malloc(size, M_DEVBUF, M_NOWAIT);
|
||||
if (!entry->data) {
|
||||
entry->size = 0;
|
||||
return ENOMEM;
|
||||
}
|
||||
memcpy(entry->data, phy_db_notif->data, size);
|
||||
|
||||
entry->size = size;
|
||||
|
||||
IWM_DPRINTF(phy_db->sc, IWM_DEBUG_RESET,
|
||||
"%s(%d): [PHYDB]SET: Type %d , Size: %d\n",
|
||||
__func__, __LINE__, type, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
is_valid_channel(uint16_t ch_id)
|
||||
{
|
||||
if (ch_id <= 14 ||
|
||||
(36 <= ch_id && ch_id <= 64 && ch_id % 4 == 0) ||
|
||||
(100 <= ch_id && ch_id <= 140 && ch_id % 4 == 0) ||
|
||||
(145 <= ch_id && ch_id <= 165 && ch_id % 4 == 1))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
ch_id_to_ch_index(uint16_t ch_id)
|
||||
{
|
||||
if (!is_valid_channel(ch_id))
|
||||
return 0xff;
|
||||
|
||||
if (ch_id <= 14)
|
||||
return ch_id - 1;
|
||||
if (ch_id <= 64)
|
||||
return (ch_id + 20) / 4;
|
||||
if (ch_id <= 140)
|
||||
return (ch_id - 12) / 4;
|
||||
return (ch_id - 13) / 4;
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
channel_id_to_papd(uint16_t ch_id)
|
||||
{
|
||||
if (!is_valid_channel(ch_id))
|
||||
return 0xff;
|
||||
|
||||
if (1 <= ch_id && ch_id <= 14)
|
||||
return 0;
|
||||
if (36 <= ch_id && ch_id <= 64)
|
||||
return 1;
|
||||
if (100 <= ch_id && ch_id <= 140)
|
||||
return 2;
|
||||
return 3;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
channel_id_to_txp(struct iwm_phy_db *phy_db, uint16_t ch_id)
|
||||
{
|
||||
struct iwm_phy_db_chg_txp *txp_chg;
|
||||
int i;
|
||||
uint8_t ch_index = ch_id_to_ch_index(ch_id);
|
||||
if (ch_index == 0xff)
|
||||
return 0xff;
|
||||
|
||||
for (i = 0; i < phy_db->n_group_txp; i++) {
|
||||
txp_chg = (void *)phy_db->calib_ch_group_txp[i].data;
|
||||
if (!txp_chg)
|
||||
return 0xff;
|
||||
/*
|
||||
* Looking for the first channel group that its max channel is
|
||||
* higher then wanted channel.
|
||||
*/
|
||||
if (le16toh(txp_chg->max_channel_idx) >= ch_index)
|
||||
return i;
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_phy_db_get_section_data(struct iwm_phy_db *phy_db,
|
||||
uint32_t type, uint8_t **data, uint16_t *size,
|
||||
uint16_t ch_id)
|
||||
{
|
||||
struct iwm_phy_db_entry *entry;
|
||||
uint16_t ch_group_id = 0;
|
||||
|
||||
if (!phy_db)
|
||||
return EINVAL;
|
||||
|
||||
/* find wanted channel group */
|
||||
if (type == IWM_PHY_DB_CALIB_CHG_PAPD)
|
||||
ch_group_id = channel_id_to_papd(ch_id);
|
||||
else if (type == IWM_PHY_DB_CALIB_CHG_TXP)
|
||||
ch_group_id = channel_id_to_txp(phy_db, ch_id);
|
||||
|
||||
entry = iwm_phy_db_get_section(phy_db, type, ch_group_id);
|
||||
if (!entry)
|
||||
return EINVAL;
|
||||
|
||||
*data = entry->data;
|
||||
*size = entry->size;
|
||||
|
||||
IWM_DPRINTF(phy_db->sc, IWM_DEBUG_RESET,
|
||||
"%s(%d): [PHYDB] GET: Type %d , Size: %d\n",
|
||||
__func__, __LINE__, type, *size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_send_phy_db_cmd(struct iwm_phy_db *phy_db, uint16_t type,
|
||||
uint16_t length, void *data)
|
||||
{
|
||||
struct iwm_phy_db_cmd phy_db_cmd;
|
||||
struct iwm_host_cmd cmd = {
|
||||
.id = PHY_DB_CMD,
|
||||
};
|
||||
|
||||
IWM_DPRINTF(phy_db->sc, IWM_DEBUG_RESET,
|
||||
"Sending PHY-DB hcmd of type %d, of length %d\n",
|
||||
type, length);
|
||||
|
||||
/* Set phy db cmd variables */
|
||||
phy_db_cmd.type = htole16(type);
|
||||
phy_db_cmd.length = htole16(length);
|
||||
|
||||
/* Set hcmd variables */
|
||||
cmd.data[0] = &phy_db_cmd;
|
||||
cmd.len[0] = sizeof(struct iwm_phy_db_cmd);
|
||||
cmd.data[1] = data;
|
||||
cmd.len[1] = length;
|
||||
#ifdef notyet
|
||||
cmd.dataflags[1] = IWM_HCMD_DFL_NOCOPY;
|
||||
#endif
|
||||
|
||||
return iwm_send_cmd(phy_db->sc, &cmd);
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_phy_db_send_all_channel_groups(struct iwm_phy_db *phy_db,
|
||||
enum iwm_phy_db_section_type type,
|
||||
uint8_t max_ch_groups)
|
||||
{
|
||||
uint16_t i;
|
||||
int err;
|
||||
struct iwm_phy_db_entry *entry;
|
||||
|
||||
/* Send all the channel specific groups to operational fw */
|
||||
for (i = 0; i < max_ch_groups; i++) {
|
||||
entry = iwm_phy_db_get_section(phy_db,
|
||||
type,
|
||||
i);
|
||||
if (!entry)
|
||||
return EINVAL;
|
||||
|
||||
if (!entry->size)
|
||||
continue;
|
||||
|
||||
/* Send the requested PHY DB section */
|
||||
err = iwm_send_phy_db_cmd(phy_db,
|
||||
type,
|
||||
entry->size,
|
||||
entry->data);
|
||||
if (err) {
|
||||
device_printf(phy_db->sc->sc_dev,
|
||||
"Can't SEND phy_db section %d (%d), err %d\n",
|
||||
type, i, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
IWM_DPRINTF(phy_db->sc, IWM_DEBUG_CMD,
|
||||
"Sent PHY_DB HCMD, type = %d num = %d\n", type, i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_send_phy_db_data(struct iwm_phy_db *phy_db)
|
||||
{
|
||||
uint8_t *data = NULL;
|
||||
uint16_t size = 0;
|
||||
int err;
|
||||
|
||||
IWM_DPRINTF(phy_db->sc, IWM_DEBUG_CMD | IWM_DEBUG_RESET,
|
||||
"%s: Sending phy db data and configuration to runtime image\n",
|
||||
__func__);
|
||||
|
||||
/* Send PHY DB CFG section */
|
||||
err = iwm_phy_db_get_section_data(phy_db, IWM_PHY_DB_CFG,
|
||||
&data, &size, 0);
|
||||
if (err) {
|
||||
device_printf(phy_db->sc->sc_dev,
|
||||
"%s: Cannot get Phy DB cfg section, %d\n",
|
||||
__func__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = iwm_send_phy_db_cmd(phy_db, IWM_PHY_DB_CFG, size, data);
|
||||
if (err) {
|
||||
device_printf(phy_db->sc->sc_dev,
|
||||
"%s: Cannot send HCMD of Phy DB cfg section, %d\n",
|
||||
__func__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = iwm_phy_db_get_section_data(phy_db, IWM_PHY_DB_CALIB_NCH,
|
||||
&data, &size, 0);
|
||||
if (err) {
|
||||
device_printf(phy_db->sc->sc_dev,
|
||||
"%s: Cannot get Phy DB non specific channel section, "
|
||||
"%d\n", __func__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = iwm_send_phy_db_cmd(phy_db, IWM_PHY_DB_CALIB_NCH, size, data);
|
||||
if (err) {
|
||||
device_printf(phy_db->sc->sc_dev,
|
||||
"%s: Cannot send HCMD of Phy DB non specific channel "
|
||||
"sect, %d\n", __func__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Send all the TXP channel specific data */
|
||||
err = iwm_phy_db_send_all_channel_groups(phy_db,
|
||||
IWM_PHY_DB_CALIB_CHG_PAPD, phy_db->n_group_papd);
|
||||
if (err) {
|
||||
device_printf(phy_db->sc->sc_dev,
|
||||
"%s: Cannot send channel specific PAPD groups, %d\n",
|
||||
__func__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Send all the TXP channel specific data */
|
||||
err = iwm_phy_db_send_all_channel_groups(phy_db,
|
||||
IWM_PHY_DB_CALIB_CHG_TXP, phy_db->n_group_txp);
|
||||
if (err) {
|
||||
device_printf(phy_db->sc->sc_dev,
|
||||
"%s: Cannot send channel specific TX power groups, "
|
||||
"%d\n", __func__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
IWM_DPRINTF(phy_db->sc, IWM_DEBUG_CMD | IWM_DEBUG_RESET,
|
||||
"%s: Finished sending phy db non channel data\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef __IF_IWM_PHY_DB_H__
|
||||
#define __IF_IWM_PHY_DB_H__
|
||||
|
||||
struct iwm_calib_res_notif_phy_db;
|
||||
|
||||
extern struct iwm_phy_db *iwm_phy_db_init(struct iwm_softc *sc);
|
||||
extern void iwm_phy_db_free(struct iwm_phy_db *phy_db);
|
||||
extern int iwm_phy_db_set_section(struct iwm_phy_db *phy_db,
|
||||
struct iwm_rx_packet *pkt);
|
||||
extern int iwm_send_phy_db_data(struct iwm_phy_db *phy_db);
|
||||
|
||||
#endif /* __IF_IWM_PHY_DB_H__ */
|
|
@ -1,489 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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 <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/endian.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_regdomain.h>
|
||||
#include <net80211/ieee80211_ratectl.h>
|
||||
#include <net80211/ieee80211_radiotap.h>
|
||||
|
||||
#include <dev/iwm/if_iwmreg.h>
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_constants.h>
|
||||
#include <dev/iwm/if_iwm_util.h>
|
||||
#include <dev/iwm/if_iwm_power.h>
|
||||
|
||||
static int iwm_power_scheme = IWM_POWER_SCHEME_BPS;
|
||||
|
||||
TUNABLE_INT("hw.iwm.power_scheme", &iwm_power_scheme);
|
||||
|
||||
/*
|
||||
* BEGIN mvm/power.c
|
||||
*/
|
||||
|
||||
#define IWM_POWER_KEEP_ALIVE_PERIOD_SEC 25
|
||||
|
||||
static int
|
||||
iwm_beacon_filter_send_cmd(struct iwm_softc *sc,
|
||||
struct iwm_beacon_filter_cmd *cmd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iwm_send_cmd_pdu(sc, IWM_REPLY_BEACON_FILTERING_CMD,
|
||||
0, sizeof(struct iwm_beacon_filter_cmd), cmd);
|
||||
|
||||
if (!ret) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"ba_enable_beacon_abort is: %d\n",
|
||||
le32toh(cmd->ba_enable_beacon_abort));
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"ba_escape_timer is: %d\n",
|
||||
le32toh(cmd->ba_escape_timer));
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"bf_debug_flag is: %d\n",
|
||||
le32toh(cmd->bf_debug_flag));
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"bf_enable_beacon_filter is: %d\n",
|
||||
le32toh(cmd->bf_enable_beacon_filter));
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"bf_energy_delta is: %d\n",
|
||||
le32toh(cmd->bf_energy_delta));
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"bf_escape_timer is: %d\n",
|
||||
le32toh(cmd->bf_escape_timer));
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"bf_roaming_energy_delta is: %d\n",
|
||||
le32toh(cmd->bf_roaming_energy_delta));
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"bf_roaming_state is: %d\n",
|
||||
le32toh(cmd->bf_roaming_state));
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"bf_temp_threshold is: %d\n",
|
||||
le32toh(cmd->bf_temp_threshold));
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"bf_temp_fast_filter is: %d\n",
|
||||
le32toh(cmd->bf_temp_fast_filter));
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"bf_temp_slow_filter is: %d\n",
|
||||
le32toh(cmd->bf_temp_slow_filter));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
iwm_beacon_filter_set_cqm_params(struct iwm_softc *sc,
|
||||
struct iwm_vap *ivp, struct iwm_beacon_filter_cmd *cmd)
|
||||
{
|
||||
cmd->ba_enable_beacon_abort = htole32(sc->sc_bf.ba_enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
iwm_power_log(struct iwm_softc *sc, struct iwm_mac_power_cmd *cmd)
|
||||
{
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"Sending power table command on mac id 0x%X for "
|
||||
"power level %d, flags = 0x%X\n",
|
||||
cmd->id_and_color, iwm_power_scheme, le16toh(cmd->flags));
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"Keep alive = %u sec\n", le16toh(cmd->keep_alive_seconds));
|
||||
|
||||
if (!(cmd->flags & htole16(IWM_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK))) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"Disable power management\n");
|
||||
return;
|
||||
}
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"Rx timeout = %u usec\n", le32toh(cmd->rx_data_timeout));
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"Tx timeout = %u usec\n", le32toh(cmd->tx_data_timeout));
|
||||
if (cmd->flags & htole16(IWM_POWER_FLAGS_SKIP_OVER_DTIM_MSK))
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"DTIM periods to skip = %u\n", cmd->skip_dtim_periods);
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
iwm_power_is_radar(struct iwm_softc *sc)
|
||||
{
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ieee80211_channel *chan;
|
||||
boolean_t radar_detect = FALSE;
|
||||
|
||||
chan = ic->ic_bsschan;
|
||||
if (chan == IEEE80211_CHAN_ANYC ||
|
||||
(chan->ic_flags & IEEE80211_CHAN_DFS) != 0) {
|
||||
radar_detect = TRUE;
|
||||
}
|
||||
|
||||
return radar_detect;
|
||||
}
|
||||
|
||||
static void
|
||||
iwm_power_config_skip_dtim(struct iwm_softc *sc,
|
||||
struct iwm_mac_power_cmd *cmd)
|
||||
{
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
|
||||
int dtimper = vap->iv_dtim_period ?: 1;
|
||||
int skip;
|
||||
|
||||
/* disable, in case we're supposed to override */
|
||||
cmd->skip_dtim_periods = 0;
|
||||
cmd->flags &= ~htole16(IWM_POWER_FLAGS_SKIP_OVER_DTIM_MSK);
|
||||
|
||||
if (iwm_power_is_radar(sc))
|
||||
return;
|
||||
|
||||
if (dtimper >= 10)
|
||||
return;
|
||||
|
||||
/* TODO: check that multicast wake lock is off */
|
||||
|
||||
if (iwm_power_scheme != IWM_POWER_SCHEME_LP)
|
||||
return;
|
||||
skip = 2;
|
||||
|
||||
/* the firmware really expects "look at every X DTIMs", so add 1 */
|
||||
cmd->skip_dtim_periods = 1 + skip;
|
||||
cmd->flags |= htole16(IWM_POWER_FLAGS_SKIP_OVER_DTIM_MSK);
|
||||
}
|
||||
|
||||
static void
|
||||
iwm_power_build_cmd(struct iwm_softc *sc, struct iwm_vap *ivp,
|
||||
struct iwm_mac_power_cmd *cmd)
|
||||
{
|
||||
struct ieee80211vap *vap = &ivp->iv_vap;
|
||||
struct ieee80211_node *ni = vap->iv_bss;
|
||||
int dtimper, dtimper_msec;
|
||||
int keep_alive;
|
||||
boolean_t bss_conf_ps = FALSE;
|
||||
|
||||
cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id,
|
||||
ivp->color));
|
||||
dtimper = vap->iv_dtim_period ?: 1;
|
||||
|
||||
/*
|
||||
* Regardless of power management state the driver must set
|
||||
* keep alive period. FW will use it for sending keep alive NDPs
|
||||
* immediately after association. Check that keep alive period
|
||||
* is at least 3 * DTIM
|
||||
*/
|
||||
dtimper_msec = dtimper * ni->ni_intval;
|
||||
keep_alive
|
||||
= imax(3 * dtimper_msec, 1000 * IWM_POWER_KEEP_ALIVE_PERIOD_SEC);
|
||||
keep_alive = roundup(keep_alive, 1000) / 1000;
|
||||
cmd->keep_alive_seconds = htole16(keep_alive);
|
||||
|
||||
if (sc->sc_ps_disabled)
|
||||
return;
|
||||
|
||||
cmd->flags |= htole16(IWM_POWER_FLAGS_POWER_SAVE_ENA_MSK);
|
||||
|
||||
if (IWM_NODE(ni)->in_assoc &&
|
||||
(vap->iv_flags & IEEE80211_F_PMGTON) != 0) {
|
||||
bss_conf_ps = TRUE;
|
||||
}
|
||||
if (!bss_conf_ps)
|
||||
return;
|
||||
|
||||
cmd->flags |= htole16(IWM_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
|
||||
|
||||
iwm_power_config_skip_dtim(sc, cmd);
|
||||
|
||||
cmd->rx_data_timeout =
|
||||
htole32(IWM_DEFAULT_PS_RX_DATA_TIMEOUT);
|
||||
cmd->tx_data_timeout =
|
||||
htole32(IWM_DEFAULT_PS_TX_DATA_TIMEOUT);
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_power_send_cmd(struct iwm_softc *sc, struct iwm_vap *ivp)
|
||||
{
|
||||
struct iwm_mac_power_cmd cmd = {};
|
||||
|
||||
iwm_power_build_cmd(sc, ivp, &cmd);
|
||||
iwm_power_log(sc, &cmd);
|
||||
|
||||
return iwm_send_cmd_pdu(sc, IWM_MAC_PM_POWER_TABLE, 0,
|
||||
sizeof(cmd), &cmd);
|
||||
}
|
||||
|
||||
static int
|
||||
_iwm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_vap *ivp,
|
||||
struct iwm_beacon_filter_cmd *cmd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
iwm_beacon_filter_set_cqm_params(sc, ivp, cmd);
|
||||
ret = iwm_beacon_filter_send_cmd(sc, cmd);
|
||||
|
||||
if (!ret)
|
||||
sc->sc_bf.bf_enabled = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_vap *ivp)
|
||||
{
|
||||
struct iwm_beacon_filter_cmd cmd = {
|
||||
IWM_BF_CMD_CONFIG_DEFAULTS,
|
||||
.bf_enable_beacon_filter = htole32(1),
|
||||
};
|
||||
|
||||
return _iwm_enable_beacon_filter(sc, ivp, &cmd);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_disable_beacon_filter(struct iwm_softc *sc)
|
||||
{
|
||||
struct iwm_beacon_filter_cmd cmd = {};
|
||||
int ret;
|
||||
|
||||
ret = iwm_beacon_filter_send_cmd(sc, &cmd);
|
||||
if (ret == 0)
|
||||
sc->sc_bf.bf_enabled = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_power_set_ps(struct iwm_softc *sc)
|
||||
{
|
||||
struct ieee80211vap *vap;
|
||||
boolean_t disable_ps;
|
||||
int ret;
|
||||
|
||||
/* disable PS if CAM */
|
||||
disable_ps = (iwm_power_scheme == IWM_POWER_SCHEME_CAM);
|
||||
/* ...or if any of the vifs require PS to be off */
|
||||
TAILQ_FOREACH(vap, &sc->sc_ic.ic_vaps, iv_next) {
|
||||
struct iwm_vap *ivp = IWM_VAP(vap);
|
||||
if (ivp->phy_ctxt != NULL && ivp->ps_disabled)
|
||||
disable_ps = TRUE;
|
||||
}
|
||||
|
||||
/* update device power state if it has changed */
|
||||
if (sc->sc_ps_disabled != disable_ps) {
|
||||
boolean_t old_ps_disabled = sc->sc_ps_disabled;
|
||||
|
||||
sc->sc_ps_disabled = disable_ps;
|
||||
ret = iwm_power_update_device(sc);
|
||||
if (ret) {
|
||||
sc->sc_ps_disabled = old_ps_disabled;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_power_set_ba(struct iwm_softc *sc, struct iwm_vap *ivp)
|
||||
{
|
||||
struct iwm_beacon_filter_cmd cmd = {
|
||||
IWM_BF_CMD_CONFIG_DEFAULTS,
|
||||
.bf_enable_beacon_filter = htole32(1),
|
||||
};
|
||||
struct ieee80211vap *vap = &ivp->iv_vap;
|
||||
struct ieee80211_node *ni = vap->iv_bss;
|
||||
boolean_t bss_conf_ps = FALSE;
|
||||
|
||||
if (!sc->sc_bf.bf_enabled)
|
||||
return 0;
|
||||
|
||||
if (ni != NULL && IWM_NODE(ni)->in_assoc &&
|
||||
(vap->iv_flags & IEEE80211_F_PMGTON) != 0) {
|
||||
bss_conf_ps = TRUE;
|
||||
}
|
||||
sc->sc_bf.ba_enabled = !sc->sc_ps_disabled && bss_conf_ps;
|
||||
|
||||
return _iwm_enable_beacon_filter(sc, ivp, &cmd);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_power_update_ps(struct iwm_softc *sc)
|
||||
{
|
||||
struct ieee80211vap *vap = TAILQ_FIRST(&sc->sc_ic.ic_vaps);
|
||||
int ret;
|
||||
|
||||
ret = iwm_power_set_ps(sc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (vap != NULL)
|
||||
return iwm_power_set_ba(sc, IWM_VAP(vap));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_power_update_mac(struct iwm_softc *sc)
|
||||
{
|
||||
struct ieee80211vap *vap = TAILQ_FIRST(&sc->sc_ic.ic_vaps);
|
||||
int ret;
|
||||
|
||||
ret = iwm_power_set_ps(sc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (vap != NULL) {
|
||||
ret = iwm_power_send_cmd(sc, IWM_VAP(vap));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (vap != NULL)
|
||||
return iwm_power_set_ba(sc, IWM_VAP(vap));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_power_update_device(struct iwm_softc *sc)
|
||||
{
|
||||
struct iwm_device_power_cmd cmd = {
|
||||
.flags = 0,
|
||||
};
|
||||
|
||||
if (iwm_power_scheme == IWM_POWER_SCHEME_CAM)
|
||||
sc->sc_ps_disabled = TRUE;
|
||||
|
||||
if (!sc->sc_ps_disabled)
|
||||
cmd.flags |= htole16(IWM_DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_PWRSAVE | IWM_DEBUG_CMD,
|
||||
"Sending device power command with flags = 0x%X\n", cmd.flags);
|
||||
|
||||
return iwm_send_cmd_pdu(sc,
|
||||
IWM_POWER_TABLE_CMD, 0, sizeof(cmd), &cmd);
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __IF_IWM_POWER_H__
|
||||
#define __IF_IWM_POWER_H__
|
||||
|
||||
extern int iwm_power_update_device(struct iwm_softc *sc);
|
||||
extern int iwm_power_update_mac(struct iwm_softc *sc);
|
||||
extern int iwm_power_update_ps(struct iwm_softc *sc);
|
||||
extern int iwm_enable_beacon_filter(struct iwm_softc *sc,
|
||||
struct iwm_vap *ivp);
|
||||
extern int iwm_disable_beacon_filter(struct iwm_softc *sc);
|
||||
|
||||
#endif /* __IF_IWM_POWER_H__ */
|
|
@ -1,919 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_wlan.h"
|
||||
#include "opt_iwm.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/endian.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_regdomain.h>
|
||||
#include <net80211/ieee80211_ratectl.h>
|
||||
#include <net80211/ieee80211_radiotap.h>
|
||||
|
||||
#include <dev/iwm/if_iwmreg.h>
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_notif_wait.h>
|
||||
#include <dev/iwm/if_iwm_util.h>
|
||||
#include <dev/iwm/if_iwm_scan.h>
|
||||
|
||||
/*
|
||||
* BEGIN mvm/scan.c
|
||||
*/
|
||||
|
||||
#define IWM_DENSE_EBS_SCAN_RATIO 5
|
||||
#define IWM_SPARSE_EBS_SCAN_RATIO 1
|
||||
|
||||
static uint16_t
|
||||
iwm_scan_rx_chain(struct iwm_softc *sc)
|
||||
{
|
||||
uint16_t rx_chain;
|
||||
uint8_t rx_ant;
|
||||
|
||||
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_FORCE_MIMO_SEL_POS;
|
||||
rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_SEL_POS;
|
||||
rx_chain |= 0x1 << IWM_PHY_RX_CHAIN_DRIVER_FORCE_POS;
|
||||
return htole16(rx_chain);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
iwm_scan_rxon_flags(struct ieee80211_channel *c)
|
||||
{
|
||||
if (IEEE80211_IS_CHAN_2GHZ(c))
|
||||
return htole32(IWM_PHY_BAND_24);
|
||||
else
|
||||
return htole32(IWM_PHY_BAND_5);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
iwm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck)
|
||||
{
|
||||
uint32_t tx_ant;
|
||||
int i, ind;
|
||||
|
||||
for (i = 0, ind = sc->sc_scan_last_antenna;
|
||||
i < IWM_RATE_MCS_ANT_NUM; i++) {
|
||||
ind = (ind + 1) % IWM_RATE_MCS_ANT_NUM;
|
||||
if (iwm_get_valid_tx_ant(sc) & (1 << ind)) {
|
||||
sc->sc_scan_last_antenna = ind;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tx_ant = (1 << sc->sc_scan_last_antenna) << IWM_RATE_MCS_ANT_POS;
|
||||
|
||||
if ((flags & IEEE80211_CHAN_2GHZ) && !no_cck)
|
||||
return htole32(IWM_RATE_1M_PLCP | IWM_RATE_MCS_CCK_MSK |
|
||||
tx_ant);
|
||||
else
|
||||
return htole32(IWM_RATE_6M_PLCP | tx_ant);
|
||||
}
|
||||
|
||||
static inline boolean_t
|
||||
iwm_rrm_scan_needed(struct iwm_softc *sc)
|
||||
{
|
||||
/* require rrm scan whenever the fw supports it */
|
||||
return iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT);
|
||||
}
|
||||
|
||||
#ifdef IWM_DEBUG
|
||||
static const char *
|
||||
iwm_ebs_status_str(enum iwm_scan_ebs_status status)
|
||||
{
|
||||
switch (status) {
|
||||
case IWM_SCAN_EBS_SUCCESS:
|
||||
return "successful";
|
||||
case IWM_SCAN_EBS_INACTIVE:
|
||||
return "inactive";
|
||||
case IWM_SCAN_EBS_FAILED:
|
||||
case IWM_SCAN_EBS_CHAN_NOT_FOUND:
|
||||
default:
|
||||
return "failed";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
iwm_offload_status_str(enum iwm_scan_offload_complete_status status)
|
||||
{
|
||||
return (status == IWM_SCAN_OFFLOAD_ABORTED) ? "aborted" : "completed";
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
iwm_rx_lmac_scan_complete_notif(struct iwm_softc *sc,
|
||||
struct iwm_rx_packet *pkt)
|
||||
{
|
||||
struct iwm_periodic_scan_complete *scan_notif = (void *)pkt->data;
|
||||
|
||||
/* If this happens, the firmware has mistakenly sent an LMAC
|
||||
* notification during UMAC scans -- warn and ignore it.
|
||||
*/
|
||||
if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: Mistakenly got LMAC notification during UMAC scan\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Regular scan %s, EBS status %s (FW)\n",
|
||||
iwm_offload_status_str(scan_notif->status),
|
||||
iwm_ebs_status_str(scan_notif->ebs_status));
|
||||
|
||||
sc->last_ebs_successful =
|
||||
scan_notif->ebs_status == IWM_SCAN_EBS_SUCCESS ||
|
||||
scan_notif->ebs_status == IWM_SCAN_EBS_INACTIVE;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
iwm_rx_umac_scan_complete_notif(struct iwm_softc *sc,
|
||||
struct iwm_rx_packet *pkt)
|
||||
{
|
||||
struct iwm_umac_scan_complete *notif = (void *)pkt->data;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
|
||||
"Scan completed, uid %u, status %s, EBS status %s\n",
|
||||
le32toh(notif->uid),
|
||||
iwm_offload_status_str(notif->status),
|
||||
iwm_ebs_status_str(notif->ebs_status));
|
||||
|
||||
if (notif->ebs_status != IWM_SCAN_EBS_SUCCESS &&
|
||||
notif->ebs_status != IWM_SCAN_EBS_INACTIVE)
|
||||
sc->last_ebs_successful = FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_scan_skip_channel(struct ieee80211_channel *c)
|
||||
{
|
||||
if (IEEE80211_IS_CHAN_2GHZ(c) && IEEE80211_IS_CHAN_B(c))
|
||||
return 0;
|
||||
else if (IEEE80211_IS_CHAN_5GHZ(c) && IEEE80211_IS_CHAN_A(c))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
iwm_lmac_scan_fill_channels(struct iwm_softc *sc,
|
||||
struct iwm_scan_channel_cfg_lmac *chan, int n_ssids)
|
||||
{
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ieee80211_scan_state *ss = ic->ic_scan;
|
||||
struct ieee80211_channel *c;
|
||||
uint8_t nchan;
|
||||
int j;
|
||||
|
||||
for (nchan = j = 0;
|
||||
j < ss->ss_last && nchan < sc->sc_fw.ucode_capa.n_scan_channels;
|
||||
j++) {
|
||||
c = ss->ss_chans[j];
|
||||
/*
|
||||
* Catch other channels, in case we have 900MHz channels or
|
||||
* something in the chanlist.
|
||||
*/
|
||||
if (!IEEE80211_IS_CHAN_2GHZ(c) && !IEEE80211_IS_CHAN_5GHZ(c)) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_EEPROM,
|
||||
"%s: skipping channel (freq=%d, ieee=%d, flags=0x%08x)\n",
|
||||
__func__, c->ic_freq, c->ic_ieee, c->ic_flags);
|
||||
continue;
|
||||
}
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_EEPROM,
|
||||
"Adding channel %d (%d Mhz) to the list\n",
|
||||
nchan, c->ic_freq);
|
||||
chan->channel_num = htole16(ieee80211_mhz2ieee(c->ic_freq, 0));
|
||||
chan->iter_count = htole16(1);
|
||||
chan->iter_interval = htole32(0);
|
||||
chan->flags = htole32(IWM_UNIFIED_SCAN_CHANNEL_PARTIAL);
|
||||
chan->flags |= htole32(IWM_SCAN_CHANNEL_NSSIDS(n_ssids));
|
||||
/* XXX IEEE80211_SCAN_NOBCAST flag is never set. */
|
||||
if (!IEEE80211_IS_CHAN_PASSIVE(c) &&
|
||||
(!(ss->ss_flags & IEEE80211_SCAN_NOBCAST) || n_ssids != 0))
|
||||
chan->flags |= htole32(IWM_SCAN_CHANNEL_TYPE_ACTIVE);
|
||||
chan++;
|
||||
nchan++;
|
||||
}
|
||||
|
||||
return nchan;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
iwm_umac_scan_fill_channels(struct iwm_softc *sc,
|
||||
struct iwm_scan_channel_cfg_umac *chan, int n_ssids)
|
||||
{
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ieee80211_scan_state *ss = ic->ic_scan;
|
||||
struct ieee80211_channel *c;
|
||||
uint8_t nchan;
|
||||
int j;
|
||||
|
||||
for (nchan = j = 0;
|
||||
j < ss->ss_last && nchan < sc->sc_fw.ucode_capa.n_scan_channels;
|
||||
j++) {
|
||||
c = ss->ss_chans[j];
|
||||
/*
|
||||
* Catch other channels, in case we have 900MHz channels or
|
||||
* something in the chanlist.
|
||||
*/
|
||||
if (!IEEE80211_IS_CHAN_2GHZ(c) && !IEEE80211_IS_CHAN_5GHZ(c)) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_EEPROM,
|
||||
"%s: skipping channel (freq=%d, ieee=%d, flags=0x%08x)\n",
|
||||
__func__, c->ic_freq, c->ic_ieee, c->ic_flags);
|
||||
continue;
|
||||
}
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_EEPROM,
|
||||
"Adding channel %d (%d Mhz) to the list\n",
|
||||
nchan, c->ic_freq);
|
||||
chan->channel_num = ieee80211_mhz2ieee(c->ic_freq, 0);
|
||||
chan->iter_count = 1;
|
||||
chan->iter_interval = htole16(0);
|
||||
chan->flags = htole32(IWM_SCAN_CHANNEL_UMAC_NSSIDS(n_ssids));
|
||||
chan++;
|
||||
nchan++;
|
||||
}
|
||||
|
||||
return nchan;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_fill_probe_req(struct iwm_softc *sc, struct iwm_scan_probe_req *preq)
|
||||
{
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
|
||||
struct ieee80211_frame *wh = (struct ieee80211_frame *)preq->buf;
|
||||
struct ieee80211_rateset *rs;
|
||||
size_t remain = sizeof(preq->buf);
|
||||
uint8_t *frm, *pos;
|
||||
|
||||
memset(preq, 0, sizeof(*preq));
|
||||
|
||||
/* Ensure enough space for header and SSID IE. */
|
||||
if (remain < sizeof(*wh) + 2)
|
||||
return ENOBUFS;
|
||||
|
||||
/*
|
||||
* Build a probe request frame. Most of the following code is a
|
||||
* copy & paste of what is done in net80211.
|
||||
*/
|
||||
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
|
||||
IEEE80211_FC0_SUBTYPE_PROBE_REQ;
|
||||
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
|
||||
IEEE80211_ADDR_COPY(wh->i_addr1, ieee80211broadcastaddr);
|
||||
IEEE80211_ADDR_COPY(wh->i_addr2, vap ? vap->iv_myaddr : ic->ic_macaddr);
|
||||
IEEE80211_ADDR_COPY(wh->i_addr3, ieee80211broadcastaddr);
|
||||
*(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */
|
||||
*(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */
|
||||
|
||||
frm = (uint8_t *)(wh + 1);
|
||||
frm = ieee80211_add_ssid(frm, NULL, 0);
|
||||
|
||||
/* Tell the firmware where the MAC header is. */
|
||||
preq->mac_header.offset = 0;
|
||||
preq->mac_header.len = htole16(frm - (uint8_t *)wh);
|
||||
remain -= frm - (uint8_t *)wh;
|
||||
|
||||
/* Fill in 2GHz IEs and tell firmware where they are. */
|
||||
rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
|
||||
if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
|
||||
if (remain < 4 + rs->rs_nrates)
|
||||
return ENOBUFS;
|
||||
} else if (remain < 2 + rs->rs_nrates) {
|
||||
return ENOBUFS;
|
||||
}
|
||||
preq->band_data[0].offset = htole16(frm - (uint8_t *)wh);
|
||||
pos = frm;
|
||||
frm = ieee80211_add_rates(frm, rs);
|
||||
if (rs->rs_nrates > IEEE80211_RATE_SIZE)
|
||||
frm = ieee80211_add_xrates(frm, rs);
|
||||
preq->band_data[0].len = htole16(frm - pos);
|
||||
remain -= frm - pos;
|
||||
|
||||
if (iwm_rrm_scan_needed(sc)) {
|
||||
if (remain < 3)
|
||||
return ENOBUFS;
|
||||
*frm++ = IEEE80211_ELEMID_DSPARMS;
|
||||
*frm++ = 1;
|
||||
*frm++ = 0;
|
||||
remain -= 3;
|
||||
}
|
||||
|
||||
if (sc->nvm_data->sku_cap_band_52GHz_enable) {
|
||||
/* Fill in 5GHz IEs. */
|
||||
rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
|
||||
if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
|
||||
if (remain < 4 + rs->rs_nrates)
|
||||
return ENOBUFS;
|
||||
} else if (remain < 2 + rs->rs_nrates) {
|
||||
return ENOBUFS;
|
||||
}
|
||||
preq->band_data[1].offset = htole16(frm - (uint8_t *)wh);
|
||||
pos = frm;
|
||||
frm = ieee80211_add_rates(frm, rs);
|
||||
if (rs->rs_nrates > IEEE80211_RATE_SIZE)
|
||||
frm = ieee80211_add_xrates(frm, rs);
|
||||
preq->band_data[1].len = htole16(frm - pos);
|
||||
remain -= frm - pos;
|
||||
}
|
||||
|
||||
/* Send 11n IEs on both 2GHz and 5GHz bands. */
|
||||
preq->common_data.offset = htole16(frm - (uint8_t *)wh);
|
||||
pos = frm;
|
||||
#if 0
|
||||
if (ic->ic_flags & IEEE80211_F_HTON) {
|
||||
if (remain < 28)
|
||||
return ENOBUFS;
|
||||
frm = ieee80211_add_htcaps(frm, ic);
|
||||
/* XXX add WME info? */
|
||||
}
|
||||
#endif
|
||||
preq->common_data.len = htole16(frm - pos);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_config_umac_scan(struct iwm_softc *sc)
|
||||
{
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
|
||||
|
||||
struct iwm_scan_config *scan_config;
|
||||
int ret, j, nchan;
|
||||
size_t cmd_size;
|
||||
struct ieee80211_channel *c;
|
||||
struct iwm_host_cmd hcmd = {
|
||||
.id = iwm_cmd_id(IWM_SCAN_CFG_CMD, IWM_ALWAYS_LONG_GROUP, 0),
|
||||
.flags = IWM_CMD_SYNC,
|
||||
};
|
||||
static const uint32_t rates = (IWM_SCAN_CONFIG_RATE_1M |
|
||||
IWM_SCAN_CONFIG_RATE_2M | IWM_SCAN_CONFIG_RATE_5M |
|
||||
IWM_SCAN_CONFIG_RATE_11M | IWM_SCAN_CONFIG_RATE_6M |
|
||||
IWM_SCAN_CONFIG_RATE_9M | IWM_SCAN_CONFIG_RATE_12M |
|
||||
IWM_SCAN_CONFIG_RATE_18M | IWM_SCAN_CONFIG_RATE_24M |
|
||||
IWM_SCAN_CONFIG_RATE_36M | IWM_SCAN_CONFIG_RATE_48M |
|
||||
IWM_SCAN_CONFIG_RATE_54M);
|
||||
|
||||
cmd_size = sizeof(*scan_config) + sc->sc_fw.ucode_capa.n_scan_channels;
|
||||
|
||||
scan_config = malloc(cmd_size, M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (scan_config == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
scan_config->tx_chains = htole32(iwm_get_valid_tx_ant(sc));
|
||||
scan_config->rx_chains = htole32(iwm_get_valid_rx_ant(sc));
|
||||
scan_config->legacy_rates = htole32(rates |
|
||||
IWM_SCAN_CONFIG_SUPPORTED_RATE(rates));
|
||||
|
||||
/* These timings correspond to iwlwifi's UNASSOC scan. */
|
||||
scan_config->dwell_active = 10;
|
||||
scan_config->dwell_passive = 110;
|
||||
scan_config->dwell_fragmented = 44;
|
||||
scan_config->dwell_extended = 90;
|
||||
scan_config->out_of_channel_time = htole32(0);
|
||||
scan_config->suspend_time = htole32(0);
|
||||
|
||||
IEEE80211_ADDR_COPY(scan_config->mac_addr,
|
||||
vap ? vap->iv_myaddr : ic->ic_macaddr);
|
||||
|
||||
scan_config->bcast_sta_id = sc->sc_aux_sta.sta_id;
|
||||
scan_config->channel_flags = IWM_CHANNEL_FLAG_EBS |
|
||||
IWM_CHANNEL_FLAG_ACCURATE_EBS | IWM_CHANNEL_FLAG_EBS_ADD |
|
||||
IWM_CHANNEL_FLAG_PRE_SCAN_PASSIVE2ACTIVE;
|
||||
|
||||
for (nchan = j = 0;
|
||||
j < ic->ic_nchans && nchan < sc->sc_fw.ucode_capa.n_scan_channels;
|
||||
j++) {
|
||||
c = &ic->ic_channels[j];
|
||||
/* For 2GHz, only populate 11b channels */
|
||||
/* For 5GHz, only populate 11a channels */
|
||||
/*
|
||||
* Catch other channels, in case we have 900MHz channels or
|
||||
* something in the chanlist.
|
||||
*/
|
||||
if (iwm_scan_skip_channel(c))
|
||||
continue;
|
||||
scan_config->channel_array[nchan++] =
|
||||
ieee80211_mhz2ieee(c->ic_freq, 0);
|
||||
}
|
||||
|
||||
scan_config->flags = htole32(IWM_SCAN_CONFIG_FLAG_ACTIVATE |
|
||||
IWM_SCAN_CONFIG_FLAG_ALLOW_CHUB_REQS |
|
||||
IWM_SCAN_CONFIG_FLAG_SET_TX_CHAINS |
|
||||
IWM_SCAN_CONFIG_FLAG_SET_RX_CHAINS |
|
||||
IWM_SCAN_CONFIG_FLAG_SET_AUX_STA_ID |
|
||||
IWM_SCAN_CONFIG_FLAG_SET_ALL_TIMES |
|
||||
IWM_SCAN_CONFIG_FLAG_SET_LEGACY_RATES |
|
||||
IWM_SCAN_CONFIG_FLAG_SET_MAC_ADDR |
|
||||
IWM_SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS|
|
||||
IWM_SCAN_CONFIG_N_CHANNELS(nchan) |
|
||||
IWM_SCAN_CONFIG_FLAG_CLEAR_FRAGMENTED);
|
||||
|
||||
hcmd.data[0] = scan_config;
|
||||
hcmd.len[0] = cmd_size;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Sending UMAC scan config\n");
|
||||
|
||||
ret = iwm_send_cmd(sc, &hcmd);
|
||||
if (!ret)
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
|
||||
"UMAC scan config was sent successfully\n");
|
||||
|
||||
free(scan_config, M_DEVBUF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
iwm_scan_use_ebs(struct iwm_softc *sc)
|
||||
{
|
||||
const struct iwm_ucode_capabilities *capa = &sc->sc_fw.ucode_capa;
|
||||
|
||||
/* We can only use EBS if:
|
||||
* 1. the feature is supported;
|
||||
* 2. the last EBS was successful;
|
||||
* 3. if only single scan, the single scan EBS API is supported;
|
||||
* 4. it's not a p2p find operation.
|
||||
*/
|
||||
return ((capa->flags & IWM_UCODE_TLV_FLAGS_EBS_SUPPORT) &&
|
||||
sc->last_ebs_successful);
|
||||
}
|
||||
|
||||
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
|
||||
iwm_umac_scan(struct iwm_softc *sc)
|
||||
{
|
||||
struct iwm_host_cmd hcmd = {
|
||||
.id = iwm_cmd_id(IWM_SCAN_REQ_UMAC, IWM_ALWAYS_LONG_GROUP, 0),
|
||||
.len = { 0, },
|
||||
.data = { NULL, },
|
||||
.flags = IWM_CMD_SYNC,
|
||||
};
|
||||
struct ieee80211_scan_state *ss = sc->sc_ic.ic_scan;
|
||||
struct iwm_scan_req_umac *req;
|
||||
struct iwm_scan_req_umac_tail *tail;
|
||||
size_t req_len;
|
||||
uint16_t general_flags;
|
||||
uint8_t channel_flags, i, nssid;
|
||||
int ret;
|
||||
|
||||
req_len = iwm_scan_size(sc);
|
||||
if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
|
||||
return ENOMEM;
|
||||
req = malloc(req_len, M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (req == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
hcmd.len[0] = (uint16_t)req_len;
|
||||
hcmd.data[0] = (void *)req;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Handling ieee80211 scan request\n");
|
||||
|
||||
nssid = MIN(ss->ss_nssid, IWM_PROBE_OPTION_MAX);
|
||||
|
||||
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);
|
||||
|
||||
/* These timings correspond to iwlwifi's UNASSOC scan. */
|
||||
if (iwm_fw_has_api(sc, IWM_UCODE_TLV_API_ADAPTIVE_DWELL)) {
|
||||
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);
|
||||
|
||||
tail = (void *)((char *)&req->v7.data +
|
||||
sizeof(struct iwm_scan_channel_cfg_umac) *
|
||||
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. */
|
||||
for (i = 0; i < nssid; i++) {
|
||||
tail->direct_scan[i].id = IEEE80211_ELEMID_SSID;
|
||||
tail->direct_scan[i].len = MIN(ss->ss_ssid[i].len,
|
||||
IEEE80211_NWID_LEN);
|
||||
memcpy(tail->direct_scan[i].ssid, ss->ss_ssid[i].ssid,
|
||||
tail->direct_scan[i].len);
|
||||
/* XXX debug */
|
||||
}
|
||||
|
||||
ret = iwm_fill_probe_req(sc, &tail->preq);
|
||||
if (ret) {
|
||||
free(req, M_DEVBUF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Specify the scan plan: We'll do one iteration. */
|
||||
tail->schedule[0].interval = 0;
|
||||
tail->schedule[0].iter_count = 1;
|
||||
|
||||
ret = iwm_send_cmd(sc, &hcmd);
|
||||
if (!ret)
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
|
||||
"Scan request was sent successfully\n");
|
||||
free(req, M_DEVBUF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_lmac_scan(struct iwm_softc *sc)
|
||||
{
|
||||
struct iwm_host_cmd hcmd = {
|
||||
.id = IWM_SCAN_OFFLOAD_REQUEST_CMD,
|
||||
.len = { 0, },
|
||||
.data = { NULL, },
|
||||
.flags = IWM_CMD_SYNC,
|
||||
};
|
||||
struct ieee80211_scan_state *ss = sc->sc_ic.ic_scan;
|
||||
struct iwm_scan_req_lmac *req;
|
||||
size_t req_len;
|
||||
uint8_t i, nssid;
|
||||
int ret;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
|
||||
"Handling ieee80211 scan request\n");
|
||||
|
||||
req_len = iwm_scan_size(sc);
|
||||
if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
|
||||
return ENOMEM;
|
||||
req = malloc(req_len, M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (req == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
hcmd.len[0] = (uint16_t)req_len;
|
||||
hcmd.data[0] = (void *)req;
|
||||
|
||||
/* These timings correspond to iwlwifi's UNASSOC scan. */
|
||||
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_prio = htole32(IWM_SCAN_PRIORITY_HIGH);
|
||||
req->rx_chain_select = iwm_scan_rx_chain(sc);
|
||||
req->iter_num = htole32(1);
|
||||
req->delay = 0;
|
||||
|
||||
req->scan_flags = htole32(IWM_LMAC_SCAN_FLAG_PASS_ALL |
|
||||
IWM_LMAC_SCAN_FLAG_ITER_COMPLETE |
|
||||
IWM_LMAC_SCAN_FLAG_EXTENDED_DWELL);
|
||||
if (iwm_rrm_scan_needed(sc))
|
||||
req->scan_flags |= htole32(IWM_LMAC_SCAN_FLAGS_RRM_ENABLED);
|
||||
|
||||
req->flags = iwm_scan_rxon_flags(sc->sc_ic.ic_scan->ss_chans[0]);
|
||||
|
||||
req->filter_flags =
|
||||
htole32(IWM_MAC_FILTER_ACCEPT_GRP | IWM_MAC_FILTER_IN_BEACON);
|
||||
|
||||
/* Tx flags 2 GHz. */
|
||||
req->tx_cmd[0].tx_flags = htole32(IWM_TX_CMD_FLG_SEQ_CTL |
|
||||
IWM_TX_CMD_FLG_BT_DIS);
|
||||
req->tx_cmd[0].rate_n_flags =
|
||||
iwm_scan_rate_n_flags(sc, IEEE80211_CHAN_2GHZ, 1/*XXX*/);
|
||||
req->tx_cmd[0].sta_id = sc->sc_aux_sta.sta_id;
|
||||
|
||||
/* Tx flags 5 GHz. */
|
||||
req->tx_cmd[1].tx_flags = htole32(IWM_TX_CMD_FLG_SEQ_CTL |
|
||||
IWM_TX_CMD_FLG_BT_DIS);
|
||||
req->tx_cmd[1].rate_n_flags =
|
||||
iwm_scan_rate_n_flags(sc, IEEE80211_CHAN_5GHZ, 1/*XXX*/);
|
||||
req->tx_cmd[1].sta_id = sc->sc_aux_sta.sta_id;
|
||||
|
||||
/* Check if we're doing an active directed scan. */
|
||||
nssid = MIN(ss->ss_nssid, IWM_PROBE_OPTION_MAX);
|
||||
for (i = 0; i < nssid; i++) {
|
||||
req->direct_scan[i].id = IEEE80211_ELEMID_SSID;
|
||||
req->direct_scan[i].len = MIN(ss->ss_ssid[i].len,
|
||||
IEEE80211_NWID_LEN);
|
||||
memcpy(req->direct_scan[i].ssid, ss->ss_ssid[i].ssid,
|
||||
req->direct_scan[i].len);
|
||||
/* XXX debug */
|
||||
}
|
||||
if (nssid != 0) {
|
||||
req->scan_flags |=
|
||||
htole32(IWM_LMAC_SCAN_FLAG_PRE_CONNECTION);
|
||||
} else
|
||||
req->scan_flags |= htole32(IWM_LMAC_SCAN_FLAG_PASSIVE);
|
||||
|
||||
req->n_channels = iwm_lmac_scan_fill_channels(sc,
|
||||
(struct iwm_scan_channel_cfg_lmac *)req->data, nssid);
|
||||
|
||||
ret = iwm_fill_probe_req(sc,
|
||||
(struct iwm_scan_probe_req *)(req->data +
|
||||
(sizeof(struct iwm_scan_channel_cfg_lmac) *
|
||||
sc->sc_fw.ucode_capa.n_scan_channels)));
|
||||
if (ret) {
|
||||
free(req, M_DEVBUF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Specify the scan plan: We'll do one iteration. */
|
||||
req->schedule[0].iterations = 1;
|
||||
req->schedule[0].full_scan_mul = 1;
|
||||
|
||||
if (iwm_scan_use_ebs(sc)) {
|
||||
req->channel_opt[0].flags =
|
||||
htole16(IWM_SCAN_CHANNEL_FLAG_EBS |
|
||||
IWM_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
|
||||
IWM_SCAN_CHANNEL_FLAG_CACHE_ADD);
|
||||
req->channel_opt[0].non_ebs_ratio =
|
||||
htole16(IWM_DENSE_EBS_SCAN_RATIO);
|
||||
req->channel_opt[1].flags =
|
||||
htole16(IWM_SCAN_CHANNEL_FLAG_EBS |
|
||||
IWM_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
|
||||
IWM_SCAN_CHANNEL_FLAG_CACHE_ADD);
|
||||
req->channel_opt[1].non_ebs_ratio =
|
||||
htole16(IWM_SPARSE_EBS_SCAN_RATIO);
|
||||
}
|
||||
|
||||
ret = iwm_send_cmd(sc, &hcmd);
|
||||
if (!ret) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
|
||||
"Scan request was sent successfully\n");
|
||||
}
|
||||
free(req, M_DEVBUF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_lmac_scan_abort(struct iwm_softc *sc)
|
||||
{
|
||||
int ret;
|
||||
struct iwm_host_cmd hcmd = {
|
||||
.id = IWM_SCAN_OFFLOAD_ABORT_CMD,
|
||||
.len = { 0, },
|
||||
.data = { NULL, },
|
||||
.flags = IWM_CMD_SYNC,
|
||||
};
|
||||
uint32_t status;
|
||||
|
||||
ret = iwm_send_cmd_status(sc, &hcmd, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (status != IWM_CAN_ABORT_STATUS) {
|
||||
/*
|
||||
* The scan abort will return 1 for success or
|
||||
* 2 for "failure". A failure condition can be
|
||||
* due to simply not being in an active scan which
|
||||
* can occur if we send the scan abort before the
|
||||
* microcode has notified us that a scan is completed.
|
||||
*/
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
|
||||
"SCAN OFFLOAD ABORT ret %d.\n", status);
|
||||
ret = ENOENT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_umac_scan_abort(struct iwm_softc *sc)
|
||||
{
|
||||
struct iwm_umac_scan_abort cmd = {};
|
||||
int uid, ret;
|
||||
|
||||
uid = 0;
|
||||
cmd.uid = htole32(uid);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Sending scan abort, uid %u\n", uid);
|
||||
|
||||
ret = iwm_send_cmd_pdu(sc,
|
||||
iwm_cmd_id(IWM_SCAN_ABORT_UMAC,
|
||||
IWM_ALWAYS_LONG_GROUP, 0),
|
||||
0, sizeof(cmd), &cmd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_scan_stop_wait(struct iwm_softc *sc)
|
||||
{
|
||||
struct iwm_notification_wait wait_scan_done;
|
||||
static const uint16_t scan_done_notif[] = { IWM_SCAN_COMPLETE_UMAC,
|
||||
IWM_SCAN_OFFLOAD_COMPLETE, };
|
||||
int ret;
|
||||
|
||||
iwm_init_notification_wait(sc->sc_notif_wait, &wait_scan_done,
|
||||
scan_done_notif, nitems(scan_done_notif),
|
||||
NULL, NULL);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Preparing to stop scan\n");
|
||||
|
||||
if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_UMAC_SCAN))
|
||||
ret = iwm_umac_scan_abort(sc);
|
||||
else
|
||||
ret = iwm_lmac_scan_abort(sc);
|
||||
|
||||
if (ret) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "couldn't stop scan\n");
|
||||
iwm_remove_notification(sc->sc_notif_wait, &wait_scan_done);
|
||||
return ret;
|
||||
}
|
||||
|
||||
IWM_UNLOCK(sc);
|
||||
ret = iwm_wait_notification(sc->sc_notif_wait, &wait_scan_done, hz);
|
||||
IWM_LOCK(sc);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef __IF_IWN_SCAN_H__
|
||||
#define __IF_IWN_SCAN_H__
|
||||
|
||||
extern int iwm_lmac_scan(struct iwm_softc *);
|
||||
extern int iwm_config_umac_scan(struct iwm_softc *);
|
||||
extern int iwm_umac_scan(struct iwm_softc *);
|
||||
extern int iwm_scan_stop_wait(struct iwm_softc *);
|
||||
extern void iwm_rx_lmac_scan_complete_notif(struct iwm_softc *,
|
||||
struct iwm_rx_packet *);
|
||||
extern void iwm_rx_umac_scan_complete_notif(struct iwm_softc *,
|
||||
struct iwm_rx_packet *);
|
||||
|
||||
#endif /* __IF_IWN_SCAN_H__ */
|
|
@ -1,330 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 4.7.3 (tag id d7f6728f57e3ecbb7ef34eb7d9f564d514775d75)
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_wlan.h"
|
||||
#include "opt_iwm.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/endian.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_regdomain.h>
|
||||
#include <net80211/ieee80211_ratectl.h>
|
||||
#include <net80211/ieee80211_radiotap.h>
|
||||
|
||||
#include <dev/iwm/if_iwmreg.h>
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_config.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_util.h>
|
||||
#include <dev/iwm/if_iwm_sf.h>
|
||||
|
||||
/*
|
||||
* Aging and idle timeouts for the different possible scenarios
|
||||
* in default configuration
|
||||
*/
|
||||
static const uint32_t
|
||||
sf_full_timeout_def[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = {
|
||||
{
|
||||
htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER_DEF),
|
||||
htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER_DEF)
|
||||
},
|
||||
{
|
||||
htole32(IWM_SF_AGG_UNICAST_AGING_TIMER_DEF),
|
||||
htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER_DEF)
|
||||
},
|
||||
{
|
||||
htole32(IWM_SF_MCAST_AGING_TIMER_DEF),
|
||||
htole32(IWM_SF_MCAST_IDLE_TIMER_DEF)
|
||||
},
|
||||
{
|
||||
htole32(IWM_SF_BA_AGING_TIMER_DEF),
|
||||
htole32(IWM_SF_BA_IDLE_TIMER_DEF)
|
||||
},
|
||||
{
|
||||
htole32(IWM_SF_TX_RE_AGING_TIMER_DEF),
|
||||
htole32(IWM_SF_TX_RE_IDLE_TIMER_DEF)
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Aging and idle timeouts for the different possible scenarios
|
||||
* in single BSS MAC configuration.
|
||||
*/
|
||||
static const uint32_t
|
||||
sf_full_timeout[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = {
|
||||
{
|
||||
htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER),
|
||||
htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER)
|
||||
},
|
||||
{
|
||||
htole32(IWM_SF_AGG_UNICAST_AGING_TIMER),
|
||||
htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER)
|
||||
},
|
||||
{
|
||||
htole32(IWM_SF_MCAST_AGING_TIMER),
|
||||
htole32(IWM_SF_MCAST_IDLE_TIMER)
|
||||
},
|
||||
{
|
||||
htole32(IWM_SF_BA_AGING_TIMER),
|
||||
htole32(IWM_SF_BA_IDLE_TIMER)
|
||||
},
|
||||
{
|
||||
htole32(IWM_SF_TX_RE_AGING_TIMER),
|
||||
htole32(IWM_SF_TX_RE_IDLE_TIMER)
|
||||
},
|
||||
};
|
||||
|
||||
static void
|
||||
iwm_fill_sf_command(struct iwm_softc *sc, struct iwm_sf_cfg_cmd *sf_cmd,
|
||||
struct ieee80211_node *ni)
|
||||
{
|
||||
int i, j, watermark;
|
||||
|
||||
sf_cmd->watermark[IWM_SF_LONG_DELAY_ON] = htole32(IWM_SF_W_MARK_SCAN);
|
||||
|
||||
/*
|
||||
* If we are in association flow - check antenna configuration
|
||||
* capabilities of the AP station, and choose the watermark accordingly.
|
||||
*/
|
||||
if (ni) {
|
||||
if (ni->ni_flags & IEEE80211_NODE_HT) {
|
||||
watermark = IWM_SF_W_MARK_SISO;
|
||||
} else {
|
||||
watermark = IWM_SF_W_MARK_LEGACY;
|
||||
}
|
||||
/* default watermark value for unassociated mode. */
|
||||
} else {
|
||||
watermark = IWM_SF_W_MARK_MIMO2;
|
||||
}
|
||||
sf_cmd->watermark[IWM_SF_FULL_ON] = htole32(watermark);
|
||||
|
||||
for (i = 0; i < IWM_SF_NUM_SCENARIO; i++) {
|
||||
for (j = 0; j < IWM_SF_NUM_TIMEOUT_TYPES; j++) {
|
||||
sf_cmd->long_delay_timeouts[i][j] =
|
||||
htole32(IWM_SF_LONG_DELAY_AGING_TIMER);
|
||||
}
|
||||
}
|
||||
|
||||
if (ni) {
|
||||
_Static_assert(sizeof(sf_full_timeout) == sizeof(uint32_t) *
|
||||
IWM_SF_NUM_SCENARIO * IWM_SF_NUM_TIMEOUT_TYPES,
|
||||
"sf_full_timeout has wrong size");
|
||||
|
||||
memcpy(sf_cmd->full_on_timeouts, sf_full_timeout,
|
||||
sizeof(sf_full_timeout));
|
||||
} else {
|
||||
_Static_assert(sizeof(sf_full_timeout_def) == sizeof(uint32_t) *
|
||||
IWM_SF_NUM_SCENARIO * IWM_SF_NUM_TIMEOUT_TYPES,
|
||||
"sf_full_timeout_def has wrong size");
|
||||
|
||||
memcpy(sf_cmd->full_on_timeouts, sf_full_timeout_def,
|
||||
sizeof(sf_full_timeout_def));
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_sf_config(struct iwm_softc *sc, struct ieee80211_node *ni,
|
||||
enum iwm_sf_state new_state)
|
||||
{
|
||||
struct iwm_sf_cfg_cmd sf_cmd = {
|
||||
.state = htole32(new_state),
|
||||
};
|
||||
int ret = 0;
|
||||
|
||||
#ifdef notyet /* only relevant for sdio variants */
|
||||
if (sc->cfg->disable_dummy_notification)
|
||||
sf_cmd.state |= htole32(IWM_SF_CFG_DUMMY_NOTIF_OFF);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If an associated AP sta changed its antenna configuration, the state
|
||||
* will remain FULL_ON but SF parameters need to be reconsidered.
|
||||
*/
|
||||
if (new_state != IWM_SF_FULL_ON && sc->sf_state == new_state)
|
||||
return 0;
|
||||
|
||||
switch (new_state) {
|
||||
case IWM_SF_UNINIT:
|
||||
iwm_fill_sf_command(sc, &sf_cmd, NULL);
|
||||
break;
|
||||
case IWM_SF_FULL_ON:
|
||||
iwm_fill_sf_command(sc, &sf_cmd, ni);
|
||||
break;
|
||||
case IWM_SF_INIT_OFF:
|
||||
iwm_fill_sf_command(sc, &sf_cmd, NULL);
|
||||
break;
|
||||
default:
|
||||
device_printf(sc->sc_dev,
|
||||
"Invalid state: %d. not sending Smart Fifo cmd\n",
|
||||
new_state);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
ret = iwm_send_cmd_pdu(sc, IWM_REPLY_SF_CFG_CMD, IWM_CMD_ASYNC,
|
||||
sizeof(sf_cmd), &sf_cmd);
|
||||
if (!ret)
|
||||
sc->sf_state = new_state;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update Smart fifo:
|
||||
* Count bound interfaces that are not to be removed, ignoring p2p devices,
|
||||
* and set new state accordingly.
|
||||
*/
|
||||
int
|
||||
iwm_sf_update(struct iwm_softc *sc, struct ieee80211vap *changed_vif,
|
||||
boolean_t remove_vif)
|
||||
{
|
||||
enum iwm_sf_state new_state;
|
||||
struct ieee80211_node *ni = NULL;
|
||||
int num_active_macs = 0;
|
||||
|
||||
/* If changed_vif exists and is not to be removed, add to the count */
|
||||
if (changed_vif && !remove_vif)
|
||||
num_active_macs++;
|
||||
|
||||
switch (num_active_macs) {
|
||||
case 0:
|
||||
/* If there are no active macs - change state to SF_INIT_OFF */
|
||||
new_state = IWM_SF_INIT_OFF;
|
||||
break;
|
||||
case 1:
|
||||
if (!changed_vif)
|
||||
return EINVAL;
|
||||
ni = changed_vif->iv_bss;
|
||||
if (ni != NULL && IWM_NODE(ni)->in_assoc &&
|
||||
changed_vif->iv_dtim_period) {
|
||||
new_state = IWM_SF_FULL_ON;
|
||||
} else {
|
||||
new_state = IWM_SF_INIT_OFF;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* If there are multiple active macs - change to SF_UNINIT */
|
||||
new_state = IWM_SF_UNINIT;
|
||||
}
|
||||
return iwm_sf_config(sc, ni, new_state);
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 4.7.3 (tag id d7f6728f57e3ecbb7ef34eb7d9f564d514775d75)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef __IF_IWM_SF_H__
|
||||
#define __IF_IWM_SF_H__
|
||||
|
||||
extern int iwm_sf_update(struct iwm_softc *sc,
|
||||
struct ieee80211vap *changed_vif,
|
||||
boolean_t remove_vif);
|
||||
|
||||
#endif /* __IF_IWM_SF_H__ */
|
|
@ -1,381 +0,0 @@
|
|||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 4.7.3 (tag id d7f6728f57e3ecbb7ef34eb7d9f564d514775d75)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2015 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 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) 2012 - 2015 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_wlan.h"
|
||||
#include "opt_iwm.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/endian.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_regdomain.h>
|
||||
#include <net80211/ieee80211_ratectl.h>
|
||||
#include <net80211/ieee80211_radiotap.h>
|
||||
|
||||
#include <dev/iwm/if_iwmreg.h>
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_config.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_constants.h>
|
||||
#include <dev/iwm/if_iwm_util.h>
|
||||
#include <dev/iwm/if_iwm_mac_ctxt.h>
|
||||
#include <dev/iwm/if_iwm_sta.h>
|
||||
|
||||
/*
|
||||
* New version of ADD_STA_sta command added new fields at the end of the
|
||||
* structure, so sending the size of the relevant API's structure is enough to
|
||||
* support both API versions.
|
||||
*/
|
||||
static inline int
|
||||
iwm_add_sta_cmd_size(struct iwm_softc *sc)
|
||||
{
|
||||
return sc->cfg->mqrx_supported ? sizeof(struct iwm_add_sta_cmd) :
|
||||
sizeof(struct iwm_add_sta_cmd_v7);
|
||||
}
|
||||
|
||||
/* send station add/update command to firmware */
|
||||
int
|
||||
iwm_sta_send_to_fw(struct iwm_softc *sc, struct iwm_node *in,
|
||||
boolean_t update)
|
||||
{
|
||||
struct iwm_vap *ivp = IWM_VAP(in->in_ni.ni_vap);
|
||||
struct iwm_add_sta_cmd add_sta_cmd = {
|
||||
.sta_id = IWM_STATION_ID,
|
||||
.mac_id_n_color =
|
||||
htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id, ivp->color)),
|
||||
.add_modify = update ? 1 : 0,
|
||||
.station_flags_msk = htole32(IWM_STA_FLG_FAT_EN_MSK |
|
||||
IWM_STA_FLG_MIMO_EN_MSK),
|
||||
.tid_disable_tx = htole16(0xffff),
|
||||
};
|
||||
int ret;
|
||||
uint32_t status;
|
||||
uint32_t agg_size = 0, mpdu_dens = 0;
|
||||
|
||||
if (!update) {
|
||||
int ac;
|
||||
for (ac = 0; ac < WME_NUM_AC; ac++) {
|
||||
add_sta_cmd.tfd_queue_msk |=
|
||||
htole32(1 << iwm_ac_to_tx_fifo[ac]);
|
||||
}
|
||||
IEEE80211_ADDR_COPY(&add_sta_cmd.addr, in->in_ni.ni_bssid);
|
||||
}
|
||||
|
||||
add_sta_cmd.station_flags |=
|
||||
htole32(agg_size << IWM_STA_FLG_MAX_AGG_SIZE_SHIFT);
|
||||
add_sta_cmd.station_flags |=
|
||||
htole32(mpdu_dens << IWM_STA_FLG_AGG_MPDU_DENS_SHIFT);
|
||||
|
||||
status = IWM_ADD_STA_SUCCESS;
|
||||
ret = iwm_send_cmd_pdu_status(sc, IWM_ADD_STA,
|
||||
iwm_add_sta_cmd_size(sc),
|
||||
&add_sta_cmd, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (status & IWM_ADD_STA_STATUS_MASK) {
|
||||
case IWM_ADD_STA_SUCCESS:
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_NODE, "IWM_ADD_STA PASSED\n");
|
||||
break;
|
||||
default:
|
||||
ret = EIO;
|
||||
device_printf(sc->sc_dev, "IWM_ADD_STA failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_add_sta(struct iwm_softc *sc, struct iwm_node *in)
|
||||
{
|
||||
return iwm_sta_send_to_fw(sc, in, FALSE);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_update_sta(struct iwm_softc *sc, struct iwm_node *in)
|
||||
{
|
||||
return iwm_sta_send_to_fw(sc, in, TRUE);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_drain_sta(struct iwm_softc *sc, struct iwm_vap *ivp, boolean_t drain)
|
||||
{
|
||||
struct iwm_add_sta_cmd cmd = {};
|
||||
int ret;
|
||||
uint32_t status;
|
||||
|
||||
cmd.mac_id_n_color =
|
||||
htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id, ivp->color));
|
||||
cmd.sta_id = IWM_STATION_ID;
|
||||
cmd.add_modify = IWM_STA_MODE_MODIFY;
|
||||
cmd.station_flags = drain ? htole32(IWM_STA_FLG_DRAIN_FLOW) : 0;
|
||||
cmd.station_flags_msk = htole32(IWM_STA_FLG_DRAIN_FLOW);
|
||||
|
||||
status = IWM_ADD_STA_SUCCESS;
|
||||
ret = iwm_send_cmd_pdu_status(sc, IWM_ADD_STA,
|
||||
iwm_add_sta_cmd_size(sc),
|
||||
&cmd, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (status & IWM_ADD_STA_STATUS_MASK) {
|
||||
case IWM_ADD_STA_SUCCESS:
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_NODE,
|
||||
"Frames for staid %d will drained in fw\n", IWM_STATION_ID);
|
||||
break;
|
||||
default:
|
||||
ret = EIO;
|
||||
device_printf(sc->sc_dev,
|
||||
"Couldn't drain frames for staid %d\n", IWM_STATION_ID);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a station from the FW table. Before sending the command to remove
|
||||
* the station validate that the station is indeed known to the driver (sanity
|
||||
* only).
|
||||
*/
|
||||
static int
|
||||
iwm_rm_sta_common(struct iwm_softc *sc)
|
||||
{
|
||||
struct iwm_rm_sta_cmd rm_sta_cmd = {
|
||||
.sta_id = IWM_STATION_ID,
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = iwm_send_cmd_pdu(sc, IWM_REMOVE_STA, 0,
|
||||
sizeof(rm_sta_cmd), &rm_sta_cmd);
|
||||
if (ret) {
|
||||
device_printf(sc->sc_dev,
|
||||
"Failed to remove station. Id=%d\n", IWM_STATION_ID);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_rm_sta(struct iwm_softc *sc, struct ieee80211vap *vap,
|
||||
boolean_t is_assoc)
|
||||
{
|
||||
uint32_t tfd_queue_msk = 0;
|
||||
int ret;
|
||||
int ac;
|
||||
|
||||
ret = iwm_drain_sta(sc, IWM_VAP(vap), TRUE);
|
||||
if (ret)
|
||||
return ret;
|
||||
for (ac = 0; ac < WME_NUM_AC; ac++) {
|
||||
tfd_queue_msk |= htole32(1 << iwm_ac_to_tx_fifo[ac]);
|
||||
}
|
||||
ret = iwm_flush_tx_path(sc, tfd_queue_msk, IWM_CMD_SYNC);
|
||||
if (ret)
|
||||
return ret;
|
||||
#ifdef notyet /* function not yet implemented */
|
||||
ret = iwl_trans_wait_tx_queue_empty(mvm->trans,
|
||||
mvm_sta->tfd_queue_msk);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
ret = iwm_drain_sta(sc, IWM_VAP(vap), FALSE);
|
||||
|
||||
/* if we are associated - we can't remove the AP STA now */
|
||||
if (is_assoc)
|
||||
return ret;
|
||||
|
||||
/* XXX wait until STA is drained */
|
||||
|
||||
ret = iwm_rm_sta_common(sc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_rm_sta_id(struct iwm_softc *sc, struct ieee80211vap *vap)
|
||||
{
|
||||
/* XXX wait until STA is drained */
|
||||
|
||||
return iwm_rm_sta_common(sc);
|
||||
}
|
||||
|
||||
static int
|
||||
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)
|
||||
{
|
||||
struct iwm_add_sta_cmd cmd;
|
||||
int ret;
|
||||
uint32_t status;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.sta_id = sta->sta_id;
|
||||
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.tid_disable_tx = htole16(0xffff);
|
||||
|
||||
if (addr)
|
||||
IEEE80211_ADDR_COPY(cmd.addr, addr);
|
||||
|
||||
ret = iwm_send_cmd_pdu_status(sc, IWM_ADD_STA,
|
||||
iwm_add_sta_cmd_size(sc),
|
||||
&cmd, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (status & IWM_ADD_STA_STATUS_MASK) {
|
||||
case IWM_ADD_STA_SUCCESS:
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_NODE, "Internal station added.\n");
|
||||
return 0;
|
||||
default:
|
||||
ret = EIO;
|
||||
device_printf(sc->sc_dev,
|
||||
"Add internal station failed, status=0x%x\n", status);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_add_aux_sta(struct iwm_softc *sc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
sc->sc_aux_sta.sta_id = IWM_AUX_STA_ID;
|
||||
sc->sc_aux_sta.tfd_queue_msk = (1 << IWM_AUX_QUEUE);
|
||||
|
||||
/* Map Aux queue to fifo - needs to happen before adding Aux station */
|
||||
ret = iwm_enable_txq(sc, IWM_AUX_STA_ID, IWM_AUX_QUEUE,
|
||||
IWM_TX_FIFO_MCAST);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = iwm_add_int_sta_common(sc, &sc->sc_aux_sta, NULL,
|
||||
IWM_MAC_INDEX_AUX, 0);
|
||||
|
||||
if (ret) {
|
||||
memset(&sc->sc_aux_sta, 0, sizeof(sc->sc_aux_sta));
|
||||
sc->sc_aux_sta.sta_id = IWM_STATION_COUNT;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iwm_del_aux_sta(struct iwm_softc *sc)
|
||||
{
|
||||
memset(&sc->sc_aux_sta, 0, sizeof(sc->sc_aux_sta));
|
||||
sc->sc_aux_sta.sta_id = IWM_STATION_COUNT;
|
||||
}
|
|
@ -1,223 +0,0 @@
|
|||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 4.7.3 (tag id d7f6728f57e3ecbb7ef34eb7d9f564d514775d75)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 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) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#ifndef __IF_IWM_STA_H__
|
||||
#define __IF_IWM_STA_H__
|
||||
|
||||
/**
|
||||
* DOC: station table - introduction
|
||||
*
|
||||
* The station table is a list of data structure that reprensent the stations.
|
||||
* In STA/P2P client mode, the driver will hold one station for the AP/ GO.
|
||||
* In GO/AP mode, the driver will have as many stations as associated clients.
|
||||
* All these stations are reflected in the fw's station table. The driver
|
||||
* keeps the fw's station table up to date with the ADD_STA command. Stations
|
||||
* can be removed by the REMOVE_STA command.
|
||||
*
|
||||
* 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.
|
||||
* This data includes the index of the station in the fw, per tid information
|
||||
* (sequence numbers, Block-ack state machine, etc...). The stations are
|
||||
* 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
|
||||
* %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
|
||||
* 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
|
||||
* %ieee80211 structure. This map helps to get that pointer quickly.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: station table - locking
|
||||
*
|
||||
* As stated before, the station is created / deleted by mac80211's %sta_state
|
||||
* callback from %ieee80211_ops which can sleep. The next paragraph explains
|
||||
* the locking of a single stations, the next ones relates to the station
|
||||
* table.
|
||||
*
|
||||
* The station holds the sequence number per tid. So this data needs to be
|
||||
* accessed in the Tx path (which is softIRQ). It also holds the Block-Ack
|
||||
* information (the state machine / and the logic that checks if the queues
|
||||
* were drained), so it also needs to be accessible from the Tx response flow.
|
||||
* In short, the station needs to be access from sleepable context as well as
|
||||
* from tasklets, so the station itself needs a spinlock.
|
||||
*
|
||||
* The writers of %fw_id_to_mac_id map are serialized by the global mutex of
|
||||
* the mvm op_mode. This is possible since %sta_state can sleep.
|
||||
* The pointers in this map are RCU protected, hence we won't replace the
|
||||
* station while we have Tx / Tx response / BA notification running.
|
||||
*
|
||||
* If a station is deleted while it still has packets in its A-MPDU queues,
|
||||
* then the reclaim flow will notice that there is no station in the map for
|
||||
* sta_id and it will dump the responses.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: station table - internal stations
|
||||
*
|
||||
* 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
|
||||
* scanning and P2P device (during the GO negotiation).
|
||||
* For these kind of stations we have %iwl_int_sta struct which holds the
|
||||
* data relevant for them from both %iwl_sta and %ieee80211_sta.
|
||||
* Usually the data for these stations is static, so no locking is required,
|
||||
* 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
|
||||
* in mac80211. In order to "reserve" them a sta_id in %fw_id_to_mac_id
|
||||
* we fill ERR_PTR(EINVAL) in this mapping and all other dereferencing of
|
||||
* pointers from this mapping need to check that the value is not error
|
||||
* or NULL.
|
||||
*
|
||||
* Currently there is only one auxiliary station for scanning, initialized
|
||||
* on init.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: station table - AP Station in STA mode
|
||||
*
|
||||
* %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,
|
||||
* &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.
|
||||
* Hence, %fw_id_to_mac_id[%ap_sta_id] will be NULLed when the AP station is
|
||||
* removed by mac80211, but the station won't be removed in the fw until the
|
||||
* VIF is set as unassociated. Then, %ap_sta_id will be invalidated.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: station table - Drain vs. Flush
|
||||
*
|
||||
* Flush means that all the frames in the SCD queue are dumped regardless the
|
||||
* station to which they were sent. We do that when we disassociate and before
|
||||
* we remove the STA of the AP. The flush can be done synchronously against the
|
||||
* fw.
|
||||
* Drain means that the fw will drop all the frames sent to a specific station.
|
||||
* This is useful when a client (if we are IBSS / GO or AP) disassociates. In
|
||||
* that case, we need to drain all the frames for that client from the AC queues
|
||||
* that are shared with the other clients. Only then, we can remove the STA in
|
||||
* 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
|
||||
* the queues, we mark this station as %EBUSY in %fw_id_to_mac_id, and drop all
|
||||
* 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
|
||||
* it as %NULL in %fw_id_to_mac_id: this is the purpose of
|
||||
* %iwl_sta_drained_wk.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: station table - fw restart
|
||||
*
|
||||
* When the fw asserts, or we have any other issue that requires to reset the
|
||||
* 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
|
||||
* not be zeroed and needs to be reinitialized manually.
|
||||
* %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
|
||||
* 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
|
||||
* 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
|
||||
* after the restart: mac80211 call's %iwl_mac_start which calls to
|
||||
* %iwl_up.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Send the STA info to the FW.
|
||||
*
|
||||
* @sc: the iwm_softc* to use
|
||||
* @sta: the STA
|
||||
* @update: this is true if the FW is being updated about a STA it already knows
|
||||
* about. Otherwise (if this is a new STA), this should be false.
|
||||
* @flags: if update==true, this marks what is being changed via ORs of values
|
||||
* from enum iwm_sta_modify_flag. Otherwise, this is ignored.
|
||||
*/
|
||||
extern int iwm_sta_send_to_fw(struct iwm_softc *sc, struct iwm_node *in,
|
||||
boolean_t update);
|
||||
extern int iwm_add_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_rm_sta(struct iwm_softc *sc, struct ieee80211vap *vap,
|
||||
boolean_t is_assoc);
|
||||
extern int iwm_rm_sta_id(struct iwm_softc *sc, struct ieee80211vap *vap);
|
||||
|
||||
extern int iwm_add_aux_sta(struct iwm_softc *sc);
|
||||
extern void iwm_del_aux_sta(struct iwm_softc *sc);
|
||||
|
||||
extern int iwm_drain_sta(struct iwm_softc *sc, struct iwm_vap *ivp,
|
||||
boolean_t drain);
|
||||
|
||||
#endif /* __IF_IWM_STA_H__ */
|
|
@ -1,429 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_wlan.h"
|
||||
#include "opt_iwm.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/endian.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_regdomain.h>
|
||||
#include <net80211/ieee80211_ratectl.h>
|
||||
#include <net80211/ieee80211_radiotap.h>
|
||||
|
||||
#include <dev/iwm/if_iwmreg.h>
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_util.h>
|
||||
#include <dev/iwm/if_iwm_notif_wait.h>
|
||||
#include <dev/iwm/if_iwm_pcie_trans.h>
|
||||
#include <dev/iwm/if_iwm_time_event.h>
|
||||
|
||||
#define TU_TO_HZ(tu) (((uint64_t)(tu) * 1024 * hz) / 1000000)
|
||||
|
||||
static void
|
||||
iwm_te_clear_data(struct iwm_softc *sc)
|
||||
{
|
||||
sc->sc_time_event_uid = 0;
|
||||
sc->sc_time_event_duration = 0;
|
||||
sc->sc_time_event_end_ticks = 0;
|
||||
sc->sc_flags &= ~IWM_FLAG_TE_ACTIVE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles a FW notification for an event that is known to the driver.
|
||||
*
|
||||
* @mvm: the mvm component
|
||||
* @te_data: the time event data
|
||||
* @notif: the notification data corresponding the time event data.
|
||||
*/
|
||||
static void
|
||||
iwm_te_handle_notif(struct iwm_softc *sc,
|
||||
struct iwm_time_event_notif *notif)
|
||||
{
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"Handle time event notif - UID = 0x%x action %d\n",
|
||||
le32toh(notif->unique_id),
|
||||
le32toh(notif->action));
|
||||
|
||||
if (!le32toh(notif->status)) {
|
||||
const char *msg;
|
||||
|
||||
if (notif->action & htole32(IWM_TE_V2_NOTIF_HOST_EVENT_START))
|
||||
msg = "Time Event start notification failure";
|
||||
else
|
||||
msg = "Time Event end notification failure";
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE, "%s\n", msg);
|
||||
}
|
||||
|
||||
if (le32toh(notif->action) & IWM_TE_V2_NOTIF_HOST_EVENT_END) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"TE ended - current time %d, estimated end %d\n",
|
||||
ticks, sc->sc_time_event_end_ticks);
|
||||
|
||||
iwm_te_clear_data(sc);
|
||||
} else if (le32toh(notif->action) & IWM_TE_V2_NOTIF_HOST_EVENT_START) {
|
||||
sc->sc_time_event_end_ticks =
|
||||
ticks + TU_TO_HZ(sc->sc_time_event_duration);
|
||||
} else {
|
||||
device_printf(sc->sc_dev, "Got TE with unknown action\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The Rx handler for time event notifications
|
||||
*/
|
||||
void
|
||||
iwm_rx_time_event_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt)
|
||||
{
|
||||
struct iwm_time_event_notif *notif = (void *)pkt->data;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"Time event notification - UID = 0x%x action %d\n",
|
||||
le32toh(notif->unique_id),
|
||||
le32toh(notif->action));
|
||||
|
||||
iwm_te_handle_notif(sc, notif);
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_te_notif(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
|
||||
void *data)
|
||||
{
|
||||
struct iwm_time_event_notif *resp;
|
||||
int resp_len = iwm_rx_packet_payload_len(pkt);
|
||||
|
||||
if (pkt->hdr.code != IWM_TIME_EVENT_NOTIFICATION ||
|
||||
resp_len != sizeof(*resp)) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"Invalid TIME_EVENT_NOTIFICATION response\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
resp = (void *)pkt->data;
|
||||
|
||||
/* te_data->uid is already set in the TIME_EVENT_CMD response */
|
||||
if (le32toh(resp->unique_id) != sc->sc_time_event_uid)
|
||||
return false;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"TIME_EVENT_NOTIFICATION response - UID = 0x%x\n",
|
||||
sc->sc_time_event_uid);
|
||||
if (!resp->status) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"TIME_EVENT_NOTIFICATION received but not executed\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_time_event_response(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
|
||||
void *data)
|
||||
{
|
||||
struct iwm_time_event_resp *resp;
|
||||
int resp_len = iwm_rx_packet_payload_len(pkt);
|
||||
|
||||
if (pkt->hdr.code != IWM_TIME_EVENT_CMD ||
|
||||
resp_len != sizeof(*resp)) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"Invalid TIME_EVENT_CMD response\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
resp = (void *)pkt->data;
|
||||
|
||||
/* we should never get a response to another TIME_EVENT_CMD here */
|
||||
if (le32toh(resp->id) != IWM_TE_BSS_STA_AGGRESSIVE_ASSOC) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"Got TIME_EVENT_CMD response with wrong id: %d\n",
|
||||
le32toh(resp->id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
sc->sc_time_event_uid = le32toh(resp->unique_id);
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"TIME_EVENT_CMD response - UID = 0x%x\n", sc->sc_time_event_uid);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* XXX Use the te_data function argument properly, like in iwlwifi's code. */
|
||||
|
||||
static int
|
||||
iwm_time_event_send_add(struct iwm_softc *sc, struct iwm_vap *ivp,
|
||||
void *te_data, struct iwm_time_event_cmd *te_cmd)
|
||||
{
|
||||
static const uint16_t time_event_response[] = { IWM_TIME_EVENT_CMD };
|
||||
struct iwm_notification_wait wait_time_event;
|
||||
int ret;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"Add new TE, duration %d TU\n", le32toh(te_cmd->duration));
|
||||
|
||||
sc->sc_time_event_duration = le32toh(te_cmd->duration);
|
||||
|
||||
/*
|
||||
* Use a notification wait, which really just processes the
|
||||
* command response and doesn't wait for anything, in order
|
||||
* to be able to process the response and get the UID inside
|
||||
* the RX path. Using CMD_WANT_SKB doesn't work because it
|
||||
* stores the buffer and then wakes up this thread, by which
|
||||
* time another notification (that the time event started)
|
||||
* might already be processed unsuccessfully.
|
||||
*/
|
||||
iwm_init_notification_wait(sc->sc_notif_wait, &wait_time_event,
|
||||
time_event_response,
|
||||
nitems(time_event_response),
|
||||
iwm_time_event_response, /*te_data*/NULL);
|
||||
|
||||
ret = iwm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, 0, sizeof(*te_cmd),
|
||||
te_cmd);
|
||||
if (ret) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"%s: Couldn't send IWM_TIME_EVENT_CMD: %d\n",
|
||||
__func__, ret);
|
||||
iwm_remove_notification(sc->sc_notif_wait, &wait_time_event);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* No need to wait for anything, so just pass 1 (0 isn't valid) */
|
||||
IWM_UNLOCK(sc);
|
||||
ret = iwm_wait_notification(sc->sc_notif_wait, &wait_time_event, 1);
|
||||
IWM_LOCK(sc);
|
||||
/* should never fail */
|
||||
if (ret) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"%s: Failed to get response for IWM_TIME_EVENT_CMD: %d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
iwm_protect_session(struct iwm_softc *sc, struct iwm_vap *ivp,
|
||||
uint32_t duration, uint32_t max_delay, boolean_t wait_for_notif)
|
||||
{
|
||||
const uint16_t te_notif_response[] = { IWM_TIME_EVENT_NOTIFICATION };
|
||||
struct iwm_notification_wait wait_te_notif;
|
||||
struct iwm_time_event_cmd time_cmd = {};
|
||||
|
||||
/* Do nothing if a time event is already scheduled. */
|
||||
if (sc->sc_flags & IWM_FLAG_TE_ACTIVE)
|
||||
return;
|
||||
|
||||
time_cmd.action = htole32(IWM_FW_CTXT_ACTION_ADD);
|
||||
time_cmd.id_and_color =
|
||||
htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id, ivp->color));
|
||||
time_cmd.id = htole32(IWM_TE_BSS_STA_AGGRESSIVE_ASSOC);
|
||||
|
||||
time_cmd.apply_time = htole32(0);
|
||||
|
||||
time_cmd.max_frags = IWM_TE_V2_FRAG_NONE;
|
||||
time_cmd.max_delay = htole32(max_delay);
|
||||
/* TODO: why do we need to interval = bi if it is not periodic? */
|
||||
time_cmd.interval = htole32(1);
|
||||
time_cmd.duration = htole32(duration);
|
||||
time_cmd.repeat = 1;
|
||||
time_cmd.policy
|
||||
= htole16(IWM_TE_V2_NOTIF_HOST_EVENT_START |
|
||||
IWM_TE_V2_NOTIF_HOST_EVENT_END |
|
||||
IWM_T2_V2_START_IMMEDIATELY);
|
||||
|
||||
if (!wait_for_notif) {
|
||||
iwm_time_event_send_add(sc, ivp, /*te_data*/NULL, &time_cmd);
|
||||
DELAY(100);
|
||||
sc->sc_flags |= IWM_FLAG_TE_ACTIVE;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create notification_wait for the TIME_EVENT_NOTIFICATION to use
|
||||
* right after we send the time event
|
||||
*/
|
||||
iwm_init_notification_wait(sc->sc_notif_wait, &wait_te_notif,
|
||||
te_notif_response, nitems(te_notif_response),
|
||||
iwm_te_notif, /*te_data*/NULL);
|
||||
|
||||
/* If TE was sent OK - wait for the notification that started */
|
||||
if (iwm_time_event_send_add(sc, ivp, /*te_data*/NULL, &time_cmd)) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"%s: Failed to add TE to protect session\n", __func__);
|
||||
iwm_remove_notification(sc->sc_notif_wait, &wait_te_notif);
|
||||
} else {
|
||||
sc->sc_flags |= IWM_FLAG_TE_ACTIVE;
|
||||
IWM_UNLOCK(sc);
|
||||
if (iwm_wait_notification(sc->sc_notif_wait, &wait_te_notif,
|
||||
TU_TO_HZ(max_delay))) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"%s: Failed to protect session until TE\n",
|
||||
__func__);
|
||||
}
|
||||
IWM_LOCK(sc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
iwm_stop_session_protection(struct iwm_softc *sc, struct iwm_vap *ivp)
|
||||
{
|
||||
struct iwm_time_event_cmd time_cmd = {};
|
||||
|
||||
/* Do nothing if the time event has already ended. */
|
||||
if ((sc->sc_flags & IWM_FLAG_TE_ACTIVE) == 0)
|
||||
return;
|
||||
|
||||
time_cmd.id = htole32(sc->sc_time_event_uid);
|
||||
time_cmd.action = htole32(IWM_FW_CTXT_ACTION_REMOVE);
|
||||
time_cmd.id_and_color =
|
||||
htole32(IWM_FW_CMD_ID_AND_COLOR(ivp->id, ivp->color));
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TE,
|
||||
"%s: Removing TE 0x%x\n", __func__, le32toh(time_cmd.id));
|
||||
if (iwm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, 0, sizeof(time_cmd),
|
||||
&time_cmd) == 0)
|
||||
iwm_te_clear_data(sc);
|
||||
|
||||
DELAY(100);
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __IF_IWM_TIME_EVENT_H__
|
||||
#define __IF_IWM_TIME_EVENT_H__
|
||||
|
||||
extern void iwm_rx_time_event_notif(struct iwm_softc *sc,
|
||||
struct iwm_rx_packet *pkt);
|
||||
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);
|
||||
extern void iwm_stop_session_protection(struct iwm_softc *sc,
|
||||
struct iwm_vap *ivp);
|
||||
|
||||
#endif /* __IF_IWM_TIME_EVENT_H__ */
|
|
@ -1,532 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_wlan.h"
|
||||
#include "opt_iwm.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/endian.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_regdomain.h>
|
||||
#include <net80211/ieee80211_ratectl.h>
|
||||
#include <net80211/ieee80211_radiotap.h>
|
||||
|
||||
#include <dev/iwm/if_iwmreg.h>
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_config.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_binding.h>
|
||||
#include <dev/iwm/if_iwm_util.h>
|
||||
#include <dev/iwm/if_iwm_pcie_trans.h>
|
||||
|
||||
/*
|
||||
* Send a command to the firmware. We try to implement the Linux
|
||||
* driver interface for the routine.
|
||||
* mostly from if_iwn (iwn_cmd()).
|
||||
*
|
||||
* For now, we always copy the first part and map the second one (if it exists).
|
||||
*/
|
||||
int
|
||||
iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
|
||||
{
|
||||
struct iwm_tx_ring *ring = &sc->txq[IWM_CMD_QUEUE];
|
||||
struct iwm_tfd *desc;
|
||||
struct iwm_tx_data *txdata = NULL;
|
||||
struct iwm_device_cmd *cmd;
|
||||
struct mbuf *m;
|
||||
bus_dma_segment_t seg;
|
||||
bus_addr_t paddr;
|
||||
uint32_t addr_lo;
|
||||
int error = 0, i, paylen, off;
|
||||
int code;
|
||||
int async, wantresp;
|
||||
int group_id;
|
||||
int nsegs;
|
||||
size_t hdrlen, datasz;
|
||||
uint8_t *data;
|
||||
|
||||
code = hcmd->id;
|
||||
async = hcmd->flags & IWM_CMD_ASYNC;
|
||||
wantresp = hcmd->flags & IWM_CMD_WANT_SKB;
|
||||
data = NULL;
|
||||
|
||||
for (i = 0, paylen = 0; i < nitems(hcmd->len); i++) {
|
||||
paylen += hcmd->len[i];
|
||||
}
|
||||
|
||||
/* if the command wants an answer, busy sc_cmd_resp */
|
||||
if (wantresp) {
|
||||
KASSERT(!async, ("invalid async parameter"));
|
||||
while (sc->sc_wantresp != -1)
|
||||
msleep(&sc->sc_wantresp, &sc->sc_mtx, 0, "iwmcmdsl", 0);
|
||||
sc->sc_wantresp = ring->qid << 16 | ring->cur;
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_CMD,
|
||||
"wantresp is %x\n", sc->sc_wantresp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Is the hardware still available? (after e.g. above wait).
|
||||
*/
|
||||
if (sc->sc_flags & IWM_FLAG_STOPPED) {
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
desc = &ring->desc[ring->cur];
|
||||
txdata = &ring->data[ring->cur];
|
||||
|
||||
group_id = iwm_cmd_groupid(code);
|
||||
if (group_id != 0) {
|
||||
hdrlen = sizeof(cmd->hdr_wide);
|
||||
datasz = sizeof(cmd->data_wide);
|
||||
} else {
|
||||
hdrlen = sizeof(cmd->hdr);
|
||||
datasz = sizeof(cmd->data);
|
||||
}
|
||||
|
||||
if (paylen > datasz) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_CMD,
|
||||
"large command paylen=%u len0=%u\n",
|
||||
paylen, hcmd->len[0]);
|
||||
{
|
||||
/* Command is too large */
|
||||
size_t totlen = hdrlen + paylen;
|
||||
if (paylen > IWM_MAX_CMD_PAYLOAD_SIZE) {
|
||||
device_printf(sc->sc_dev,
|
||||
"firmware command too long (%zd bytes)\n",
|
||||
totlen);
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, IWM_RBUF_SIZE);
|
||||
if (m == NULL) {
|
||||
error = ENOBUFS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
|
||||
error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
|
||||
txdata->map, m, &seg, &nsegs, BUS_DMA_NOWAIT);
|
||||
if (error != 0) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: can't map mbuf, error %d\n", __func__, error);
|
||||
m_freem(m);
|
||||
goto out;
|
||||
}
|
||||
txdata->m = m; /* mbuf will be freed in iwm_cmd_done() */
|
||||
cmd = mtod(m, struct iwm_device_cmd *);
|
||||
paddr = seg.ds_addr;
|
||||
}
|
||||
} else {
|
||||
cmd = &ring->cmd[ring->cur];
|
||||
paddr = txdata->cmd_paddr;
|
||||
}
|
||||
|
||||
if (group_id != 0) {
|
||||
cmd->hdr_wide.opcode = iwm_cmd_opcode(code);
|
||||
cmd->hdr_wide.group_id = group_id;
|
||||
cmd->hdr_wide.qid = ring->qid;
|
||||
cmd->hdr_wide.idx = ring->cur;
|
||||
cmd->hdr_wide.length = htole16(paylen);
|
||||
cmd->hdr_wide.version = iwm_cmd_version(code);
|
||||
data = cmd->data_wide;
|
||||
} else {
|
||||
cmd->hdr.code = iwm_cmd_opcode(code);
|
||||
cmd->hdr.flags = 0;
|
||||
cmd->hdr.qid = ring->qid;
|
||||
cmd->hdr.idx = ring->cur;
|
||||
data = cmd->data;
|
||||
}
|
||||
|
||||
for (i = 0, off = 0; i < nitems(hcmd->data); i++) {
|
||||
if (hcmd->len[i] == 0)
|
||||
continue;
|
||||
memcpy(data + off, hcmd->data[i], hcmd->len[i]);
|
||||
off += hcmd->len[i];
|
||||
}
|
||||
KASSERT(off == paylen, ("off %d != paylen %d", off, paylen));
|
||||
|
||||
/* lo field is not aligned */
|
||||
addr_lo = htole32((uint32_t)paddr);
|
||||
memcpy(&desc->tbs[0].lo, &addr_lo, sizeof(uint32_t));
|
||||
desc->tbs[0].hi_n_len = htole16(iwm_get_dma_hi_addr(paddr)
|
||||
| ((hdrlen + paylen) << 4));
|
||||
desc->num_tbs = 1;
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_CMD,
|
||||
"iwm_send_cmd 0x%x size=%lu %s\n",
|
||||
code,
|
||||
(unsigned long) (hcmd->len[0] + hcmd->len[1] + hdrlen),
|
||||
async ? " (async)" : "");
|
||||
|
||||
if (paylen > datasz) {
|
||||
bus_dmamap_sync(ring->data_dmat, txdata->map,
|
||||
BUS_DMASYNC_PREWRITE);
|
||||
} else {
|
||||
bus_dmamap_sync(ring->cmd_dma.tag, ring->cmd_dma.map,
|
||||
BUS_DMASYNC_PREWRITE);
|
||||
}
|
||||
bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
|
||||
BUS_DMASYNC_PREWRITE);
|
||||
|
||||
error = iwm_pcie_set_cmd_in_flight(sc);
|
||||
if (error)
|
||||
goto out;
|
||||
ring->queued++;
|
||||
|
||||
#if 0
|
||||
iwm_update_sched(sc, ring->qid, ring->cur, 0, 0);
|
||||
#endif
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_CMD,
|
||||
"sending command 0x%x qid %d, idx %d\n",
|
||||
code, ring->qid, ring->cur);
|
||||
|
||||
/* Kick command ring. */
|
||||
ring->cur = (ring->cur + 1) % IWM_TX_RING_COUNT;
|
||||
IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
|
||||
|
||||
if (!async) {
|
||||
/* m..m-mmyy-mmyyyy-mym-ym m-my generation */
|
||||
int generation = sc->sc_generation;
|
||||
error = msleep(desc, &sc->sc_mtx, PCATCH, "iwmcmd", hz);
|
||||
if (error == 0) {
|
||||
/* if hardware is no longer up, return error */
|
||||
if (generation != sc->sc_generation) {
|
||||
error = ENXIO;
|
||||
} else {
|
||||
hcmd->resp_pkt = (void *)sc->sc_cmd_resp;
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
if (wantresp && error != 0) {
|
||||
iwm_free_resp(sc, hcmd);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* iwlwifi: mvm/utils.c */
|
||||
int
|
||||
iwm_send_cmd_pdu(struct iwm_softc *sc, uint32_t id,
|
||||
uint32_t flags, uint16_t len, const void *data)
|
||||
{
|
||||
struct iwm_host_cmd cmd = {
|
||||
.id = id,
|
||||
.len = { len, },
|
||||
.data = { data, },
|
||||
.flags = flags,
|
||||
};
|
||||
|
||||
return iwm_send_cmd(sc, &cmd);
|
||||
}
|
||||
|
||||
/* iwlwifi: mvm/utils.c */
|
||||
int
|
||||
iwm_send_cmd_status(struct iwm_softc *sc,
|
||||
struct iwm_host_cmd *cmd, uint32_t *status)
|
||||
{
|
||||
struct iwm_rx_packet *pkt;
|
||||
struct iwm_cmd_response *resp;
|
||||
int error, resp_len;
|
||||
|
||||
KASSERT((cmd->flags & IWM_CMD_WANT_SKB) == 0,
|
||||
("invalid command"));
|
||||
cmd->flags |= IWM_CMD_SYNC | IWM_CMD_WANT_SKB;
|
||||
|
||||
if ((error = iwm_send_cmd(sc, cmd)) != 0)
|
||||
return error;
|
||||
pkt = cmd->resp_pkt;
|
||||
|
||||
/* Can happen if RFKILL is asserted */
|
||||
if (!pkt) {
|
||||
error = 0;
|
||||
goto out_free_resp;
|
||||
}
|
||||
|
||||
if (pkt->hdr.flags & IWM_CMD_FAILED_MSK) {
|
||||
error = EIO;
|
||||
goto out_free_resp;
|
||||
}
|
||||
|
||||
resp_len = iwm_rx_packet_payload_len(pkt);
|
||||
if (resp_len != sizeof(*resp)) {
|
||||
error = EIO;
|
||||
goto out_free_resp;
|
||||
}
|
||||
|
||||
resp = (void *)pkt->data;
|
||||
*status = le32toh(resp->status);
|
||||
out_free_resp:
|
||||
iwm_free_resp(sc, cmd);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* iwlwifi/mvm/utils.c */
|
||||
int
|
||||
iwm_send_cmd_pdu_status(struct iwm_softc *sc, uint32_t id,
|
||||
uint16_t len, const void *data, uint32_t *status)
|
||||
{
|
||||
struct iwm_host_cmd cmd = {
|
||||
.id = id,
|
||||
.len = { len, },
|
||||
.data = { data, },
|
||||
};
|
||||
|
||||
return iwm_send_cmd_status(sc, &cmd, status);
|
||||
}
|
||||
|
||||
void
|
||||
iwm_free_resp(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
|
||||
{
|
||||
KASSERT(sc->sc_wantresp != -1, ("already freed"));
|
||||
KASSERT((hcmd->flags & (IWM_CMD_WANT_SKB|IWM_CMD_SYNC))
|
||||
== (IWM_CMD_WANT_SKB|IWM_CMD_SYNC), ("invalid flags"));
|
||||
sc->sc_wantresp = -1;
|
||||
wakeup(&sc->sc_wantresp);
|
||||
}
|
||||
|
||||
static void
|
||||
iwm_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
|
||||
{
|
||||
if (error != 0)
|
||||
return;
|
||||
KASSERT(nsegs == 1, ("too many DMA segments, %d should be 1", nsegs));
|
||||
*(bus_addr_t *)arg = segs[0].ds_addr;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
|
||||
bus_size_t size, bus_size_t alignment)
|
||||
{
|
||||
int error;
|
||||
|
||||
dma->tag = NULL;
|
||||
dma->map = NULL;
|
||||
dma->size = size;
|
||||
dma->vaddr = NULL;
|
||||
|
||||
error = bus_dma_tag_create(tag, alignment,
|
||||
0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size,
|
||||
1, size, 0, NULL, NULL, &dma->tag);
|
||||
if (error != 0)
|
||||
goto fail;
|
||||
|
||||
error = bus_dmamem_alloc(dma->tag, (void **)&dma->vaddr,
|
||||
BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &dma->map);
|
||||
if (error != 0)
|
||||
goto fail;
|
||||
|
||||
error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr, size,
|
||||
iwm_dma_map_addr, &dma->paddr, BUS_DMA_NOWAIT);
|
||||
if (error != 0) {
|
||||
bus_dmamem_free(dma->tag, dma->vaddr, dma->map);
|
||||
dma->vaddr = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
iwm_dma_contig_free(dma);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
iwm_dma_contig_free(struct iwm_dma_info *dma)
|
||||
{
|
||||
if (dma->vaddr != NULL) {
|
||||
bus_dmamap_sync(dma->tag, dma->map,
|
||||
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
||||
bus_dmamap_unload(dma->tag, dma->map);
|
||||
bus_dmamem_free(dma->tag, dma->vaddr, dma->map);
|
||||
dma->vaddr = NULL;
|
||||
}
|
||||
if (dma->tag != NULL) {
|
||||
bus_dma_tag_destroy(dma->tag);
|
||||
dma->tag = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* iwm_send_lq_cmd() - Send link quality command
|
||||
* @init: This command is sent as part of station initialization right
|
||||
* after station has been added.
|
||||
*
|
||||
* The link quality command is sent as the last step of station creation.
|
||||
* This is the special case in which init is set and we call a callback in
|
||||
* this case to clear the state indicating that station creation is in
|
||||
* progress.
|
||||
*/
|
||||
int
|
||||
iwm_send_lq_cmd(struct iwm_softc *sc, struct iwm_lq_cmd *lq, boolean_t init)
|
||||
{
|
||||
struct iwm_host_cmd cmd = {
|
||||
.id = IWM_LQ_CMD,
|
||||
.len = { sizeof(struct iwm_lq_cmd), },
|
||||
.flags = init ? 0 : IWM_CMD_ASYNC,
|
||||
.data = { lq, },
|
||||
};
|
||||
|
||||
if (lq->sta_id == IWM_STATION_COUNT)
|
||||
return EINVAL;
|
||||
|
||||
return iwm_send_cmd(sc, &cmd);
|
||||
}
|
||||
|
||||
boolean_t
|
||||
iwm_rx_diversity_allowed(struct iwm_softc *sc)
|
||||
{
|
||||
if (num_of_ant(iwm_get_valid_rx_ant(sc)) == 1)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* XXX Also return FALSE when SMPS (Spatial Multiplexing Powersave)
|
||||
* is used on any vap (in the future).
|
||||
*/
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -1,163 +0,0 @@
|
|||
/* $OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef __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_pdu(struct iwm_softc *sc, uint32_t id,
|
||||
uint32_t flags, uint16_t len, const void *data);
|
||||
|
||||
extern int iwm_send_cmd_status(struct iwm_softc *sc,
|
||||
struct iwm_host_cmd *cmd, uint32_t *status);
|
||||
extern int iwm_send_cmd_pdu_status(struct iwm_softc *sc, uint32_t id,
|
||||
uint16_t len, const void *data, uint32_t *status);
|
||||
extern void iwm_free_resp(struct iwm_softc *sc, struct iwm_host_cmd *hcmd);
|
||||
|
||||
extern int iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
|
||||
bus_size_t size, bus_size_t alignment);
|
||||
extern void iwm_dma_contig_free(struct iwm_dma_info *);
|
||||
|
||||
extern int iwm_send_lq_cmd(struct iwm_softc *sc, struct iwm_lq_cmd *lq,
|
||||
boolean_t init);
|
||||
|
||||
extern boolean_t iwm_rx_diversity_allowed(struct iwm_softc *sc);
|
||||
|
||||
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_flush_tx_path(struct iwm_softc *sc, uint32_t tfd_msk,
|
||||
uint32_t flags);
|
||||
|
||||
static inline uint8_t
|
||||
iwm_get_valid_tx_ant(struct iwm_softc *sc)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
static inline uint8_t
|
||||
iwm_get_valid_rx_ant(struct iwm_softc *sc)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
iwm_get_phy_config(struct iwm_softc *sc)
|
||||
{
|
||||
uint32_t phy_config = ~(IWM_FW_PHY_CFG_TX_CHAIN |
|
||||
IWM_FW_PHY_CFG_RX_CHAIN);
|
||||
uint32_t valid_rx_ant = iwm_get_valid_rx_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 |
|
||||
valid_rx_ant << IWM_FW_PHY_CFG_RX_CHAIN_POS;
|
||||
|
||||
return sc->sc_fw.phy_config & phy_config;
|
||||
}
|
||||
|
||||
#endif /* __IF_IWM_UTIL_H__ */
|
|
@ -1,585 +0,0 @@
|
|||
/* $OpenBSD: if_iwmvar.h,v 1.7 2015/03/02 13:51:10 jsg Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
struct iwm_rx_radiotap_header {
|
||||
struct ieee80211_radiotap_header wr_ihdr;
|
||||
uint64_t wr_tsft;
|
||||
uint8_t wr_flags;
|
||||
uint8_t wr_rate;
|
||||
uint16_t wr_chan_freq;
|
||||
uint16_t wr_chan_flags;
|
||||
int8_t wr_dbm_antsignal;
|
||||
int8_t wr_dbm_antnoise;
|
||||
} __packed __aligned(8);
|
||||
|
||||
#define IWM_RX_RADIOTAP_PRESENT \
|
||||
((1 << IEEE80211_RADIOTAP_TSFT) | \
|
||||
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
|
||||
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
|
||||
|
||||
struct iwm_tx_radiotap_header {
|
||||
struct ieee80211_radiotap_header wt_ihdr;
|
||||
uint8_t wt_flags;
|
||||
uint8_t wt_rate;
|
||||
uint16_t wt_chan_freq;
|
||||
uint16_t wt_chan_flags;
|
||||
} __packed;
|
||||
|
||||
#define IWM_TX_RADIOTAP_PRESENT \
|
||||
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL))
|
||||
|
||||
|
||||
#define IWM_UCODE_SECTION_MAX 16
|
||||
|
||||
/**
|
||||
* enum iwm_ucode_type
|
||||
*
|
||||
* The type of ucode.
|
||||
*
|
||||
* @IWM_UCODE_REGULAR: Normal runtime ucode
|
||||
* @IWM_UCODE_INIT: Initial ucode
|
||||
* @IWM_UCODE_WOWLAN: Wake on Wireless enabled ucode
|
||||
* @IWM_UCODE_REGULAR_USNIFFER: Normal runtime ucode when using usniffer image
|
||||
*/
|
||||
enum iwm_ucode_type {
|
||||
IWM_UCODE_REGULAR,
|
||||
IWM_UCODE_INIT,
|
||||
IWM_UCODE_WOWLAN,
|
||||
IWM_UCODE_REGULAR_USNIFFER,
|
||||
IWM_UCODE_TYPE_MAX
|
||||
};
|
||||
|
||||
struct iwm_ucode_capabilities {
|
||||
uint32_t max_probe_length;
|
||||
uint32_t n_scan_channels;
|
||||
uint32_t flags;
|
||||
uint8_t enabled_api[howmany(IWM_NUM_UCODE_TLV_API, NBBY)];
|
||||
uint8_t enabled_capa[howmany(IWM_NUM_UCODE_TLV_CAPA, NBBY)];
|
||||
};
|
||||
|
||||
/* one for each uCode image (inst/data, init/runtime/wowlan) */
|
||||
struct iwm_fw_desc {
|
||||
const void *data; /* vmalloc'ed data */
|
||||
uint32_t len; /* size in bytes */
|
||||
uint32_t offset; /* offset in the device */
|
||||
};
|
||||
|
||||
struct iwm_fw_img {
|
||||
struct iwm_fw_desc sec[IWM_UCODE_SECTION_MAX];
|
||||
int fw_count;
|
||||
int is_dual_cpus;
|
||||
uint32_t paging_mem_size;
|
||||
};
|
||||
|
||||
struct iwm_fw_info {
|
||||
const struct firmware *fw_fp;
|
||||
|
||||
/* ucode images */
|
||||
struct iwm_fw_img img[IWM_UCODE_TYPE_MAX];
|
||||
|
||||
struct iwm_ucode_capabilities ucode_capa;
|
||||
|
||||
uint32_t phy_config;
|
||||
uint8_t valid_tx_ant;
|
||||
uint8_t valid_rx_ant;
|
||||
};
|
||||
|
||||
struct iwm_nvm_data {
|
||||
int n_hw_addrs;
|
||||
uint8_t hw_addr[IEEE80211_ADDR_LEN];
|
||||
|
||||
int sku_cap_band_24GHz_enable;
|
||||
int sku_cap_band_52GHz_enable;
|
||||
int sku_cap_11n_enable;
|
||||
int sku_cap_amt_enable;
|
||||
int sku_cap_ipan_enable;
|
||||
|
||||
uint8_t radio_cfg_type;
|
||||
uint8_t radio_cfg_step;
|
||||
uint8_t radio_cfg_dash;
|
||||
uint8_t radio_cfg_pnum;
|
||||
uint8_t valid_tx_ant, valid_rx_ant;
|
||||
#define IWM_NUM_CHANNELS 39
|
||||
#define IWM_NUM_CHANNELS_8000 51
|
||||
|
||||
uint16_t nvm_version;
|
||||
uint8_t max_tx_pwr_half_dbm;
|
||||
|
||||
boolean_t lar_enabled;
|
||||
uint16_t nvm_ch_flags[0];
|
||||
};
|
||||
|
||||
/* max bufs per tfd the driver will use */
|
||||
#define IWM_MAX_CMD_TBS_PER_TFD 2
|
||||
|
||||
struct iwm_rx_packet;
|
||||
struct iwm_host_cmd {
|
||||
const void *data[IWM_MAX_CMD_TBS_PER_TFD];
|
||||
struct iwm_rx_packet *resp_pkt;
|
||||
unsigned long _rx_page_addr;
|
||||
uint32_t _rx_page_order;
|
||||
int handler_status;
|
||||
|
||||
uint32_t flags;
|
||||
uint32_t id;
|
||||
uint16_t len[IWM_MAX_CMD_TBS_PER_TFD];
|
||||
uint8_t dataflags[IWM_MAX_CMD_TBS_PER_TFD];
|
||||
};
|
||||
|
||||
/*
|
||||
* DMA glue is from iwn
|
||||
*/
|
||||
|
||||
typedef caddr_t iwm_caddr_t;
|
||||
typedef void *iwm_hookarg_t;
|
||||
|
||||
struct iwm_dma_info {
|
||||
bus_dma_tag_t tag;
|
||||
bus_dmamap_t map;
|
||||
bus_dma_segment_t seg;
|
||||
bus_addr_t paddr;
|
||||
void *vaddr;
|
||||
bus_size_t size;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwm_fw_paging
|
||||
* @fw_paging_block: dma memory info
|
||||
* @fw_paging_size: page size
|
||||
*/
|
||||
struct iwm_fw_paging {
|
||||
struct iwm_dma_info fw_paging_block;
|
||||
uint32_t fw_paging_size;
|
||||
};
|
||||
|
||||
#define IWM_TX_RING_COUNT 256
|
||||
#define IWM_TX_RING_LOMARK 192
|
||||
#define IWM_TX_RING_HIMARK 224
|
||||
|
||||
struct iwm_tx_data {
|
||||
bus_dmamap_t map;
|
||||
bus_addr_t cmd_paddr;
|
||||
bus_addr_t scratch_paddr;
|
||||
struct mbuf *m;
|
||||
struct iwm_node *in;
|
||||
int done;
|
||||
};
|
||||
|
||||
struct iwm_tx_ring {
|
||||
struct iwm_dma_info desc_dma;
|
||||
struct iwm_dma_info cmd_dma;
|
||||
struct iwm_tfd *desc;
|
||||
struct iwm_device_cmd *cmd;
|
||||
bus_dma_tag_t data_dmat;
|
||||
struct iwm_tx_data data[IWM_TX_RING_COUNT];
|
||||
int qid;
|
||||
int queued;
|
||||
int cur;
|
||||
};
|
||||
|
||||
#define IWM_RX_LEGACY_RING_COUNT 256
|
||||
#define IWM_RX_MQ_RING_COUNT 512
|
||||
|
||||
#define IWM_RBUF_SIZE 4096
|
||||
|
||||
#define IWM_MAX_SCATTER 20
|
||||
|
||||
struct iwm_rx_data {
|
||||
struct mbuf *m;
|
||||
bus_dmamap_t map;
|
||||
};
|
||||
|
||||
struct iwm_rx_ring {
|
||||
struct iwm_dma_info free_desc_dma;
|
||||
struct iwm_dma_info used_desc_dma;
|
||||
struct iwm_dma_info stat_dma;
|
||||
struct iwm_dma_info buf_dma;
|
||||
void *desc;
|
||||
struct iwm_rb_status *stat;
|
||||
struct iwm_rx_data data[512];
|
||||
bus_dmamap_t spare_map; /* for iwm_rx_addbuf() */
|
||||
bus_dma_tag_t data_dmat;
|
||||
int cur;
|
||||
};
|
||||
|
||||
#define IWM_CMD_RESP_MAX PAGE_SIZE
|
||||
|
||||
#define IWM_TE_SESSION_PROTECTION_MAX_TIME_MS 500
|
||||
#define IWM_TE_SESSION_PROTECTION_MIN_TIME_MS 400
|
||||
|
||||
/*
|
||||
* Command headers are in iwl-trans.h, which is full of all
|
||||
* kinds of other junk, so we just replicate the structures here.
|
||||
* First the software bits:
|
||||
*/
|
||||
enum IWM_CMD_MODE {
|
||||
IWM_CMD_SYNC = 0,
|
||||
IWM_CMD_ASYNC = (1 << 0),
|
||||
IWM_CMD_WANT_SKB = (1 << 1),
|
||||
IWM_CMD_SEND_IN_RFKILL = (1 << 2),
|
||||
};
|
||||
enum iwm_hcmd_dataflag {
|
||||
IWM_HCMD_DFL_NOCOPY = (1 << 0),
|
||||
IWM_HCMD_DFL_DUP = (1 << 1),
|
||||
};
|
||||
|
||||
struct iwm_int_sta {
|
||||
uint32_t sta_id;
|
||||
uint32_t tfd_queue_msk;
|
||||
};
|
||||
|
||||
struct iwm_phy_ctxt {
|
||||
uint16_t id;
|
||||
uint16_t color;
|
||||
uint32_t ref;
|
||||
struct ieee80211_channel *channel;
|
||||
};
|
||||
|
||||
struct iwm_bf_data {
|
||||
int bf_enabled; /* filtering */
|
||||
int ba_enabled; /* abort */
|
||||
int ave_beacon_signal;
|
||||
int last_cqm_event;
|
||||
};
|
||||
|
||||
struct iwm_vap {
|
||||
struct ieee80211vap iv_vap;
|
||||
int is_uploaded;
|
||||
int iv_auth;
|
||||
|
||||
int (*iv_newstate)(struct ieee80211vap *,
|
||||
enum ieee80211_state, int);
|
||||
|
||||
struct iwm_phy_ctxt *phy_ctxt;
|
||||
|
||||
uint16_t id;
|
||||
uint16_t color;
|
||||
|
||||
boolean_t have_wme;
|
||||
/*
|
||||
* QoS data from net80211, need to store this here
|
||||
* as net80211 has a separate callback but we need
|
||||
* to have the data for the MAC context
|
||||
*/
|
||||
struct {
|
||||
uint16_t cw_min;
|
||||
uint16_t cw_max;
|
||||
uint16_t edca_txop;
|
||||
uint8_t aifsn;
|
||||
} queue_params[WME_NUM_AC];
|
||||
|
||||
/* indicates that this interface requires PS to be disabled */
|
||||
boolean_t ps_disabled;
|
||||
};
|
||||
#define IWM_VAP(_vap) ((struct iwm_vap *)(_vap))
|
||||
|
||||
struct iwm_node {
|
||||
struct ieee80211_node in_ni;
|
||||
|
||||
/* status "bits" */
|
||||
int in_assoc;
|
||||
|
||||
struct iwm_lq_cmd in_lq;
|
||||
};
|
||||
#define IWM_NODE(_ni) ((struct iwm_node *)(_ni))
|
||||
|
||||
#define IWM_STATION_ID 0
|
||||
#define IWM_AUX_STA_ID 1
|
||||
|
||||
#define IWM_DEFAULT_MACID 0
|
||||
#define IWM_DEFAULT_COLOR 0
|
||||
#define IWM_DEFAULT_TSFID 0
|
||||
|
||||
#define IWM_ICT_SIZE 4096
|
||||
#define IWM_ICT_COUNT (IWM_ICT_SIZE / sizeof (uint32_t))
|
||||
#define IWM_ICT_PADDR_SHIFT 12
|
||||
|
||||
struct iwm_cfg;
|
||||
|
||||
struct iwm_softc {
|
||||
device_t sc_dev;
|
||||
uint32_t sc_debug;
|
||||
int sc_attached;
|
||||
|
||||
struct mtx sc_mtx;
|
||||
struct mbufq sc_snd;
|
||||
struct ieee80211com sc_ic;
|
||||
struct ieee80211_ratectl_tx_status sc_txs;
|
||||
|
||||
int sc_flags;
|
||||
#define IWM_FLAG_USE_ICT (1 << 0)
|
||||
#define IWM_FLAG_HW_INITED (1 << 1)
|
||||
#define IWM_FLAG_STOPPED (1 << 2)
|
||||
#define IWM_FLAG_RFKILL (1 << 3)
|
||||
#define IWM_FLAG_BUSY (1 << 4)
|
||||
#define IWM_FLAG_SCANNING (1 << 5)
|
||||
#define IWM_FLAG_SCAN_RUNNING (1 << 6)
|
||||
#define IWM_FLAG_TE_ACTIVE (1 << 7)
|
||||
|
||||
struct intr_config_hook sc_preinit_hook;
|
||||
struct callout sc_watchdog_to;
|
||||
struct callout sc_led_blink_to;
|
||||
|
||||
struct task init_task;
|
||||
|
||||
struct resource *sc_irq;
|
||||
struct resource *sc_mem;
|
||||
bus_space_tag_t sc_st;
|
||||
bus_space_handle_t sc_sh;
|
||||
bus_size_t sc_sz;
|
||||
bus_dma_tag_t sc_dmat;
|
||||
void *sc_ih;
|
||||
|
||||
/* TX scheduler rings. */
|
||||
struct iwm_dma_info sched_dma;
|
||||
uint32_t scd_base_addr;
|
||||
|
||||
/* TX/RX rings. */
|
||||
struct iwm_tx_ring txq[IWM_MAX_QUEUES];
|
||||
struct iwm_rx_ring rxq;
|
||||
int qfullmsk;
|
||||
|
||||
/* ICT table. */
|
||||
struct iwm_dma_info ict_dma;
|
||||
int ict_cur;
|
||||
|
||||
int sc_hw_rev;
|
||||
int sc_hw_id;
|
||||
|
||||
struct iwm_dma_info kw_dma;
|
||||
struct iwm_dma_info fw_dma;
|
||||
|
||||
int sc_fw_chunk_done;
|
||||
|
||||
enum iwm_ucode_type cur_ucode;
|
||||
int ucode_loaded;
|
||||
char sc_fwver[32];
|
||||
|
||||
char sc_fw_mcc[3];
|
||||
|
||||
int sc_intmask;
|
||||
|
||||
/*
|
||||
* So why do we need a separate stopped flag and a generation?
|
||||
* the former protects the device from issuing commands when it's
|
||||
* stopped (duh). The latter protects against race from a very
|
||||
* fast stop/unstop cycle where threads waiting for responses do
|
||||
* not have a chance to run in between. Notably: we want to stop
|
||||
* the device from interrupt context when it craps out, so we
|
||||
* don't have the luxury of waiting for quiescense.
|
||||
*/
|
||||
int sc_generation;
|
||||
|
||||
struct iwm_fw_info sc_fw;
|
||||
struct iwm_tlv_calib_ctrl sc_default_calib[IWM_UCODE_TYPE_MAX];
|
||||
|
||||
const struct iwm_cfg *cfg;
|
||||
struct iwm_nvm_data *nvm_data;
|
||||
struct iwm_phy_db *sc_phy_db;
|
||||
|
||||
struct iwm_bf_data sc_bf;
|
||||
|
||||
int sc_tx_timer;
|
||||
|
||||
int sc_scan_last_antenna;
|
||||
|
||||
int sc_fixed_ridx;
|
||||
|
||||
int sc_staid;
|
||||
int sc_nodecolor;
|
||||
|
||||
uint8_t sc_cmd_resp[IWM_CMD_RESP_MAX];
|
||||
int sc_wantresp;
|
||||
|
||||
struct taskqueue *sc_tq;
|
||||
struct task sc_es_task;
|
||||
struct task sc_rftoggle_task;
|
||||
|
||||
struct iwm_rx_phy_info sc_last_phy_info;
|
||||
int sc_ampdu_ref;
|
||||
|
||||
struct iwm_int_sta sc_aux_sta;
|
||||
|
||||
/* phy contexts. we only use the first one */
|
||||
struct iwm_phy_ctxt sc_phyctxt[IWM_NUM_PHY_CTX];
|
||||
|
||||
struct iwm_notif_statistics_v10 sc_stats;
|
||||
int sc_noise;
|
||||
|
||||
struct iwm_rx_radiotap_header sc_rxtap;
|
||||
struct iwm_tx_radiotap_header sc_txtap;
|
||||
|
||||
int sc_max_rssi;
|
||||
|
||||
struct iwm_notif_wait_data *sc_notif_wait;
|
||||
|
||||
int cmd_hold_nic_awake;
|
||||
|
||||
/* Firmware status */
|
||||
uint32_t error_event_table[2];
|
||||
uint32_t log_event_table;
|
||||
uint32_t umac_error_event_table;
|
||||
int support_umac_log;
|
||||
|
||||
/*
|
||||
* Paging parameters - All of the parameters should be set by the
|
||||
* opmode when paging is enabled
|
||||
*/
|
||||
struct iwm_fw_paging fw_paging_db[IWM_NUM_OF_FW_PAGING_BLOCKS];
|
||||
uint16_t num_of_paging_blk;
|
||||
uint16_t num_of_pages_in_last_blk;
|
||||
|
||||
boolean_t last_ebs_successful;
|
||||
|
||||
/* last smart fifo state that was successfully sent to firmware */
|
||||
enum iwm_sf_state sf_state;
|
||||
|
||||
/* Indicate if device power save is allowed */
|
||||
boolean_t sc_ps_disabled;
|
||||
|
||||
int sc_ltr_enabled;
|
||||
|
||||
/* Track firmware state for STA association. */
|
||||
int sc_firmware_state;
|
||||
|
||||
/* Unique ID (assigned by the firmware) of the current Time Event. */
|
||||
uint32_t sc_time_event_uid;
|
||||
|
||||
/* Duration of the Time Event in TU. */
|
||||
uint32_t sc_time_event_duration;
|
||||
|
||||
/* Expected end of the Time Event in HZ ticks. */
|
||||
int sc_time_event_end_ticks;
|
||||
|
||||
#ifdef __HAIKU__
|
||||
uint32_t sc_intr_status_1;
|
||||
uint32_t sc_intr_status_2;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define IWM_LOCK_INIT(_sc) \
|
||||
mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
|
||||
MTX_NETWORK_LOCK, MTX_DEF);
|
||||
#define IWM_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
|
||||
#define IWM_UNLOCK(_sc) mtx_unlock(&(_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);
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
//#define IEEE80211_SUPPORT_SUPERG 1
|
||||
//#define IEEE80211_SUPPORT_TDMA 1
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,692 @@
|
|||
/* $OpenBSD: if_iwmvar.h,v 1.77 2022/03/19 14:50:01 stsp Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 genua mbh <info@genua.de>
|
||||
* Copyright (c) 2014 Fixup Software Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
|
||||
* which were used as the reference documentation for this implementation.
|
||||
*
|
||||
* Driver version we are currently based off of is
|
||||
* Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
|
||||
*
|
||||
***********************************************************************
|
||||
*
|
||||
* 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) 2007 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
struct iwm_rx_radiotap_header {
|
||||
struct ieee80211_radiotap_header wr_ihdr;
|
||||
uint64_t wr_tsft;
|
||||
uint8_t wr_flags;
|
||||
uint8_t wr_rate;
|
||||
uint16_t wr_chan_freq;
|
||||
uint16_t wr_chan_flags;
|
||||
int8_t wr_dbm_antsignal;
|
||||
int8_t wr_dbm_antnoise;
|
||||
} __packed;
|
||||
|
||||
#define IWM_RX_RADIOTAP_PRESENT \
|
||||
((1 << IEEE80211_RADIOTAP_TSFT) | \
|
||||
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
|
||||
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
|
||||
|
||||
struct iwm_tx_radiotap_header {
|
||||
struct ieee80211_radiotap_header wt_ihdr;
|
||||
uint8_t wt_flags;
|
||||
uint8_t wt_rate;
|
||||
uint16_t wt_chan_freq;
|
||||
uint16_t wt_chan_flags;
|
||||
} __packed;
|
||||
|
||||
#define IWM_TX_RADIOTAP_PRESENT \
|
||||
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL))
|
||||
|
||||
#define IWM_UCODE_SECT_MAX 16
|
||||
#define IWM_FWDMASEGSZ (192*1024)
|
||||
#define IWM_FWDMASEGSZ_8000 (320*1024)
|
||||
/* sanity check value */
|
||||
#define IWM_FWMAXSIZE (2*1024*1024)
|
||||
|
||||
/*
|
||||
* fw_status is used to determine if we've already parsed the firmware file
|
||||
*
|
||||
* In addition to the following, status < 0 ==> -error
|
||||
*/
|
||||
#define IWM_FW_STATUS_NONE 0
|
||||
#define IWM_FW_STATUS_INPROGRESS 1
|
||||
#define IWM_FW_STATUS_DONE 2
|
||||
|
||||
enum iwm_ucode_type {
|
||||
IWM_UCODE_TYPE_REGULAR,
|
||||
IWM_UCODE_TYPE_INIT,
|
||||
IWM_UCODE_TYPE_WOW,
|
||||
IWM_UCODE_TYPE_REGULAR_USNIFFER,
|
||||
IWM_UCODE_TYPE_MAX
|
||||
};
|
||||
|
||||
struct iwm_fw_info {
|
||||
void *fw_rawdata;
|
||||
size_t fw_rawsize;
|
||||
int fw_status;
|
||||
|
||||
struct iwm_fw_sects {
|
||||
struct iwm_fw_onesect {
|
||||
void *fws_data;
|
||||
uint32_t fws_len;
|
||||
uint32_t fws_devoff;
|
||||
} fw_sect[IWM_UCODE_SECT_MAX];
|
||||
size_t fw_totlen;
|
||||
int fw_count;
|
||||
uint32_t paging_mem_size;
|
||||
} fw_sects[IWM_UCODE_TYPE_MAX];
|
||||
};
|
||||
|
||||
struct iwm_nvm_data {
|
||||
int n_hw_addrs;
|
||||
uint8_t hw_addr[ETHER_ADDR_LEN];
|
||||
|
||||
uint8_t calib_version;
|
||||
uint16_t calib_voltage;
|
||||
|
||||
uint16_t raw_temperature;
|
||||
uint16_t kelvin_temperature;
|
||||
uint16_t kelvin_voltage;
|
||||
uint16_t xtal_calib[2];
|
||||
|
||||
int sku_cap_band_24GHz_enable;
|
||||
int sku_cap_band_52GHz_enable;
|
||||
int sku_cap_11n_enable;
|
||||
int sku_cap_11ac_enable;
|
||||
int sku_cap_amt_enable;
|
||||
int sku_cap_ipan_enable;
|
||||
int sku_cap_mimo_disable;
|
||||
|
||||
uint8_t radio_cfg_type;
|
||||
uint8_t radio_cfg_step;
|
||||
uint8_t radio_cfg_dash;
|
||||
uint8_t radio_cfg_pnum;
|
||||
uint8_t valid_tx_ant, valid_rx_ant;
|
||||
|
||||
uint16_t nvm_version;
|
||||
uint8_t max_tx_pwr_half_dbm;
|
||||
|
||||
int lar_enabled;
|
||||
};
|
||||
|
||||
/* max bufs per tfd the driver will use */
|
||||
#define IWM_MAX_CMD_TBS_PER_TFD 2
|
||||
|
||||
struct iwm_host_cmd {
|
||||
const void *data[IWM_MAX_CMD_TBS_PER_TFD];
|
||||
struct iwm_rx_packet *resp_pkt;
|
||||
size_t resp_pkt_len;
|
||||
unsigned long _rx_page_addr;
|
||||
uint32_t _rx_page_order;
|
||||
int handler_status;
|
||||
|
||||
uint32_t flags;
|
||||
uint16_t len[IWM_MAX_CMD_TBS_PER_TFD];
|
||||
uint8_t dataflags[IWM_MAX_CMD_TBS_PER_TFD];
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
/*
|
||||
* DMA glue is from iwn
|
||||
*/
|
||||
|
||||
struct iwm_dma_info {
|
||||
bus_dma_tag_t tag;
|
||||
bus_dmamap_t map;
|
||||
bus_dma_segment_t seg;
|
||||
bus_addr_t paddr;
|
||||
void *vaddr;
|
||||
bus_size_t size;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwm_fw_paging
|
||||
* @fw_paging_block: dma memory info
|
||||
* @fw_paging_size: page size
|
||||
*/
|
||||
struct iwm_fw_paging {
|
||||
struct iwm_dma_info fw_paging_block;
|
||||
uint32_t fw_paging_size;
|
||||
};
|
||||
|
||||
#define IWM_TX_RING_COUNT 256
|
||||
#define IWM_TX_RING_LOMARK 192
|
||||
#define IWM_TX_RING_HIMARK 224
|
||||
|
||||
/* For aggregation queues, index must be aligned to frame sequence number. */
|
||||
#define IWM_AGG_SSN_TO_TXQ_IDX(x) ((x) & (IWM_TX_RING_COUNT - 1))
|
||||
|
||||
struct iwm_tx_data {
|
||||
bus_dmamap_t map;
|
||||
bus_addr_t cmd_paddr;
|
||||
bus_addr_t scratch_paddr;
|
||||
struct mbuf *m;
|
||||
struct iwm_node *in;
|
||||
int txmcs;
|
||||
int txrate;
|
||||
|
||||
/* A-MPDU subframes */
|
||||
int ampdu_txmcs;
|
||||
int ampdu_txnss;
|
||||
int ampdu_nframes;
|
||||
};
|
||||
|
||||
struct iwm_tx_ring {
|
||||
struct iwm_dma_info desc_dma;
|
||||
struct iwm_dma_info cmd_dma;
|
||||
struct iwm_tfd *desc;
|
||||
struct iwm_device_cmd *cmd;
|
||||
struct iwm_tx_data data[IWM_TX_RING_COUNT];
|
||||
int qid;
|
||||
int queued;
|
||||
int cur;
|
||||
int tail;
|
||||
};
|
||||
|
||||
#define IWM_RX_MQ_RING_COUNT 512
|
||||
#define IWM_RX_RING_COUNT 256
|
||||
/* Linux driver optionally uses 8k buffer */
|
||||
#define IWM_RBUF_SIZE 4096
|
||||
|
||||
struct iwm_rx_data {
|
||||
struct mbuf *m;
|
||||
bus_dmamap_t map;
|
||||
};
|
||||
|
||||
struct iwm_rx_ring {
|
||||
struct iwm_dma_info free_desc_dma;
|
||||
struct iwm_dma_info stat_dma;
|
||||
struct iwm_dma_info used_desc_dma;
|
||||
struct iwm_dma_info buf_dma;
|
||||
void *desc;
|
||||
struct iwm_rb_status *stat;
|
||||
struct iwm_rx_data data[IWM_RX_MQ_RING_COUNT];
|
||||
int cur;
|
||||
};
|
||||
|
||||
#define IWM_FLAG_USE_ICT 0x01 /* using Interrupt Cause Table */
|
||||
#define IWM_FLAG_RFKILL 0x02 /* radio kill switch is set */
|
||||
#define IWM_FLAG_SCANNING 0x04 /* scan in progress */
|
||||
#define IWM_FLAG_MAC_ACTIVE 0x08 /* MAC context added to firmware */
|
||||
#define IWM_FLAG_BINDING_ACTIVE 0x10 /* MAC->PHY binding added to firmware */
|
||||
#define IWM_FLAG_STA_ACTIVE 0x20 /* AP added to firmware station table */
|
||||
#define IWM_FLAG_TE_ACTIVE 0x40 /* time event is scheduled */
|
||||
#define IWM_FLAG_HW_ERR 0x80 /* hardware error occurred */
|
||||
#define IWM_FLAG_SHUTDOWN 0x100 /* shutting down; new tasks forbidden */
|
||||
#define IWM_FLAG_BGSCAN 0x200 /* background scan in progress */
|
||||
#define IWM_FLAG_TXFLUSH 0x400 /* Tx queue flushing in progress */
|
||||
|
||||
struct iwm_ucode_status {
|
||||
uint32_t uc_error_event_table;
|
||||
uint32_t uc_umac_error_event_table;
|
||||
uint32_t uc_log_event_table;
|
||||
|
||||
int uc_ok;
|
||||
int uc_intr;
|
||||
};
|
||||
|
||||
#define IWM_CMD_RESP_MAX PAGE_SIZE
|
||||
|
||||
/* lower blocks contain EEPROM image and calibration data */
|
||||
#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000 16384
|
||||
#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000 32768
|
||||
|
||||
#define IWM_TE_SESSION_PROTECTION_MAX_TIME_MS 1000
|
||||
#define IWM_TE_SESSION_PROTECTION_MIN_TIME_MS 400
|
||||
|
||||
enum IWM_CMD_MODE {
|
||||
IWM_CMD_ASYNC = (1 << 0),
|
||||
IWM_CMD_WANT_RESP = (1 << 1),
|
||||
IWM_CMD_SEND_IN_RFKILL = (1 << 2),
|
||||
};
|
||||
enum iwm_hcmd_dataflag {
|
||||
IWM_HCMD_DFL_NOCOPY = (1 << 0),
|
||||
IWM_HCMD_DFL_DUP = (1 << 1),
|
||||
};
|
||||
|
||||
#define IWM_NUM_PAPD_CH_GROUPS 9
|
||||
#define IWM_NUM_TXP_CH_GROUPS 9
|
||||
|
||||
struct iwm_phy_db_entry {
|
||||
uint16_t size;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
struct iwm_phy_db {
|
||||
struct iwm_phy_db_entry cfg;
|
||||
struct iwm_phy_db_entry calib_nch;
|
||||
struct iwm_phy_db_entry calib_ch_group_papd[IWM_NUM_PAPD_CH_GROUPS];
|
||||
struct iwm_phy_db_entry calib_ch_group_txp[IWM_NUM_TXP_CH_GROUPS];
|
||||
};
|
||||
|
||||
struct iwm_phy_ctxt {
|
||||
uint16_t id;
|
||||
uint16_t color;
|
||||
uint32_t ref;
|
||||
struct ieee80211_channel *channel;
|
||||
uint8_t sco; /* 40 MHz secondary channel offset */
|
||||
uint8_t vht_chan_width;
|
||||
};
|
||||
|
||||
struct iwm_bf_data {
|
||||
int bf_enabled; /* filtering */
|
||||
int ba_enabled; /* abort */
|
||||
int ave_beacon_signal;
|
||||
int last_cqm_event;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwm_reorder_buffer - per ra/tid/queue reorder buffer
|
||||
* @head_sn: reorder window head sn
|
||||
* @num_stored: number of mpdus stored in the buffer
|
||||
* @buf_size: the reorder buffer size as set by the last addba request
|
||||
* @queue: queue of this reorder buffer
|
||||
* @last_amsdu: track last ASMDU SN for duplication detection
|
||||
* @last_sub_index: track ASMDU sub frame index for duplication detection
|
||||
* @reorder_timer: timer for frames are in the reorder buffer. For AMSDU
|
||||
* it is the time of last received sub-frame
|
||||
* @removed: prevent timer re-arming
|
||||
* @valid: reordering is valid for this queue
|
||||
* @consec_oldsn_drops: consecutive drops due to old SN
|
||||
* @consec_oldsn_ampdu_gp2: A-MPDU GP2 timestamp to track
|
||||
* when to apply old SN consecutive drop workaround
|
||||
* @consec_oldsn_prev_drop: track whether or not an MPDU
|
||||
* that was single/part of the previous A-MPDU was
|
||||
* dropped due to old SN
|
||||
*/
|
||||
struct iwm_reorder_buffer {
|
||||
uint16_t head_sn;
|
||||
uint16_t num_stored;
|
||||
uint16_t buf_size;
|
||||
uint16_t last_amsdu;
|
||||
uint8_t last_sub_index;
|
||||
struct timeout reorder_timer;
|
||||
int removed;
|
||||
int valid;
|
||||
unsigned int consec_oldsn_drops;
|
||||
uint32_t consec_oldsn_ampdu_gp2;
|
||||
unsigned int consec_oldsn_prev_drop;
|
||||
#define IWM_AMPDU_CONSEC_DROPS_DELBA 10
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwm_reorder_buf_entry - reorder buffer entry per frame sequence number
|
||||
* @frames: list of mbufs stored (A-MSDU subframes share a sequence number)
|
||||
* @reorder_time: time the packet was stored in the reorder buffer
|
||||
*/
|
||||
struct iwm_reorder_buf_entry {
|
||||
struct mbuf_list frames;
|
||||
struct timeval reorder_time;
|
||||
uint32_t rx_pkt_status;
|
||||
int chanidx;
|
||||
int is_shortpre;
|
||||
uint32_t rate_n_flags;
|
||||
uint32_t device_timestamp;
|
||||
struct ieee80211_rxinfo rxi;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwm_rxba_data - BA session data
|
||||
* @sta_id: station id
|
||||
* @tid: tid of the session
|
||||
* @baid: baid of the session
|
||||
* @timeout: the timeout set in the addba request
|
||||
* @entries_per_queue: # of buffers per queue
|
||||
* @last_rx: last rx timestamp, updated only if timeout passed from last update
|
||||
* @session_timer: timer to check if BA session expired, runs at 2 * timeout
|
||||
* @sc: softc pointer, needed for timer context
|
||||
* @reorder_buf: reorder buffer
|
||||
* @reorder_buf_data: buffered frames, one entry per sequence number
|
||||
*/
|
||||
struct iwm_rxba_data {
|
||||
uint8_t sta_id;
|
||||
uint8_t tid;
|
||||
uint8_t baid;
|
||||
uint16_t timeout;
|
||||
uint16_t entries_per_queue;
|
||||
struct timeval last_rx;
|
||||
struct timeout session_timer;
|
||||
struct iwm_softc *sc;
|
||||
struct iwm_reorder_buffer reorder_buf;
|
||||
struct iwm_reorder_buf_entry entries[IEEE80211_BA_MAX_WINSZ];
|
||||
};
|
||||
|
||||
static inline struct iwm_rxba_data *
|
||||
iwm_rxba_data_from_reorder_buf(struct iwm_reorder_buffer *buf)
|
||||
{
|
||||
return (void *)((uint8_t *)buf -
|
||||
offsetof(struct iwm_rxba_data, reorder_buf));
|
||||
}
|
||||
|
||||
/**
|
||||
* struct iwm_rxq_dup_data - per station per rx queue data
|
||||
* @last_seq: last sequence per tid for duplicate packet detection
|
||||
* @last_sub_frame: last subframe packet
|
||||
*/
|
||||
struct iwm_rxq_dup_data {
|
||||
uint16_t last_seq[IWM_MAX_TID_COUNT + 1];
|
||||
uint8_t last_sub_frame[IWM_MAX_TID_COUNT + 1];
|
||||
};
|
||||
|
||||
struct iwm_ba_task_data {
|
||||
uint32_t start_tidmask;
|
||||
uint32_t stop_tidmask;
|
||||
};
|
||||
|
||||
struct iwm_softc {
|
||||
struct device sc_dev;
|
||||
struct ieee80211com sc_ic;
|
||||
int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int);
|
||||
int sc_newstate_pending;
|
||||
int attached;
|
||||
|
||||
struct ieee80211_amrr sc_amrr;
|
||||
struct timeout sc_calib_to;
|
||||
struct timeout sc_led_blink_to;
|
||||
|
||||
struct task init_task; /* NB: not reference-counted */
|
||||
struct refcnt task_refs;
|
||||
struct task newstate_task;
|
||||
enum ieee80211_state ns_nstate;
|
||||
int ns_arg;
|
||||
|
||||
/* Task for firmware BlockAck setup/teardown and its arguments. */
|
||||
struct task ba_task;
|
||||
struct iwm_ba_task_data ba_rx;
|
||||
struct iwm_ba_task_data ba_tx;
|
||||
|
||||
/* Task for ERP/HT prot/slot-time/EDCA updates. */
|
||||
struct task mac_ctxt_task;
|
||||
|
||||
/* Task for HT 20/40 MHz channel width updates. */
|
||||
struct task phy_ctxt_task;
|
||||
|
||||
bus_space_tag_t sc_st;
|
||||
bus_space_handle_t sc_sh;
|
||||
bus_size_t sc_sz;
|
||||
bus_dma_tag_t sc_dmat;
|
||||
pci_chipset_tag_t sc_pct;
|
||||
pcitag_t sc_pcitag;
|
||||
const void *sc_ih;
|
||||
int sc_msix;
|
||||
|
||||
/* TX scheduler rings. */
|
||||
struct iwm_dma_info sched_dma;
|
||||
uint32_t sched_base;
|
||||
|
||||
/* TX/RX rings. */
|
||||
struct iwm_tx_ring txq[IWM_MAX_QUEUES];
|
||||
struct iwm_rx_ring rxq;
|
||||
int qfullmsk;
|
||||
int qenablemsk;
|
||||
int cmdqid;
|
||||
|
||||
int sc_sf_state;
|
||||
|
||||
/* ICT table. */
|
||||
struct iwm_dma_info ict_dma;
|
||||
int ict_cur;
|
||||
|
||||
int sc_hw_rev;
|
||||
#define IWM_SILICON_A_STEP 0
|
||||
#define IWM_SILICON_B_STEP 1
|
||||
#define IWM_SILICON_C_STEP 2
|
||||
#define IWM_SILICON_D_STEP 3
|
||||
int sc_hw_id;
|
||||
int sc_device_family;
|
||||
#define IWM_DEVICE_FAMILY_7000 1
|
||||
#define IWM_DEVICE_FAMILY_8000 2
|
||||
#define IWM_DEVICE_FAMILY_9000 3
|
||||
|
||||
struct iwm_dma_info kw_dma;
|
||||
struct iwm_dma_info fw_dma;
|
||||
|
||||
int sc_fw_chunk_done;
|
||||
int sc_init_complete;
|
||||
#define IWM_INIT_COMPLETE 0x01
|
||||
#define IWM_CALIB_COMPLETE 0x02
|
||||
|
||||
struct iwm_ucode_status sc_uc;
|
||||
enum iwm_ucode_type sc_uc_current;
|
||||
char sc_fwver[32];
|
||||
|
||||
int sc_capaflags;
|
||||
int sc_capa_max_probe_len;
|
||||
int sc_capa_n_scan_channels;
|
||||
uint8_t sc_ucode_api[howmany(IWM_NUM_UCODE_TLV_API, NBBY)];
|
||||
uint8_t sc_enabled_capa[howmany(IWM_NUM_UCODE_TLV_CAPA, NBBY)];
|
||||
#define IWM_MAX_FW_CMD_VERSIONS 64
|
||||
struct iwm_fw_cmd_version cmd_versions[IWM_MAX_FW_CMD_VERSIONS];
|
||||
int n_cmd_versions;
|
||||
|
||||
int sc_intmask;
|
||||
int sc_flags;
|
||||
|
||||
uint32_t sc_fh_init_mask;
|
||||
uint32_t sc_hw_init_mask;
|
||||
uint32_t sc_fh_mask;
|
||||
uint32_t sc_hw_mask;
|
||||
|
||||
/*
|
||||
* So why do we need a separate stopped flag and a generation?
|
||||
* the former protects the device from issuing commands when it's
|
||||
* stopped (duh). The latter protects against race from a very
|
||||
* fast stop/unstop cycle where threads waiting for responses do
|
||||
* not have a chance to run in between. Notably: we want to stop
|
||||
* the device from interrupt context when it craps out, so we
|
||||
* don't have the luxury of waiting for quiescence.
|
||||
*/
|
||||
int sc_generation;
|
||||
|
||||
struct rwlock ioctl_rwl;
|
||||
|
||||
int sc_cap_off; /* PCIe caps */
|
||||
|
||||
const char *sc_fwname;
|
||||
bus_size_t sc_fwdmasegsz;
|
||||
size_t sc_nvm_max_section_size;
|
||||
struct iwm_fw_info sc_fw;
|
||||
uint32_t sc_fw_phy_config;
|
||||
uint32_t sc_extra_phy_config;
|
||||
struct iwm_tlv_calib_ctrl sc_default_calib[IWM_UCODE_TYPE_MAX];
|
||||
|
||||
struct iwm_nvm_data sc_nvm;
|
||||
struct iwm_phy_db sc_phy_db;
|
||||
|
||||
struct iwm_bf_data sc_bf;
|
||||
|
||||
int sc_tx_timer[IWM_MAX_QUEUES];
|
||||
int sc_rx_ba_sessions;
|
||||
int tx_ba_queue_mask;
|
||||
|
||||
struct task bgscan_done_task;
|
||||
struct ieee80211_node_switch_bss_arg *bgscan_unref_arg;
|
||||
size_t bgscan_unref_arg_size;
|
||||
|
||||
int sc_scan_last_antenna;
|
||||
|
||||
int sc_fixed_ridx;
|
||||
|
||||
int sc_staid;
|
||||
int sc_nodecolor;
|
||||
|
||||
uint8_t *sc_cmd_resp_pkt[IWM_TX_RING_COUNT];
|
||||
size_t sc_cmd_resp_len[IWM_TX_RING_COUNT];
|
||||
int sc_nic_locks;
|
||||
|
||||
struct taskq *sc_nswq;
|
||||
|
||||
struct iwm_rx_phy_info sc_last_phy_info;
|
||||
int sc_ampdu_ref;
|
||||
#define IWM_MAX_BAID 32
|
||||
struct iwm_rxba_data sc_rxba_data[IWM_MAX_BAID];
|
||||
|
||||
uint32_t sc_time_event_uid;
|
||||
|
||||
/* phy contexts. we only use the first one */
|
||||
struct iwm_phy_ctxt sc_phyctxt[IWM_NUM_PHY_CTX];
|
||||
|
||||
struct iwm_notif_statistics sc_stats;
|
||||
int sc_noise;
|
||||
|
||||
int host_interrupt_operation_mode;
|
||||
int sc_ltr_enabled;
|
||||
enum iwm_nvm_type nvm_type;
|
||||
|
||||
int sc_mqrx_supported;
|
||||
int sc_integrated;
|
||||
int sc_ltr_delay;
|
||||
int sc_xtal_latency;
|
||||
int sc_low_latency_xtal;
|
||||
|
||||
/*
|
||||
* Paging parameters - All of the parameters should be set by the
|
||||
* opmode when paging is enabled
|
||||
*/
|
||||
struct iwm_fw_paging fw_paging_db[IWM_NUM_OF_FW_PAGING_BLOCKS];
|
||||
uint16_t num_of_paging_blk;
|
||||
uint16_t num_of_pages_in_last_blk;
|
||||
|
||||
#if NBPFILTER > 0
|
||||
caddr_t sc_drvbpf;
|
||||
|
||||
union {
|
||||
struct iwm_rx_radiotap_header th;
|
||||
uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
|
||||
} sc_rxtapu;
|
||||
#define sc_rxtap sc_rxtapu.th
|
||||
int sc_rxtap_len;
|
||||
|
||||
union {
|
||||
struct iwm_tx_radiotap_header th;
|
||||
uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
|
||||
} sc_txtapu;
|
||||
#define sc_txtap sc_txtapu.th
|
||||
int sc_txtap_len;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct iwm_node {
|
||||
struct ieee80211_node in_ni;
|
||||
struct iwm_phy_ctxt *in_phyctxt;
|
||||
uint8_t in_macaddr[ETHER_ADDR_LEN];
|
||||
|
||||
uint16_t in_id;
|
||||
uint16_t in_color;
|
||||
|
||||
struct ieee80211_amrr_node in_amn;
|
||||
struct ieee80211_ra_node in_rn;
|
||||
struct ieee80211_ra_vht_node in_rn_vht;
|
||||
int lq_rate_mismatch;
|
||||
|
||||
struct iwm_rxq_dup_data dup_data;
|
||||
|
||||
/* For use with the ADD_STA command. */
|
||||
uint32_t tfd_queue_msk;
|
||||
uint16_t tid_disable_ampdu;
|
||||
};
|
||||
#define IWM_STATION_ID 0
|
||||
#define IWM_AUX_STA_ID 1
|
||||
#define IWM_MONITOR_STA_ID 2
|
||||
|
||||
#define IWM_ICT_SIZE 4096
|
||||
#define IWM_ICT_COUNT (IWM_ICT_SIZE / sizeof (uint32_t))
|
||||
#define IWM_ICT_PADDR_SHIFT 12
|
Loading…
Reference in New Issue